winform 調(diào)用攝像頭掃碼識(shí)別二維碼的實(shí)現(xiàn)步驟
因?yàn)楣緲I(yè)務(wù)需求,需要在Windows系統(tǒng)下調(diào)用攝像頭識(shí)別二維碼需求,就有了這個(gè)功能。
我根據(jù)網(wǎng)上網(wǎng)友提供的一些資料,自己整合應(yīng)用到項(xiàng)目中,效果還不錯(cuò)(就是感覺(jué)像素不是太好)
現(xiàn)在將調(diào)用攝像頭+識(shí)別二維碼這兩個(gè)功能單獨(dú)出來(lái)寫(xiě)到這里,供大家討論和參考。
有什么不足或者問(wèn)題大家可以提出來(lái),共同改進(jìn)共同進(jìn)步
創(chuàng)建一個(gè)空的winform項(xiàng)目解決方案,我起名叫他:ScanQRCode
將Form1作為主窗體,設(shè)置相關(guān)屬性:
StartPosition:CenterScreen (窗體居中)
添加一個(gè)居中標(biāo)題:
private void LoadTitleCenterData() { string titleMsg ="二維碼識(shí)別主界面"; Graphics g = this.CreateGraphics(); Double startingPoint = (this.Width / 2) - (g.MeasureString(titleMsg, this.Font).Width / 2); Double widthOfASpace = g.MeasureString(" ", this.Font).Width; String tmp = " "; Double tmpWidth = 0; while ((tmpWidth + widthOfASpace) < startingPoint) { tmp += " "; tmpWidth += widthOfASpace; } this.Text = tmp + titleMsg; }
最大最小化禁用:
public Form1() { this.MinimizeBox = false; this.MaximizeBox = false; InitializeComponent(); LoadTitleCenterData(); }
Form1中添加一個(gè)TableLayoutPanel,三行三列,比例按照百分比:10%,80%,10%這樣
在TableLayoutPanel的80%中再添加一個(gè)TableLayoutPanel,還是行比例:20%,80%這樣(二八定律)
在TableLayoutPanel中添加Panel,在其中手動(dòng)在添加幾個(gè)按鈕和label
最終界面這樣(能看就行):
添加一個(gè)二維碼識(shí)別界面CameraQR:
使用Nuget添加引用,搜索AForge,將如下程序包引入:
添加一個(gè)識(shí)別二維碼的窗體,命名名稱(chēng)為:CameraQR
將VideoSourcePlayer添加到窗體中,F(xiàn)ill顯示:
窗體中定義幾個(gè)私有變量:
private AForge.Video.DirectShow.FilterInfoCollection _videoDevices;//攝像設(shè)備 System.Timers.Timer timer;//定時(shí)器 CameraHelper _cameraHelper = new CameraHelper();//視屏設(shè)備操作類(lèi)
窗體Load事件中獲取拍照設(shè)備列表,并將第一個(gè)設(shè)備作為攝像設(shè)備(如有前后兩個(gè)或多個(gè)攝像頭,自己去改一下代碼,設(shè)置成可以選擇的,在CameraHelper中的CreateFilterInfoCollection()中):
private void CameraQR_Load(object sender, EventArgs e) { // 獲取視頻輸入設(shè)備 _videoDevices = _cameraHelper.CreateFilterInfoCollection();//獲取拍照設(shè)備列表 if (_videoDevices.Count == 0) { MessageBox.Show("無(wú)設(shè)備"); this.Dispose(); this.Close(); return; } resultStr = "";//二維碼識(shí)別字符串清空 _cameraHelper.ConnectDevice(videoSourcePlayer1);//連接打開(kāi)設(shè)備 }
組件初始化完成之后,添加一個(gè)定時(shí)任務(wù),用來(lái)階段性識(shí)別攝像設(shè)備中的圖片資源,我寫(xiě)的是每200毫秒去識(shí)別一次,如果圖片中有二維碼,就識(shí)別二維碼;識(shí)別成功之后,關(guān)閉窗體,將識(shí)別結(jié)果返回給上一個(gè)界面,此處需要一個(gè)有識(shí)別二維碼程序包
使用Nuget添加引用,搜索ZXing,將如下程序包引入:
代碼如下(核心代碼基本就這些):
public CameraQR() { this.MinimizeBox = false; this.MaximizeBox = false; InitializeComponent(); LoadTitleCenterData(); CheckForIllegalCrossThreadCalls = false;//多線程中訪問(wèn)窗體控件資源不會(huì)異常 AddTimer();//定時(shí)識(shí)別圖片 } private void AddTimer() { timer = new System.Timers.Timer(); timer.Enabled = true; timer.Interval = 200; timer.Start(); timer.Elapsed += new ElapsedEventHandler(PicToQRCode); } private void PicToQRCode(object sender, ElapsedEventArgs e) { if (_cameraHelper.img == null) return; BinaryBitmap bitmap = null; try { MemoryStream ms = new MemoryStream(); _cameraHelper.img.Save(ms, System.Drawing.Imaging.ImageFormat.Bmp); byte[] bt = ms.GetBuffer(); ms.Close(); LuminanceSource source = new RGBLuminanceSource(bt, _cameraHelper.img.Width, _cameraHelper.img.Height); bitmap = new BinaryBitmap(new ZXing.Common.HybridBinarizer(source)); } catch (Exception ex) { return; } Result result=null; try { //開(kāi)始解碼 result = new MultiFormatReader().decode(bitmap); } catch (ReaderException ex) { resultStr = ex.ToString(); } if (result != null) { resultStr = result.Text; this.DialogResult = DialogResult.OK; this.Close(); }}
窗體關(guān)閉時(shí),記得釋放定時(shí)器 關(guān)閉攝像頭(不然異常滿天飛):
private void CameraQR_FormClosing(object sender, FormClosingEventArgs e) { if (timer != null) { timer.Dispose(); } _cameraHelper.CloseDevice(); }
CameraHelper類(lèi):
public class CameraHelper { public FilterInfoCollection _videoDevices;//本機(jī)攝像硬件設(shè)備列表 public VideoSourcePlayer _videoSourcePlayer;//視頻畫(huà)布 public Bitmap img = null;//全局變量,保存每一次捕獲的圖像 public System.Drawing.Image CaptureImage(VideoSourcePlayer sourcePlayer = null) { if (sourcePlayer == null || sourcePlayer.VideoSource == null) { if (_videoSourcePlayer == null) return null; else { sourcePlayer = _videoSourcePlayer; } } try { if (sourcePlayer.IsRunning) { System.Drawing.Image bitmap = sourcePlayer.GetCurrentVideoFrame(); return bitmap; } return null; } catch (Exception ex) { return null; } } public FilterInfoCollection CreateFilterInfoCollection() { if (_videoDevices != null) return _videoDevices; _videoDevices = new FilterInfoCollection(FilterCategory.VideoInputDevice); return _videoDevices; } public VideoCaptureDevice ConnectDevice(VideoSourcePlayer videoSourcePlayer, FilterInfo filterInfo = null) { VideoCaptureDevice videoSource = new VideoCaptureDevice(); if (filterInfo == null) { videoSource = new VideoCaptureDevice(_videoDevices[_videoDevices.Count - 1].MonikerString); } else { videoSource = new VideoCaptureDevice(filterInfo.MonikerString); } videoSource.NewFrame += new NewFrameEventHandler(video_NewFrame); videoSourcePlayer.VideoSource = videoSource; videoSourcePlayer.Start(); _videoSourcePlayer = videoSourcePlayer; return videoSource; } private void video_NewFrame(object sender, NewFrameEventArgs eventArgs) { img = (Bitmap)eventArgs.Frame.Clone(); } public void CloseDevice(VideoSourcePlayer videoSourcePlayer = null) { if (videoSourcePlayer == null) { if (_videoSourcePlayer == null) return; _videoSourcePlayer.SignalToStop(); } else { videoSourcePlayer.SignalToStop(); } } }
我用的測(cè)試二維碼是:
最終的別結(jié)果為:
代碼:https://github.com/Binzm/ScanQRCode.git
以上就是winform 調(diào)用攝像頭掃碼識(shí)別二維碼的實(shí)現(xiàn)步驟的詳細(xì)內(nèi)容,更多關(guān)于winform 調(diào)用攝像頭識(shí)別二維碼的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
- C# winform點(diǎn)擊生成二維碼實(shí)例代碼
- 新手小白用C# winform 讀取Excel表的實(shí)現(xiàn)
- C# WinForm狀態(tài)欄實(shí)時(shí)顯示當(dāng)前時(shí)間(窗體狀態(tài)欄StatusStrip示例)
- C# 使用Winform 獲取下拉框 選中的值
- C#-WinForm跨線程修改UI界面的示例
- Winform 實(shí)現(xiàn)進(jìn)度條彈窗和任務(wù)控制
- c# winform 解決PictureBox 無(wú)法打印全部圖片的問(wèn)題
- C# winform中窗口關(guān)閉按鈕的隱藏與禁用詳解
- C# WinForm-Timer控件的使用
- C# Winform實(shí)現(xiàn)波浪滾動(dòng)效果
- C# Winform按鈕中圖片實(shí)現(xiàn)左圖右字的效果實(shí)例
相關(guān)文章
C#實(shí)現(xiàn)把指定數(shù)據(jù)寫(xiě)入串口
這篇文章主要介紹了C#實(shí)現(xiàn)把指定數(shù)據(jù)寫(xiě)入串口,直接給出示例代碼,需要的朋友可以參考下2015-06-06C# webservice接口編寫(xiě)、發(fā)布與測(cè)試
這篇文章主要介紹了C# webservice接口編寫(xiě)、發(fā)布與測(cè)試,文章通過(guò)圖文結(jié)合的方式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或共組有一定的幫助,需要的朋友可以參考下2024-07-07winfrom 在業(yè)務(wù)層實(shí)現(xiàn)事務(wù)控制的小例子
winfrom 在業(yè)務(wù)層實(shí)現(xiàn)事務(wù)控制的小例子,需要的朋友可以參考一下2013-03-03c# WPF實(shí)現(xiàn)Windows資源管理器(附源碼)
這篇文章主要介紹了c# WPF實(shí)現(xiàn)Windows資源管理器的示例(附源碼),幫助大家更好的理解和學(xué)習(xí)使用c#,感興趣的朋友可以了解下2021-03-03比Math類(lèi)庫(kù)abs()方法性能更高的取絕對(duì)值方法介紹
這篇文章主要給大家介紹了一種比Math類(lèi)庫(kù)abs()方法性能更高的取絕對(duì)值方法的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-04-04