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  下載

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM