C#调用摄像头(AForge)实现扫描条码解析(Zxing)功能

网上找了很多代码,都比较零散,以下代码纯自己手写,经过测试。下面有链接,下载后可以直接使用。

 

介绍:

自动识别:点击Start按钮会调用PC摄像头,代码内置Timer,会每100毫秒识别一下当前摄像头图像中的图像,并调用条码识别功能判定是否有条码,如果有的话就直接停止,否则继循环识别。

 

截图:也可以手动截图,截图后存在运行目录,请自行查找。

 

补充:识别通过率取决于摄像头的像素,我的笔记本比较烂,所以通过率不高。高像素的摄像头通过率很高。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

using AForge;
using AForge.Controls;
using AForge.Imaging;
using AForge.Video;
using AForge.Video.DirectShow;
using System.Drawing.Imaging;

using ZXing;
using ZXing.Common;
using ZXing.QrCode;
using ZXing.QrCode.Internal;


/// <summary>
/// 20190515 by hanfre 
/// 关于原理:
/// C#调用摄像头+存储图片+Zxing/Zbar图片识别.当开启摄像头的时候利用Timer对当前图片进行解析处理,识别条码;
/// 关于条码解析:
/// 这个DEMO含两个条码解析组件,分别是Zxing和Zbar,使用哪个可以自己切换;
/// 关于作者:
/// Hanfre
/// </summary>
namespace WindowsFormsApplication1
{
    /// <summary>
    /// 20190515 by hanfre 
    /// </summary>
    public partial class Form1 : Form
    {
        #region 全局变量定义
        FilterInfoCollection videoDevices;
        VideoCaptureDevice videoSource;
        public int selectedDeviceIndex = 0;
        #endregion

        public Form1()
        {
            InitializeComponent();

            InitializeView();
        }

        #region 事件
        /// <summary>
        /// 启动
        /// 20190515 by hanfre 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void BtnStart_Click(object sender, EventArgs e)
        {
            PbxScanner.Image = null;
       
            videoDevices = new FilterInfoCollection(FilterCategory.VideoInputDevice);
            selectedDeviceIndex = 0;
            videoSource = new VideoCaptureDevice(videoDevices[selectedDeviceIndex].MonikerString);//连接摄像头

            videoSource.NewFrame += new NewFrameEventHandler(VspContainerClone);//捕获画面事件

            videoSource.VideoResolution = videoSource.VideoCapabilities[selectedDeviceIndex];
            VspContainer.VideoSource = videoSource;
            VspContainer.Start();

            StartVideoSource();
        }

        /// <summary>
        /// 停止
        /// 20190515 by hanfre 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void BtnStop_Click(object sender, EventArgs e)
        {
            CloseVideoSource();
        }

        /// <summary>
        /// 保存
        /// 20190515 by hanfre 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void BtnScanner_Click(object sender, EventArgs e)
        {
            if (videoSource == null)
                return;
            Bitmap bitmap = VspContainer.GetCurrentVideoFrame();
            string fileName = DateTime.Now.ToString("yyyy-MM-dd-HH-mm-ss-ff") + ".jpg";

            bitmap.Save(Application.StartupPath + "\\" + fileName, ImageFormat.Jpeg);
            bitmap.Dispose();
        }

        /// <summary>
        /// 同步事件
        /// 20190515 by hanfre 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="eventArgs"></param>
        private void VspContainerClone(object sender, NewFrameEventArgs eventArgs)
        {
            PbxScanner.Image = (Bitmap)eventArgs.Frame.Clone();
        }

        /// <summary>
        /// Timer定时器
        /// 20190515 by hanfre 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void TmScanner_Tick(object sender, EventArgs e)
        {
            if (PbxScanner.Image != null)
            {
                TmScanner.Enabled = false;
                Bitmap img = (Bitmap)PbxScanner.Image.Clone();
                if (DecodeByZxing(img))
                ///if (DecodeByZbar(img))    
                {
                    CloseVideoSource();
                }
                else
                {
                    TmScanner.Enabled = true;
                }
            }
        }
        #endregion

        #region 方法
        /// <summary>
        /// 初始化
        /// 20190515 by hanfre 
        /// </summary>
        private void InitializeView()
        {
            BtnScanner.Enabled = false;
            BtnStop.Enabled = false;
        }

        /// <summary>
        /// 启动
        /// 20190515 by hanfre 
        /// </summary>
        private void StartVideoSource()
        {
            TmScanner.Enabled = true;
            BtnStart.Enabled = false;
            BtnStop.Enabled = true;
            BtnScanner.Enabled = true;
        }
        /// <summary>
        /// 关闭
        /// 20190515 by hanfre 
        /// </summary>
        private void CloseVideoSource()
        {
            if (!(videoSource == null))
            {
                if (videoSource.IsRunning)
                {
                    videoSource.SignalToStop();
                    videoSource = null;
                }
            }

            VspContainer.SignalToStop();
            //videoSourcePlayer1.Stop();
            //videoSourcePlayer1.Dispose();

            TmScanner.Enabled = false;
            BtnScanner.Enabled = false;
            BtnStart.Enabled = true;
            BtnStop.Enabled = false;
        }
        #endregion

        #region 方法/Zxing&Zbar
        /// <summary>
        /// 解码
        /// 20190515 by hanfre 
        /// </summary>
        /// <param name="b"></param>
        /// <returns></returns>
        private bool DecodeByZxing(Bitmap b)
        {
            try
            {
                BarcodeReader reader = new BarcodeReader();
                reader.AutoRotate = true;
                Result result = reader.Decode(b);

                TxtScannerCode.Text = result.Text;
            }
            catch (Exception e)
            {
                System.Console.WriteLine(e.Message);
                TxtScannerCode.Text = "";
                return false;
            }

            return true;
        }

        private bool DecodeByZbar(Bitmap b)
        {
            DateTime now = DateTime.Now;

            Bitmap pImg = ZbarMakeGrayscale3(b);
            using (ZBar.ImageScanner scanner = new ZBar.ImageScanner())
            {
                scanner.SetConfiguration(ZBar.SymbolType.None, ZBar.Config.Enable, 0);
                scanner.SetConfiguration(ZBar.SymbolType.CODE39, ZBar.Config.Enable, 1);
                scanner.SetConfiguration(ZBar.SymbolType.CODE128, ZBar.Config.Enable, 1);

                List<ZBar.Symbol> symbols = new List<ZBar.Symbol>();
                symbols = scanner.Scan((System.Drawing.Image)pImg);

                if (symbols != null && symbols.Count > 0)
                {
                    string result = string.Empty;
                    symbols.ForEach(s => result += "条码内容:" + s.Data + " 条码质量:" + s.Quality + Environment.NewLine);
                    MessageBox.Show(result);
                    return true;
                }
                else
                {
                    return false;
                }
            }
        }

        /// <summary>
        /// 处理图片灰度
        /// </summary>
        /// <param name="original"></param>
        /// <returns></returns>
        public static Bitmap ZbarMakeGrayscale3(Bitmap original)
        {
            //create a blank bitmap the same size as original
            Bitmap newBitmap = new Bitmap(original.Width, original.Height);

            //get a graphics object from the new image
            Graphics g = Graphics.FromImage(newBitmap);

            //create the grayscale ColorMatrix
            System.Drawing.Imaging.ColorMatrix colorMatrix = new System.Drawing.Imaging.ColorMatrix(
               new float[][]
              {
                 new float[] {.3f, .3f, .3f, 0, 0},
                 new float[] {.59f, .59f, .59f, 0, 0},
                 new float[] {.11f, .11f, .11f, 0, 0},
                 new float[] {0, 0, 0, 1, 0},
                 new float[] {0, 0, 0, 0, 1}
              });

            //create some image attributes
            ImageAttributes attributes = new ImageAttributes();

            //set the color matrix attribute
            attributes.SetColorMatrix(colorMatrix);

            //draw the original image on the new image
            //using the grayscale color matrix
            g.DrawImage(original, new Rectangle(0, 0, original.Width, original.Height),
               0, 0, original.Width, original.Height, GraphicsUnit.Pixel, attributes);

            //dispose the Graphics object
            g.Dispose();
            return newBitmap;
        }
        #endregion
    }
}

  下载地址我已上传到CSDN,可以访问   https://download.csdn.net/download/fandoc/11180026  下载

 

posted on 2019-05-15 15:42  范兵  阅读(6381)  评论(2编辑  收藏  举报

导航