Zint類用於產生二維碼。https://sourceforge.net/projects/zint/html
Zxing類用於讀取二維碼. https://github.com/zxing/zxinggit
AForge類用於初始攝像頭等。http://www.aforgenet.com/framework/downloads.htmlgithub
以上三個類爲開源的第三方類,可直接引用。數組
如下爲用AForge和ZXing實時讀取二維碼的代碼:ide
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using ZXing; using ZXing.Common; using System.Drawing.Imaging; using AForge; using AForge.Controls; using AForge.Imaging; using AForge.Video; using AForge.Video.DirectShow; namespace AutoScan { public partial class Form1 : Form { private FilterInfoCollection videoDevices; private VideoCaptureDevice videoSource; Bitmap bmp = null; //全局變量,保存每一次捕獲的圖像 int itop = 0;// 全局變量,記錄掃描線距離頂端的距離 public Form1() { InitializeComponent(); } private void getVideoDevices() { cboDevices.Items.Clear(); try { videoDevices=new FilterInfoCollection(FilterCategory.VideoInputDevice); if (videoDevices.Count>0) { foreach(FilterInfo device in videoDevices) cboDevices.Items.Add(device.Name); } } catch(Exception ex) { MessageBox.Show("not found camera"); } } private void Open() { if (cboDevices.SelectedIndex == -1) return; try { btnOpen.Enabled = false; btnClose.Enabled = true; CloseVideoSource(); videoSource = new VideoCaptureDevice(videoDevices[cboDevices.SelectedIndex].MonikerString); videoSource.DesiredFrameRate = 1; videoSource.DesiredFrameSize = new Size(320, 240); videoSource.NewFrame += new NewFrameEventHandler(newframe); videoSource.Start(); } catch { btnOpen.Enabled = true; btnClose.Enabled = false; return; } timer1.Enabled = true;//解析二維碼 timer2.Enabled = true;//啓動繪製視頻中的掃描線 } private void Stop() { CloseVideoSource(); } private void newframe(object sender, NewFrameEventArgs args) { bmp = (Bitmap)args.Frame.Clone(); } private void Form1_Load(object sender, EventArgs e) { timer1.Enabled = false; timer2.Enabled = false; getVideoDevices(); } private void CloseVideoSource() { timer1.Enabled = false; timer2.Enabled = false; if (videoSource == null) return; if (videoSource.IsRunning) { videoSource.SignalToStop(); videoSource.WaitForStop(); videoSource = null; pictureBox1.Image = null; } btnOpen.Enabled = true; btnClose.Enabled = false; txtMsg.Clear(); } private void ScanBarcode() { if (pictureBox1.Image == null) { MessageBox.Show("請載入圖像資源!"); return; } //設置讀取二維碼 DecodingOptions decodeOption = new DecodingOptions(); decodeOption.PossibleFormats = new List<BarcodeFormat>(){ BarcodeFormat.QR_CODE }; //讀取操做 BarcodeReader bar = new BarcodeReader(); bar.Options = decodeOption; ZXing.Result rs = bar.Decode(pictureBox1.Image as Bitmap); if (rs == null) { txtMsg.Text = "讀取失敗"; MessageBox.Show("讀取失敗"); } else { txtMsg.Text = rs.Text; MessageBox.Show("讀取成功,內容:" + rs.Text); } } private void timer2_Tick(object sender, EventArgs e) { timer2.Enabled = false; try { if (bmp == null) return; Bitmap bmp2 = (Bitmap)bmp.Clone(); Pen p = new Pen(Color.GreenYellow); p.Width = 2; Graphics g=Graphics.FromImage(bmp2); System.Drawing.Point p1 = new System.Drawing.Point(0, itop); System.Drawing.Point p2 = new System.Drawing.Point(pictureBox1.Width,itop); g.DrawLine(p, p1, p2); g.Dispose(); itop += 2; itop = itop % pictureBox1.Height; pictureBox1.Image = bmp2; } finally { timer2.Enabled = true; } } private void timer1_Tick(object sender, EventArgs e) { Result result; try { if (bmp == null) return; try { BarcodeReader br = new BarcodeReader(); result = br.Decode(bmp); } catch(Exception ex) { return; } /* #region //將圖片轉換成byte數組 MemoryStream ms = new MemoryStream(); bmp.Save(ms, ImageFormat.Bmp); byte[] bt = ms.GetBuffer(); ms.Close(); #endregion LuminanceSource source = new RGBLuminanceSource(bt, bmp.Width, bmp.Height); BinaryBitmap bitmap = new BinaryBitmap(new ZXing.Common.HybridBinarizer(source)); try { result = new MultiFormatReader().decode(bitmap); } catch (ReaderException ex) { return; }*/ if (result != null) { txtMsg.Text = result.Text; } } finally { timer1.Enabled = true; } } private void btnClose_Click(object sender, EventArgs e) { CloseVideoSource(); } private void btnOpen_Click(object sender, EventArgs e) { Open(); } } }
界面(黃綠色條爲掃描時上下滾動的線條,把條形碼放在攝像頭處便可掃描):spa