前言
作為一名資深Delphi7程序員,想要實現攝像頭掃描一維碼/二維碼功能,發現所有免費的第三方庫都沒有簡便的實現辦法,通用的OpenCV或者ZXing庫基本上只支持XE以上的版本,而且一維碼的識別還需要自己重新寫,費時費力。最近,心里滋生一些用其他語言實現的想法。本篇講解使用VS2019 C#程序調用AForge庫實現調用攝像頭拍照功能,接下來的幾天學習使用ZXing庫實現一維碼/二維碼的生成和識別,這樣就能夠做到,程序實現攝像頭掃描一維碼/二維碼,並獲取到碼值。
AForge庫的引用
新建一個C# WinFrm應用程序,右鍵解決方案項目,選擇管理NuGet程序包,並安裝必要的AForge庫,如下圖。
如果沒有搜索到時,需要新增程序包源,然后重新搜索安裝即可,如下圖:
窗體控件部署
在窗體上添加必要的控件。當AForge庫安裝成功之后,可以在工具欄看到AForge.NET控件包,如下圖。
核心代碼
窗體載入時,枚舉當前設備所有視頻輸入設備,並加載到設備列表中。
1 /// <summary> 2 /// 窗體初始化時,枚舉所有視頻輸入設備,並加載到cmbDeviceLists中 3 /// </summary> 4 /// <param name="sender"></param> 5 /// <param name="e"></param> 6 private void MainFrm_Load(object sender, EventArgs e) 7 { 8 try 9 { 10 videoDevices = new FilterInfoCollection(FilterCategory.VideoInputDevice); 11 if (videoDevices.Count == 0) 12 throw new ApplicationException(); 13 foreach (FilterInfo device in videoDevices) 14 { 15 cmbDeviceLists.Items.Add(device.Name); 16 } 17 cmbDeviceLists.SelectedIndex = 0; 18 } 19 catch (ApplicationException) 20 { 21 cmbDeviceLists.Items.Add("No local capture devices"); 22 videoDevices = null; 23 } 24 }
打開相機
1 /// <summary> 2 /// 打開相機 3 /// </summary> 4 /// <param name="sender"></param> 5 /// <param name="e"></param> 6 private void btnOpenCamera_Click(object sender, EventArgs e) 7 { 8 VideoCaptureDevice videoSource = new VideoCaptureDevice(videoDevices[cmbDeviceLists.SelectedIndex].MonikerString); 9 this.videoSourcePlayer.VideoSource = videoSource; 10 this.videoSourcePlayer.Start(); 11 this.btnOpenCamera.Enabled = false; 12 this.btnTakePic.Enabled = true; 13 this.btnExit.Enabled = true; 14 }
拍照
1 /// <summary> 2 /// 拍照 3 /// </summary> 4 /// <param name="sender"></param> 5 /// <param name="e"></param> 6 private void btnTakePic_Click(object sender, EventArgs e) 7 { 8 try 9 { 10 if (this.videoSourcePlayer.IsRunning) 11 { 12 this.pbImage.Visible = true; 13 Bitmap bitMap = this.videoSourcePlayer.GetCurrentVideoFrame(); 14 this.pbImage.Image = bitMap; 15 //設置圖片相對控件的大小 16 this.pbImage.SizeMode = PictureBoxSizeMode.StretchImage; 17 this.btnSavePic.Enabled = true; 18 } 19 } 20 catch (Exception ex) 21 { 22 MessageBox.Show("攝像頭異常:" + ex.Message); 23 } 24 }
保存圖片
1 /// <summary> 2 /// 保存圖片 3 /// </summary> 4 /// <param name="sender"></param> 5 /// <param name="e"></param> 6 private void btnSavePic_Click(object sender, EventArgs e) 7 { 8 BitmapSource bitmapSource = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap( 9 videoSourcePlayer.GetCurrentVideoFrame().GetHbitmap(), 10 IntPtr.Zero, 11 Int32Rect.Empty, 12 BitmapSizeOptions.FromEmptyOptions()); 13 PngBitmapEncoder pE = new PngBitmapEncoder(); 14 pE.Frames.Add(BitmapFrame.Create(bitmapSource)); 15 string picName = GetImagePath() + "\\" + "Test" + ".bmp"; 16 if (File.Exists(picName)) 17 { 18 File.Delete(picName); 19 } 20 using (Stream stream = File.Create(picName)) 21 { 22 pE.Save(stream); 23 } 24 MessageBox.Show("保存成功!根路徑Imgs文件夾下!"); 25 }
關閉相機
1 /// <summary> 2 /// 關閉相機 3 /// </summary> 4 /// <param name="sender"></param> 5 /// <param name="e"></param> 6 private void btnExit_Click(object sender, EventArgs e) 7 { 8 videoSourcePlayer.SignalToStop(); 9 videoSourcePlayer.WaitForStop(); 10 this.btnOpenCamera.Enabled = true; 11 this.btnTakePic.Enabled = false; 12 this.btnExit.Enabled = false; 13 this.pbImage.Visible = false; 14 }
程序退出
1 private void MainFrm_FormClosed(object sender, FormClosedEventArgs e) 2 { 3 videoSourcePlayer.SignalToStop(); 4 videoSourcePlayer.WaitForStop(); 5 }
實現效果
至此,已全部完成!
作者:Jeremy.Wu
出處:https://www.cnblogs.com/jeremywucnblog/
本文版權歸作者和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接,否則保留追究法律責任的權利。