首先我們需要引用兩個第三方元件:AForge和zxing。
Aforge是攝像頭操作元件,zxing是二維碼識别元件。都是開源項目。避免重複造輪子。
其實一些操作代碼我也是參照别人的,若侵犯您的版權,請和我聯系。
此部落格僅供技術交流。
下載下傳和用法大家可以自行搜尋下。

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 }
用了第三方元件,開發難度真是直線下降。内部具體怎麼解碼的,真的是一點不知道。還望有經驗的高手不吝賜教。