前言
作為一名資深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/
本文版權歸作者和部落格園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接配接,否則保留追究法律責任的權利。