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         }

用了第三方組件,開發難度真是直線下降。內部具體怎么解碼的,真的是一點不知道。還望有經驗的高手不吝賜教。


免責聲明!

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



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