• C#


    前言

    作为一名资深Delphi7程序员,想要实现摄像头扫描一维码/二维码功能,发现所有免费的第三方库都没有简便的实现办法,通用的OpenCV或者ZXing库基本上只支持XE以上的版本,而且一维码的识别还需要自己重新写,费时费力。最近,心里滋生一些用其他语言实现的想法。本篇讲解使用VS2019 C#程序调用AForge库实现调用摄像头拍照功能,接下来的几天学习使用ZXing库实现一维码/二维码的生成和识别,这样就能够做到,程序实现摄像头扫描一维码/二维码,并获取到码值。

    AForge库的引用

    新建一个C# WinFrm应用程序,右键解决方案项目,选择管理NuGet程序包,并安装必要的AForge库,如下图。

    如果没有搜索到时,需要新增程序包源,然后重新搜索安装即可,如下图:

    窗体控件部署

    在窗体上添加必要的控件。当AForge库安装成功之后,可以在工具栏看到AForge.NET控件包,如下图。

    核心代码

    窗体载入时,枚举当前设备所有视频输入设备,并加载到设备列表中。

     1         /// <summary>
     2         /// 窗体初始化时,枚举所有视频输入设备,并加载到cmbDeviceLists中
     3         /// </summary>
     4         /// <param name="sender"></param>
     5         /// <param name="e"></param>
     6         private void MainFrm_Load(object sender, EventArgs e)
     7         {
     8             try
     9             {
    10                 videoDevices = new FilterInfoCollection(FilterCategory.VideoInputDevice);
    11                 if (videoDevices.Count == 0)
    12                     throw new ApplicationException();
    13                 foreach (FilterInfo device in videoDevices)
    14                 {
    15                     cmbDeviceLists.Items.Add(device.Name);
    16                 }
    17                 cmbDeviceLists.SelectedIndex = 0;
    18             }
    19             catch (ApplicationException)
    20             {
    21                 cmbDeviceLists.Items.Add("No local capture devices");
    22                 videoDevices = null;
    23             }
    24         }

    打开相机

     1         /// <summary>
     2         /// 打开相机
     3         /// </summary>
     4         /// <param name="sender"></param>
     5         /// <param name="e"></param>
     6         private void btnOpenCamera_Click(object sender, EventArgs e)
     7         {
     8             VideoCaptureDevice videoSource = new VideoCaptureDevice(videoDevices[cmbDeviceLists.SelectedIndex].MonikerString);
     9             this.videoSourcePlayer.VideoSource = videoSource;
    10             this.videoSourcePlayer.Start();
    11             this.btnOpenCamera.Enabled = false;
    12             this.btnTakePic.Enabled = true;
    13             this.btnExit.Enabled = true;
    14         }

    拍照

     1         /// <summary>
     2         /// 拍照
     3         /// </summary>
     4         /// <param name="sender"></param>
     5         /// <param name="e"></param>
     6         private void btnTakePic_Click(object sender, EventArgs e)
     7         {
     8             try
     9             {
    10                 if (this.videoSourcePlayer.IsRunning)
    11                 {
    12                     this.pbImage.Visible = true;
    13                     Bitmap bitMap = this.videoSourcePlayer.GetCurrentVideoFrame();
    14                     this.pbImage.Image = bitMap;
    15                     //设置图片相对控件的大小
    16                     this.pbImage.SizeMode = PictureBoxSizeMode.StretchImage;
    17                     this.btnSavePic.Enabled = true;
    18                 }
    19             }
    20             catch (Exception ex)
    21             {
    22                 MessageBox.Show("摄像头异常:" + ex.Message);
    23             }
    24         }

    保存图片

     1         /// <summary>
     2         /// 保存图片
     3         /// </summary>
     4         /// <param name="sender"></param>
     5         /// <param name="e"></param>
     6         private void btnSavePic_Click(object sender, EventArgs e)
     7         {
     8             BitmapSource bitmapSource = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(
     9                                     videoSourcePlayer.GetCurrentVideoFrame().GetHbitmap(),
    10                                     IntPtr.Zero,
    11                                      Int32Rect.Empty,
    12                                     BitmapSizeOptions.FromEmptyOptions());
    13             PngBitmapEncoder pE = new PngBitmapEncoder();
    14             pE.Frames.Add(BitmapFrame.Create(bitmapSource));
    15             string picName = GetImagePath() + "\" + "Test" + ".bmp";
    16             if (File.Exists(picName))
    17             {
    18                 File.Delete(picName);
    19             }
    20             using (Stream stream = File.Create(picName))
    21             {
    22                 pE.Save(stream);
    23             }
    24             MessageBox.Show("保存成功!根路径Imgs文件夹下!");
    25         }

    关闭相机

     1         /// <summary>
     2         /// 关闭相机
     3         /// </summary>
     4         /// <param name="sender"></param>
     5         /// <param name="e"></param>
     6         private void btnExit_Click(object sender, EventArgs e)
     7         {
     8             videoSourcePlayer.SignalToStop();
     9             videoSourcePlayer.WaitForStop();
    10             this.btnOpenCamera.Enabled = true;
    11             this.btnTakePic.Enabled = false;
    12             this.btnExit.Enabled = false;
    13             this.pbImage.Visible = false;
    14         }

    程序退出

    1         private void MainFrm_FormClosed(object sender, FormClosedEventArgs e)
    2         {
    3             videoSourcePlayer.SignalToStop();
    4             videoSourcePlayer.WaitForStop();
    5         }

    实现效果

    至此,已全部完成! 

      作者:Jeremy.Wu
      出处:https://www.cnblogs.com/jeremywucnblog/
      本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

  • 相关阅读:
    DDD:再谈:实体能否处于非法状态?
    EntityFramework:迁移工具入门
    技术人生:态度决定人生
    EntityFramework:EF Migrations Command Reference
    DDD:聊天笔记
    DCI:DCI学习总结
    DCI:The DCI Architecture: A New Vision of Object-Oriented Programming
    设计原则:消除Switch...Case的过程,可能有点过度设计了。
    .NET:动态代理的 “5 + 1” 模式
    Silverlight:《Pro Silverlight5》读书笔记 之 Dependency Properties And Routed Event
  • 原文地址:https://www.cnblogs.com/jeremywucnblog/p/11838651.html
Copyright © 2020-2023  润新知