欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

C# winfrom调用摄像头扫描二维码(完整版)

程序员文章站 2023-10-16 17:44:14
前段时间看到一篇博客,是这个功能的,参考了那篇博客写了这个功能玩一玩,没有做商业用途。发现他的代码给的有些描述不清晰的,我就自己整理一下发出来记录一下。 参考博客链接:https://www.cnblogs.com/geeking/p/4181450.html 好了 进入正题。 项目环境 项目代码的 ......

  前段时间看到一篇博客,是这个功能的,参考了那篇博客写了这个功能玩一玩,没有做商业用途。发现他的代码给的有些描述不清晰的,我就自己整理一下发出来记录一下。

  参考博客链接:
  好了 进入正题。

项目环境


  项目代码的版本是.net4.0的 

  主要采用的插件是
C# winfrom调用摄像头扫描二维码(完整版)

 

 

 都是我在网上找的资源插件 版本的话 随意吧  我也不知道哪个版本最适用了。

aforge主要是调用摄像头的

zxing是调用解析二维码的 其实还有生成二维码的功能。 

  前台界面

 
 C# winfrom调用摄像头扫描二维码(完整版)
这里的窗体只是放了一个列表标签,存储电脑上面的摄像头设备(如果没有就不能用这个功能了) 另外的一个开启关闭按钮,一个图片控件控制显示图片。一个文本框展示解析出来的二维码地址。
另外还有两个time控件完成图片的刷新,控制图片刷新的频率。

代码部分

后台代码如下:(不想看解析的直接划到最后 有全部的源码展示)

首先是加载部分的代码,主要用于调用插件获取摄像头设备。

 

1   private void form1_load(object sender, eventargs e)
2         {
3             //获取摄像头列表
4             getcamlist();
5         }
 1   /// <summary>
 2         /// 获取摄像头列表
 3         /// </summary>
 4         private void getcamlist()
 5         {
 6             try
 7             {
 8                 //aforge.video.directshow.filterinfocollection 设备枚举类
 9                 videodevices = new filterinfocollection(filtercategory.videoinputdevice);
10                 //清空列表框
11                 combobox1.items.clear();
12                 if (videodevices.count == 0)
13                     throw new applicationexception();
14                 deviceexist = true;
15                 //加入设备
16                 foreach (filterinfo device in videodevices)
17                 {
18                     combobox1.items.add(device.name);
19                 }
20                 //默认选择第一项
21                 combobox1.selectedindex = 0;
22             }
23             catch (applicationexception)
24             {
25                 deviceexist = false;
26                 combobox1.items.add("未找到可用设备");
27             }
28         }

 

下一步 是声明的全局变量代码

        filterinfocollection videodevices; //所有摄像头
        videocapturedevice videosource; //当前摄像头 
        public int selecteddeviceindex = 0;
        /// <summary>
        /// 全局变量,标示设备摄像头设备是否存在
        /// </summary>
        bool deviceexist;
        /// <summary>
        /// 全局变量,记录扫描线距离顶端的距离
        /// </summary>
        int top = 0;
        /// <summary>
        /// 全局变量,保存每一次捕获的图像
        /// </summary>
        bitmap img = null;

 

然后是点击开始按钮的代码

 

 

 1  private void start_click(object sender, eventargs e)
 2         {
 3             if (start.text == "开始")
 4             {
 5                 if (deviceexist)
 6                 {
 7                     //视频捕获设备
 8                     videosource = new videocapturedevice(videodevices[combobox1.selectedindex].monikerstring);
 9                     //捕获到新画面时触发
10                     videosource.newframe += new newframeeventhandler(video_newframe);
11                     //先关一下,下面再打开。避免重复打开的错误
12                     closevideosource();
13                     //设置画面大小
14                     videosource.desiredframesize = new size(160, 120);
15                     //启动视频组件
16                     videosource.start();
17                     start.text = "结束";
18                     //启动定时解析二维码
19                     timer1.enabled = true;
20                     //启动绘制视频中的扫描线
21                     timer2.enabled = true;
22                 }
23             }
24             else
25             {
26                 if (videosource.isrunning)
27                 {
28                     timer2.enabled = false;
29                     timer1.enabled = false;
30                     closevideosource();
31                     start.text = "开始";
32                 }
33             }
34         }

 

两个timer控件的代码

 1  private void timer1_tick(object sender, eventargs e)
 2         {
 3             if (img == null)
 4             {
 5                 return;
 6             }
 7             #region 将图片转换成byte数组
 8             memorystream ms = new memorystream();
 9             img.save(ms, system.drawing.imaging.imageformat.bmp);
10             byte[] bt = ms.getbuffer();
11             ms.close();
12             #endregion
13             #region 不稳定的二维码解析端口
14             luminancesource source = new rgbluminancesource(bt, img.width, img.height);
15             binarybitmap bitmap = new binarybitmap(new zxing.common.hybridbinarizer(source));
16 
17             result result;
18 
19             multiformatreader multiformatreader = new multiformatreader();
20 
21             try
22             {
23                 //开始解码
24                 result = multiformatreader.decode(bitmap);//(不定期暴毙)
25             }
26             catch (exception ex)
27             {
28                 return;
29             }
30             finally
31             {
32                 multiformatreader.reset();
33 
34             }
35 
36 
37             if (result != null)
38             {
39                 textbox1.text = result.text;
40 
41             }
42             #endregion
43 
44 
45 
46         }
47         private void timer2_tick(object sender, eventargs e)
48         {
49             if (img == null)
50             {
51                 return;
52             }
53             bitmap img2 = (bitmap)img.clone();
54             pen p = new pen(color.red);
55             graphics g = graphics.fromimage(img2);
56             point p1 = new point(0, top);
57             point p2 = new point(picturebox1.width, top);
58             g.drawline(p, p1, p2);
59             g.dispose();
60             top += 2;
61 
62             top = top % picturebox1.height;
63             picturebox1.image = img2;
64 
65         }

 

 

以及关闭摄像头的方法:

 

 1  /// <summary>
 2         /// 关闭摄像头
 3         /// </summary>
 4         private void closevideosource()
 5         {
 6             if (!(videosource == null))
 7                 if (videosource.isrunning)
 8                 {
 9                     videosource.signaltostop();
10                     videosource = null;
11                 }
12         }

 

 

基本的操作都是在dll方法里面封装的,zxing代码好像是用java写的吧 ,我自己的电脑上运行这里的代码 有时候会报错,所以对于源代码改了一下,现在至少跑起来应该还行,此文章只是为了自己总结知识点用的,如果涉及侵权,请通知,会立即删除。

另附所有代码内容

 

  1  public partial class form1 : form
  2     {
  3         filterinfocollection videodevices; //所有摄像头
  4         videocapturedevice videosource; //当前摄像头 
  5         public int selecteddeviceindex = 0;
  6         public form1()
  7         {
  8             initializecomponent();
  9         }
 10         /// <summary>
 11         /// 全局变量,标示设备摄像头设备是否存在
 12         /// </summary>
 13         bool deviceexist;
 14         /// <summary>
 15         /// 全局变量,记录扫描线距离顶端的距离
 16         /// </summary>
 17         int top = 0;
 18         /// <summary>
 19         /// 全局变量,保存每一次捕获的图像
 20         /// </summary>
 21         bitmap img = null;
 22 
 23         private void video_newframe(object sender, newframeeventargs eventargs)
 24         {
 25             img = (bitmap)eventargs.frame.clone();
 26 
 27         }
 28 
 29         /// <summary>
 30         /// 关闭摄像头
 31         /// </summary>
 32         private void closevideosource()
 33         {
 34             if (!(videosource == null))
 35                 if (videosource.isrunning)
 36                 {
 37                     videosource.signaltostop();
 38                     videosource = null;
 39                 }
 40         }
 41         /// <summary>
 42         /// 获取摄像头列表
 43         /// </summary>
 44         private void getcamlist()
 45         {
 46             try
 47             {
 48                 //aforge.video.directshow.filterinfocollection 设备枚举类
 49                 videodevices = new filterinfocollection(filtercategory.videoinputdevice);
 50                 //清空列表框
 51                 combobox1.items.clear();
 52                 if (videodevices.count == 0)
 53                     throw new applicationexception();
 54                 deviceexist = true;
 55                 //加入设备
 56                 foreach (filterinfo device in videodevices)
 57                 {
 58                     combobox1.items.add(device.name);
 59                 }
 60                 //默认选择第一项
 61                 combobox1.selectedindex = 0;
 62             }
 63             catch (applicationexception)
 64             {
 65                 deviceexist = false;
 66                 combobox1.items.add("未找到可用设备");
 67             }
 68         }
 69 
 70         private void start_click(object sender, eventargs e)
 71         {
 72             if (start.text == "开始")
 73             {
 74                 if (deviceexist)
 75                 {
 76                     //视频捕获设备
 77                     videosource = new videocapturedevice(videodevices[combobox1.selectedindex].monikerstring);
 78                     //捕获到新画面时触发
 79                     videosource.newframe += new newframeeventhandler(video_newframe);
 80                     //先关一下,下面再打开。避免重复打开的错误
 81                     closevideosource();
 82                     //设置画面大小
 83                     videosource.desiredframesize = new size(160, 120);
 84                     //启动视频组件
 85                     videosource.start();
 86                     start.text = "结束";
 87                     //启动定时解析二维码
 88                     timer1.enabled = true;
 89                     //启动绘制视频中的扫描线
 90                     timer2.enabled = true;
 91                 }
 92             }
 93             else
 94             {
 95                 if (videosource.isrunning)
 96                 {
 97                     timer2.enabled = false;
 98                     timer1.enabled = false;
 99                     closevideosource();
100                     start.text = "开始";
101                 }
102             }
103         }
104         private void timer1_tick(object sender, eventargs e)
105         {
106             if (img == null)
107             {
108                 return;
109             }
110             #region 将图片转换成byte数组
111             memorystream ms = new memorystream();
112             img.save(ms, system.drawing.imaging.imageformat.bmp);
113             byte[] bt = ms.getbuffer();
114             ms.close();
115             #endregion
116             #region 不稳定的二维码解析端口
117             luminancesource source = new rgbluminancesource(bt, img.width, img.height);
118             binarybitmap bitmap = new binarybitmap(new zxing.common.hybridbinarizer(source));
119 
120             result result;
121 
122             multiformatreader multiformatreader = new multiformatreader();
123 
124             try
125             {
126                 //开始解码
127                 result = multiformatreader.decode(bitmap);//(不定期暴毙)
128             }
129             catch (exception ex)
130             {
131                 return;
132             }
133             finally
134             {
135                 multiformatreader.reset();
136 
137             }
138 
139 
140             if (result != null)
141             {
142                 textbox1.text = result.text;
143 
144             }
145             #endregion
146 
147 
148 
149         }
150         private void timer2_tick(object sender, eventargs e)
151         {
152             if (img == null)
153             {
154                 return;
155             }
156             bitmap img2 = (bitmap)img.clone();
157             pen p = new pen(color.red);
158             graphics g = graphics.fromimage(img2);
159             point p1 = new point(0, top);
160             point p2 = new point(picturebox1.width, top);
161             g.drawline(p, p1, p2);
162             g.dispose();
163             top += 2;
164 
165             top = top % picturebox1.height;
166             picturebox1.image = img2;
167 
168         }
169 
170         private void form1_load(object sender, eventargs e)
171         {
172             //获取摄像头列表
173             getcamlist();
174         }
175 
176     }

 

参考文章