打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

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

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

  参考博客链接:https://www.cnblogs.com/geeking/p/4181450.html
  好了 进入正题。

项目环境


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

  主要采用的插件是

 

 

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

AForge主要是调用摄像头的

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

  前台界面

 
 


这里的窗体只是放了一个列表标签,存储电脑上面的摄像头设备(如果没有就不能用这个功能了) 另外的一个开启关闭按钮,一个图片控件控制显示图片。一个文本框展示解析出来的二维码地址。
另外还有两个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             else25             {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             #endregion13             #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             try22             {23                 //开始解码24                 result = multiFormatReader.decode(bitmap);//(不定期暴毙)25             }26             catch (Exception ex)27             {28                 return;29             }30             finally31             {32                 multiFormatReader.reset();33 34             }35 36 37             if (result != null)38             {39                 textBox1.Text = result.Text;40 41             }42             #endregion43 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             #endregion116             #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             try125             {126                 //开始解码127                 result = multiFormatReader.decode(bitmap);//(不定期暴毙)128             }129             catch (Exception ex)130             {131                 return;132             }133             finally134             {135                 multiFormatReader.reset();136 137             }138 139 140             if (result != null)141             {142                 textBox1.Text = result.Text;143 144             }145             #endregion146 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     }
View Code

 

参考文章 https://www.cnblogs.com/geeking/p/4181450.html

 

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
winform 加载AForge.dll中的videoSourcePlayer。
「图像处理」C#+AForge.Net+DlibDotNet实现人脸识别
实现简单的手写涂鸦板(demo源码)
笔记10: 变换图像
数字图像处理 C# 程序代码实例
C# 二维码生成和解析
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服