因为公司业务需求,需要在Windows系统下调用摄像头识别二维码需求,就有了这个功能。

我根据网上网友提供的一些资料,自己整合应用到项目中,效果还不错(就是感觉像素不是太好)

现在将调用摄像头+识别二维码这两个功能单独出来写到这里,供大家讨论和参考。

有什么不足或者问题大家可以提出来,共同改进共同进步

创建一个空的winform项目解决方案,我起名叫他:ScanQRCode

将Form1作为主窗体,设置相关属性:

  StartPosition:CenterScreen (窗体居中)

  添加一个居中标题:

 1   private void LoadTitleCenterData()
2 {
3 string titleMsg ="二维码识别主界面";
4 Graphics g = this.CreateGraphics();
5 Double startingPoint = (this.Width / 2) - (g.MeasureString(titleMsg, this.Font).Width / 2);
6 Double widthOfASpace = g.MeasureString(" ", this.Font).Width;
7 String tmp = " ";
8 Double tmpWidth = 0;
9
10 while ((tmpWidth + widthOfASpace) < startingPoint)
11 {
12 tmp += " ";
13 tmpWidth += widthOfASpace;
14 }
15 this.Text = tmp + titleMsg;
16 }

  最大最小化禁用:

Form1中添加一个TableLayoutPanel,三行三列,比例按照百分比:10%,80%,10%这样

在TableLayoutPanel的80%中再添加一个TableLayoutPanel,还是行比例:20%,80%这样(二八定律)

在TableLayoutPanel中添加Panel,在其中手动在添加几个按钮和label

最终界面这样(能看就行):

添加一个二维码识别界面CameraQR:

使用Nuget添加引用,搜索AForge,将如下程序包引入:

将VideoSourcePlayer添加到窗体中,Fill显示:

窗体中定义几个私有变量:

1 private AForge.Video.DirectShow.FilterInfoCollection _videoDevices;//摄像设备
2 System.Timers.Timer timer;//定时器
3 CameraHelper _cameraHelper = new CameraHelper();//视屏设备操作类

窗体Load事件中获取拍照设备列表,并将第一个设备作为摄像设备(如有前后两个或多个摄像头,自己去改一下代码,设置成可以选择的,在CameraHelper中的CreateFilterInfoCollection()中):

 1  private void CameraQR_Load(object sender, EventArgs e)
2 {
3 // 获取视频输入设备
4 _videoDevices = _cameraHelper.CreateFilterInfoCollection();//获取拍照设备列表
5 if (_videoDevices.Count == 0)
6 {
7 MessageBox.Show("无设备");
8 this.Dispose();
9 this.Close();
10 return;
11 }
12 resultStr = "";//二维码识别字符串清空
13 _cameraHelper.ConnectDevice(videoSourcePlayer1);//连接打开设备
14 }

组件初始化完成之后,添加一个定时任务,用来阶段性识别摄像设备中的图片资源,我写的是每200毫秒去识别一次,如果图片中有二维码,就识别二维码;识别成功之后,关闭窗体,将识别结果返回给上一个界面,此处需要一个有识别二维码程序包

使用Nuget添加引用,搜索ZXing,将如下程序包引入:

代码如下(核心代码基本就这些):

public CameraQR()
{
this.MinimizeBox = false;
this.MaximizeBox = false;
InitializeComponent();
LoadTitleCenterData();
CheckForIllegalCrossThreadCalls = false;//多线程中访问窗体控件资源不会异常
AddTimer();//定时识别图片
} private void AddTimer()
{
timer = new System.Timers.Timer();
timer.Enabled = true;
timer.Interval = 200;
timer.Start();
timer.Elapsed += new ElapsedEventHandler(PicToQRCode);
}


private void PicToQRCode(object sender, ElapsedEventArgs e)
{
if (_cameraHelper.img == null)
return;
BinaryBitmap bitmap = null;
try
{
MemoryStream ms = new MemoryStream();
_cameraHelper.img.Save(ms, System.Drawing.Imaging.ImageFormat.Bmp);
byte[] bt = ms.GetBuffer();
ms.Close();
LuminanceSource source = new RGBLuminanceSource(bt, _cameraHelper.img.Width, _cameraHelper.img.Height);
bitmap = new BinaryBitmap(new ZXing.Common.HybridBinarizer(source));
}
catch (Exception ex)
{
return;
} Result result=null;
try
{
//开始解码
result = new MultiFormatReader().decode(bitmap);
}
catch (ReaderException ex)
{
resultStr = ex.ToString();
}
if (result != null)
{
resultStr = result.Text;
this.DialogResult = DialogResult.OK;
this.Close();
}
}

窗体关闭时,记得释放定时器 关闭摄像头(不然异常满天飞):

private void CameraQR_FormClosing(object sender, FormClosingEventArgs e)
{
if (timer != null)
{
timer.Dispose();
}
_cameraHelper.CloseDevice();
}

CameraHelper类:

 1 public class CameraHelper
2 {
3 public FilterInfoCollection _videoDevices;//本机摄像硬件设备列表
4 public VideoSourcePlayer _videoSourcePlayer;//视频画布
5 public Bitmap img = null;//全局变量,保存每一次捕获的图像
6 public System.Drawing.Image CaptureImage(VideoSourcePlayer sourcePlayer = null)
7 {
8
9 if (sourcePlayer == null || sourcePlayer.VideoSource == null)
10 {
11 if (_videoSourcePlayer == null)
12 return null;
13 else
14 {
15 sourcePlayer = _videoSourcePlayer;
16 }
17 }
18
19 try
20 {
21 if (sourcePlayer.IsRunning)
22 {
23 System.Drawing.Image bitmap = sourcePlayer.GetCurrentVideoFrame();
24 return bitmap;
25 }
26 return null;
27
28 }
29 catch (Exception ex)
30 {
31 return null;
32 }
33 }
34
35 public FilterInfoCollection CreateFilterInfoCollection()
36 {
37 if (_videoDevices != null)
38 return _videoDevices;
39 _videoDevices = new FilterInfoCollection(FilterCategory.VideoInputDevice);
40 return _videoDevices;
41 }
42
43 public VideoCaptureDevice ConnectDevice(VideoSourcePlayer videoSourcePlayer, FilterInfo filterInfo = null)
44 {
45 VideoCaptureDevice videoSource = new VideoCaptureDevice();
46 if (filterInfo == null)
47 {
48 videoSource = new VideoCaptureDevice(_videoDevices[_videoDevices.Count - 1].MonikerString);
49 }
50 else
51 {
52 videoSource = new VideoCaptureDevice(filterInfo.MonikerString);
53 }
54
55 videoSource.NewFrame += new NewFrameEventHandler(video_NewFrame);
56 videoSourcePlayer.VideoSource = videoSource;
57 videoSourcePlayer.Start();
58 _videoSourcePlayer = videoSourcePlayer;
59 return videoSource;
60 }
61
62 private void video_NewFrame(object sender, NewFrameEventArgs eventArgs)
63 {
64 img = (Bitmap)eventArgs.Frame.Clone();
65 }
66
67 public void CloseDevice(VideoSourcePlayer videoSourcePlayer = null)
68 {
69 if (videoSourcePlayer == null)
70 {
71 if (_videoSourcePlayer == null)
72 return;
73 _videoSourcePlayer.SignalToStop();
74 }
75 else
76 {
77 videoSourcePlayer.SignalToStop();
78 }
79 }
80 }

我用的测试二维码是:

最终的别结果为:

代码:https://github.com/Binzm/ScanQRCode.git

winform 扫码识别二维码的更多相关文章

  1. Flutter扫码识别二维码内容

    前面一篇写了生成二维码图片,这篇来写使用相机扫描识别二维码 识别二维码需要用到插件 barcode_scan 首先在 pubspec.yaml 文件中添加以下依赖,添加依赖后在 pubspec.yam ...

  2. c# winform调用摄像头识别二维码

    首先我们需要引用两个第三方组件:AForge和zxing. Aforge是摄像头操作组件,zxing是二维码识别组件.都是开源项目.避免重复造轮子. 其实一些操作代码我也是参照别人的,若侵犯您的版权, ...

  3. python3 树莓派 + usb摄像头 做颜色识别 二维码识别

    今天又啥也没干 我完蛋了哦  就是没办法沉下心来,咋办....还是先来条NLP吧.. 七,凡事必有至少三个解决方法 对事情只有一个方法的人,必陷入困境,因为别无选择. 对事情有两个方法的人也陷入困境, ...

  4. 使用ZXing.Net生成与识别二维码(QR Code)

    Google ZXing是目前一个常用的基于Java实现的多种格式的1D/2D条码图像处理库,出于其开源的特性其现在已有多平台版本.比如今天要用到的ZXing.Net就是针对微软.Net平台的版本.使 ...

  5. 使用JS调用手机本地摄像头或者相册图片识别二维码/条形码

    接着昨天的需求,不过这次不依赖微信,使用纯js唤醒手机本地摄像头或者选择手机相册图片,识别其中的二维码或者是条形码.昨天,我使用微信扫一扫识别,效果超棒的.不过如果依赖微信的话,又怎么实现呢,这里介绍 ...

  6. Python3+qrcode+zxing生成和识别二维码教程

    一.安装依赖库 pip install qrcode pillow image zxing pillow是python3中PIL的代替库,image是生成图版需要用到的库 安装image时报错“Cou ...

  7. PHP 生成、识别二维码及安装相关扩展/工具

    2018-02-20 00:30:26  更新:推荐新扩展(极力推荐) 这篇文章里用的两个二维码扩展都有些问题和麻烦:phpqrcode(生成二维码)的源码有点小 bug: 而 php-zbarcod ...

  8. Pyqt+QRcode 生成 识别 二维码

    1.生成二维码 python生成二维码是件很简单的事,使用第三方库Python QRCode就可生成二维码,我用Pyqt给QRcode打个壳 一.python-qrcode介绍 python-qrco ...

  9. python实现树莓派生成并识别二维码

    python实现树莓派生成并识别二维码 参考来源:http://blog.csdn.net/Burgess_Liu/article/details/40397803 设备及环境 树莓派2代 官方系统R ...

随机推荐

  1. Typora + 七牛云图床快速配置,告别手动上传图片!

    大家好,我是zeroing,本文将介绍关于 Typora 软件如何配置七牛云图床,实现图片即插即用,可以先看一下最终效果! 可以看到图片借助 Typora 软件自动将本地存储转化为第三方图片网络链接 ...

  2. 死磕以太坊源码分析之downloader同步

    死磕以太坊源码分析之downloader同步 需要配合注释代码看:https://github.com/blockchainGuide/ 这篇文章篇幅较长,能看下去的是条汉子,建议收藏 希望读者在阅读 ...

  3. Pygal之掷骰子

    python之使用pygal模拟掷骰子创建直方图: 1,文件die.py,源码如下: 1 from random import randint 2 3 class Die(): 4 '''表示一个骰子 ...

  4. C#中未在本地计算机上注册“Microsoft.Jet.OLEDB.4.0”提供程序

    解决方法 方法一 "设置应用程序池默认属性"/"常规"/"启用32位应用程序",设置为 true. 方法二 生成->配置管理器-> ...

  5. 安利一个基于Spring Cloud 的面试刷题系统。面试、毕设、项目经验一网打尽

    推荐: 接近100K star 的Java学习/面试指南 Github 95k+点赞的Java面试/学习手册.pdf 今天给小伙伴们推荐一个朋友开源的面试刷题系统. 这篇文章我会从系统架构设计层面详解 ...

  6. 【译】对Rust中的std::io::Error的研究

    原文标题:Study of std::io::Error 原文链接:https://matklad.github.io/2020/10/15/study-of-std-io-error.html 公众 ...

  7. Javaweb前台界面代码复用总结

    servlet声明定义message信息传给前天界面判断输出message: if(booknamelist.size()==0) { message="根据书名查询没有结果!"; ...

  8. cmake - 可执行文件

    1.生成可执行文件 add_executable(hello xxx.cpp xxxxx.cpp) ##根据文件xxx.cpp和xxxx.cpp生成可执行文件hello,但是这两个可执行文件如果依赖其 ...

  9. 第十九章节 BJROBOT 安卓手机 APP 导航【ROS全开源阿克曼转向智能网联无人驾驶车】

    导航前说明:一定要确保你小车在构建好地图的基础上进行! 1.把小车平放在你想要构建地图区域的地板上,打开资料里的虚拟机,打开一个终端, ssh 过去主控端启动roslaunch znjrobot br ...

  10. windows10系统修改JDK版本后配置环境变量不生效怎么办

    之前安装了个jdk8版本,今天突然想安装个更新版本的jdk11来用,但在安装好JDK11并配置环境变量后发现修改JDK版本后配置的环境变量不生效的.本文就给大家分享一下windows10系统修改JDK ...