软件编程
位置:首页>> 软件编程>> C#编程>> winform 调用摄像头扫码识别二维码的实现步骤

winform 调用摄像头扫码识别二维码的实现步骤

作者:随风去远方  发布时间:2022-08-08 21:50:20 

标签:winform,调用,摄像头,识别,二维码

因为公司业务需求,需要在Windows系统下调用摄像头识别二维码需求,就有了这个功能。

我根据网上网友提供的一些资料,自己整合应用到项目中,效果还不错(就是感觉像素不是太好)

现在将调用摄像头+识别二维码这两个功能单独出来写到这里,供大家讨论和参考。

有什么不足或者问题大家可以提出来,共同改进共同进步

创建一个空的winform项目解决方案,我起名叫他:ScanQRCode

将Form1作为主窗体,设置相关属性:

StartPosition:CenterScreen (窗体居中)

添加一个居中标题:


private void LoadTitleCenterData()
{
     string titleMsg ="二维码识别主界面";
     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中添加一个TableLayoutPanel,三行三列,比例按照百分比:10%,80%,10%这样

在TableLayoutPanel的80%中再添加一个TableLayoutPanel,还是行比例:20%,80%这样(二八定律)

在TableLayoutPanel中添加Panel,在其中手动在添加几个按钮和label

最终界面这样(能看就行):

winform 调用摄像头扫码识别二维码的实现步骤

添加一个二维码识别界面CameraQR:

使用Nuget添加引用,搜索AForge,将如下程序包引入:

winform 调用摄像头扫码识别二维码的实现步骤

添加一个识别二维码的窗体,命名名称为:CameraQR

将VideoSourcePlayer添加到窗体中,Fill显示:

winform 调用摄像头扫码识别二维码的实现步骤

窗体中定义几个私有变量:


private AForge.Video.DirectShow.FilterInfoCollection _videoDevices;//摄像设备
System.Timers.Timer timer;//定时器
CameraHelper _cameraHelper = new CameraHelper();//视屏设备操作类

窗体Load事件中获取拍照设备列表,并将第一个设备作为摄像设备(如有前后两个或多个摄像头,自己去改一下代码,设置成可以选择的,在CameraHelper中的CreateFilterInfoCollection()中):


private void CameraQR_Load(object sender, EventArgs e)
{
     // 获取视频输入设备
     _videoDevices = _cameraHelper.CreateFilterInfoCollection();//获取拍照设备列表
     if (_videoDevices.Count == 0)
     {
       MessageBox.Show("无设备");
       this.Dispose();
       this.Close();
       return;
     }
     resultStr = "";//二维码识别字符串清空
     _cameraHelper.ConnectDevice(videoSourcePlayer1);//连接打开设备
}

组件初始化完成之后,添加一个定时任务,用来阶段性识别摄像设备中的图片资源,我写的是每200毫秒去识别一次,如果图片中有二维码,就识别二维码;识别成功之后,关闭窗体,将识别结果返回给上一个界面,此处需要一个有识别二维码程序包

使用Nuget添加引用,搜索ZXing,将如下程序包引入:

winform 调用摄像头扫码识别二维码的实现步骤

 代码如下(核心代码基本就这些):


public CameraQR()
{
 this.MinimizeBox = false;
 this.MaximizeBox = false;
 InitializeComponent();
 LoadTitleCenterData();
 CheckForIllegalCrossThreadCalls = false;//多线程中访问窗体控件资源不会异常
 AddTimer();//定时识别图片
}

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
     {
       //开始解码
       result = new MultiFormatReader().decode(bitmap);
     }
     catch (ReaderException ex)
     {
       resultStr = ex.ToString();
     }
     if (result != null)
     {
       resultStr = result.Text;
       this.DialogResult = DialogResult.OK;
       this.Close();
     }}

窗体关闭时,记得释放定时器 关闭摄像头(不然异常满天飞):


private void CameraQR_FormClosing(object sender, FormClosingEventArgs e)
{
  if (timer != null)
  {
    timer.Dispose();
  }
   _cameraHelper.CloseDevice();
}

CameraHelper类:


public class CameraHelper
{
 public FilterInfoCollection _videoDevices;//本机摄像硬件设备列表
 public VideoSourcePlayer _videoSourcePlayer;//视频画布
 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();
   }
 }
}

我用的测试二维码是:

winform 调用摄像头扫码识别二维码的实现步骤

最终的别结果为:

winform 调用摄像头扫码识别二维码的实现步骤

代码:https://github.com/Binzm/ScanQRCode.git

来源:https://www.cnblogs.com/19930521zhang/p/14330585.html

0
投稿

猜你喜欢

手机版 软件编程 asp之家 www.aspxhome.com