zoukankan      html  css  js  c++  java
  • c# winform调用摄像头识别二维码

    首先我们需要引用两个第三方组件:AForge和zxing。

    Aforge是摄像头操作组件,zxing是二维码识别组件。都是开源项目。避免重复造轮子。

    其实一些操作代码我也是参照别人的,若侵犯您的版权,请和我联系。

    此博客仅供技术交流。

    下载和用法大家可以自行搜索下。

    首先获取所有可用的摄像头设备,并加入到comboBox1中

     1         private void getCamList()
     2         {
     3             try
     4             {
     5                 //AForge.Video.DirectShow.FilterInfoCollection 设备枚举类
     6                 videoDevices = new FilterInfoCollection(FilterCategory.VideoInputDevice);
     7                 //清空列表框
     8                 comboBox1.Items.Clear();
     9                 if (videoDevices.Count == 0)
    10                     throw new ApplicationException();
    11                 //全局变量,标示设备摄像头设备是否存在
    12                 DeviceExist = true;
    13                 //加入设备
    14                 foreach (FilterInfo device in videoDevices)
    15                 {
    16                     comboBox1.Items.Add(device.Name);
    17                 }
    18                 //默认选择第一项
    19                 comboBox1.SelectedIndex = 0;
    20             }
    21             catch (ApplicationException)
    22             {
    23                 DeviceExist = false;
    24                 comboBox1.Items.Add("未找到可用设备");
    25             }
    26         }

    以下是启动按钮事件代码和一些其他代码。

     1         private void start_Click(object sender, EventArgs e)
     2         {
     3             if (start.Text == "Start")
     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 = "Stop";
    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 = "Start";
    32                 }
    33             }
    34         }
            /// <summary>
            /// 全局变量,记录扫描线距离顶端的距离
            /// </summary>
            int top = 0;
            /// <summary>
            /// 全局变量,保存每一次捕获的图像
            /// </summary>
            Bitmap img = null;
    
            private void video_NewFrame(object sender, NewFrameEventArgs eventArgs)
            {
                img = (Bitmap)eventArgs.Frame.Clone();
    
            }
    
            //close the device safely
            private void CloseVideoSource()
            {
                if (!(videoSource == null))
                    if (videoSource.IsRunning)
                    {
                        videoSource.SignalToStop();
                        videoSource = null;
                    }
            }

    下面的代码是在画面中绘制扫描线。

     1         private void timer2_Tick(object sender, EventArgs e)
     2         {
     3             if (img == null)
     4             {
     5                 return;
     6             }
     7             Bitmap img2 = (Bitmap)img.Clone();
     8             Pen p = new Pen(Color.Red);
     9             Graphics g = Graphics.FromImage(img2);
    10             Point p1 = new Point(0, top);
    11             Point p2 = new Point(pictureBox1.Width, top);
    12             g.DrawLine(p, p1, p2);
    13             g.Dispose();
    14             top += 2;
    15 
    16             top = top % pictureBox1.Height;
    17             pictureBox1.Image = img2;
    18 
    19         }

    下面是解码二维码:

     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             LuminanceSource source = new RGBLuminanceSource(bt, img.Width, img.Height);
    14             BinaryBitmap bitmap = new BinaryBitmap(new ZXing.Common.HybridBinarizer(source));
    15             Result result;
    16             try
    17             {
    18                 //开始解码
    19                 result = new MultiFormatReader().decode(bitmap);
    20             }
    21             catch (ReaderException re)
    22             {
    23                 return;
    24             }
    25             if (result != null)
    26             {
    27                 textBox1.Text = result.Text;
    28 
    29             }
    30         }

    用了第三方组件,开发难度真是直线下降。内部具体怎么解码的,真的是一点不知道。还望有经验的高手不吝赐教。

  • 相关阅读:
    HDU——1215七夕节(因数和)
    UVa——400Unix ls(字典序文本处理输出iomanip)
    廖雪峰Java5集合-3Map-Properties的使用
    python图片和字符串的转换
    廖雪峰Java5集合-3Map-1使用Map
    廖雪峰Java5集合-2List-2编写equals方法
    廖雪峰Java5集合-1Java集合简介-1Java结合简介
    廖雪峰Java4反射与泛型-3泛型-7泛型和反射
    廖雪峰Java4反射与泛型-3范型-6super通配符
    廖雪峰Java4反射与泛型-3范型-5extends通配符
  • 原文地址:https://www.cnblogs.com/geeking/p/4181450.html
Copyright © 2011-2022 走看看