標籤:
首先我們需要引用兩個第三方組件: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 else25 {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 #endregion13 LuminanceSource source = new RGBLuminanceSource(bt, img.Width, img.Height);14 BinaryBitmap bitmap = new BinaryBitmap(new ZXing.Common.HybridBinarizer(source));15 Result result;16 try17 {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 }
用了第三方組件,開發難度真是直線下降。內部具體怎麼解碼的,真的是一點不知道。還望有經驗的高手不吝賜教。
c# winform調用網路攝影機識別二維碼