• 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             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     }
    View Code

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

  • 相关阅读:
    pygame系列_pygame的各模块叙述
    pygame系列_pygame安装
    python开发_thread_线程基础
    python开发_thread_布朗运动
    python开发_thread_线程_搜索本地文件
    python学习两月总结_汇总大牛们的思想_值得收藏
    C# .net中获取台式电脑中串口设备的名称
    C# ini文件操作【源码下载】
    C#中的串口通信
    Winform TreeView 查找下一个节点
  • 原文地址:https://www.cnblogs.com/Grande/p/11942119.html
Copyright © 2020-2023  润新知