C# 二维码扫描
Zint类用于产生二维码。https://sourceforge.net/projects/zint/
Zxing类用于读取二维码. https://github.com/zxing/zxing
AForge类用于初始摄像头等。http://www.aforgenet.com/framework/downloads.html
以上三个类为开源的第三方类,可直接引用。
以下为用AForge和ZXing实时读取二维码的代码:
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(); } } }
界面(黄绿色条为扫描时上下滚动的线条,把条形码放在摄像头处即可扫描):