WPF实现可视化扫码器的示例代码

 更新时间:2022年11月17日 16:30:02   作者:黑夜中的潜行者  
AForge.NET 是一个专门为开发者和研究者基于C#框架设计的,他包括计算机视觉与人工智能,图像处理,神经网络,遗传算法,机器学习,模糊系统,机器人控制等领域。本文就将用它编写一个可视化扫码器,感兴趣的可以了解一下

概述

以识别粤康码识别为例。现在的深圳进出小区、商场、办公楼、乘坐公共交通工具等都需要出示并扫描健康码,也被称之为“电子哨兵”。不多说那个用的是一般的扫码枪。

摄像头调度

调度摄像头选择使用 AForge.NET

AForge.NET 是一个专门为开发者和研究者基于C#框架设计的,他包括计算机视觉与人工智能,图像处理,神经网络,遗传算法,机器学习,模糊系统,机器人控制等领域。AForge.Net 是C#的一个图像计算机视觉库,该库是一个开源项目,提供很多图像的处理,和视频处理功能。

官方地址:http://www.aforgenet.com/

需要引入三个NuGet包:

  • AForge
  • AForge.Video
  • AForge.Video.DirectShow

如何使用这里先不介绍,后面有完整代码

二维码识别

需要的NuGet包:ZXing.Net

ZXing.Net 是由 Google ZXing 移植并优化改进而来的。

Google ZXing 是目前一个常用的基于Java实现的多种格式的1D/2D条码图像处理库。

这支持的编码方式种类相对齐全,并且支持可移植库。

如何使用这里先不介绍,后面有完整代码

源代码

<Window
    x:Class="HealthCodeIdentification.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:local="clr-namespace:HealthCodeIdentification"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    Title="MainWindow"
    Width="800"
    Height="450"
    WindowStartupLocation="CenterScreen"
    mc:Ignorable="d">
    <Grid Background="AliceBlue">
        <Grid.ColumnDefinitions>
            <ColumnDefinition />
            <ColumnDefinition />
        </Grid.ColumnDefinitions>

        <StackPanel
            Grid.Column="0"
            Margin="10"
            VerticalAlignment="Center">
            <TextBlock
                x:Name="txtTips"
                Margin="0,10"
                HorizontalAlignment="Center" />
            <Image x:Name="imageVideo" />
        </StackPanel>

        <Grid Grid.Column="1" Margin="10">
            <Grid.RowDefinitions>
                <RowDefinition />
                <RowDefinition />
            </Grid.RowDefinitions>

            <TextBox
                x:Name="txtInfo"
                BorderThickness="0"
                TextWrapping="Wrap" />

            <TextBlock
                x:Name="txtCodeColor"
                Grid.Row="1"
                FontSize="32">
                <TextBlock.Style>
                    <Style TargetType="TextBlock">
                        <Style.Triggers>
                            <Trigger Property="Text" Value="绿码">
                                <Setter Property="Foreground" Value="#0d0" />
                            </Trigger>
                            <Trigger Property="Text" Value="黄码">
                                <Setter Property="Foreground" Value="Yellow" />
                            </Trigger>
                            <Trigger Property="Text" Value="红码">
                                <Setter Property="Foreground" Value="Red" />
                            </Trigger>
                        </Style.Triggers>
                    </Style>
                </TextBlock.Style>
            </TextBlock>

        </Grid>
    </Grid>
</Window>
using AForge.Video.DirectShow;
using Newtonsoft.Json;
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Media.Imaging;
using ZXing;

namespace HealthCodeIdentification
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        private FilterInfoCollection _videoDevices;
        private VideoCaptureDevice _videoSource;

        public MainWindow()
        {
            InitializeComponent();
            Loaded += MainWindow_Loaded;
            Closed += MainWindow_Closed;
        }

        private void MainWindow_Loaded(object sender, RoutedEventArgs e)
        {
            OpenVideoCaptureDevice();
        }

        private void MainWindow_Closed(object sender, EventArgs e)
        {
            if (_videoSource is null) return;
            _videoSource.SignalToStop();
        }

        /// <summary>
        /// 查找并打开摄像头
        /// </summary>
        private void OpenVideoCaptureDevice()
        {
            _videoDevices = new FilterInfoCollection(FilterCategory.VideoInputDevice);

            if (_videoDevices.Count > 0)
            {
                _videoSource = new VideoCaptureDevice(_videoDevices[0].MonikerString);
                _videoSource.NewFrame += _camera_NewFrame;
                _videoSource.Start();
                txtTips.Text = "AI扫描已启动,请将健康码对准摄像头";
                return;
            }

            MessageBox.Show("请连接摄像头!", "提示", MessageBoxButton.OK, MessageBoxImage.Warning);
        }

        /// <summary>
        /// 加载视频
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="eventArgs"></param>
        private async void _camera_NewFrame(object sender, AForge.Video.NewFrameEventArgs eventArgs)
        {
            var image = eventArgs.Frame.Clone();
            Image videoImage = (Bitmap)image;
            Bitmap bitmapImage = (Bitmap)image;

            //image.RotateFlip(RotateFlipType.RotateNoneFlipX); // 设置图像旋转

            Graphics g = Graphics.FromImage(videoImage);

            //SolidBrush brush = new SolidBrush(Color.Red);
            //g.DrawString($"时间:{DateTime.Now:yyyy年MM月dd日 HH时mm分ss秒}", new Font("Arial", 18), brush, new PointF(5, 5));
            //brush.Dispose();
            //g.Dispose();

            MemoryStream ms = new MemoryStream();
            videoImage.Save(ms, ImageFormat.Bmp);
            ms.Seek(0, SeekOrigin.Begin);

            BitmapImage bi = new BitmapImage();
            bi.BeginInit();
            bi.StreamSource = ms;
            bi.EndInit();
            bi.Freeze();

            await Dispatcher.BeginInvoke(new ThreadStart(async delegate
             {
                 imageVideo.Source = bi;
                 await QRCodeReader(bitmapImage);
             }));
        }

        private async Task<Task> QRCodeReader(Bitmap bitmap)
        {
            await Dispatcher.BeginInvoke(new ThreadStart(delegate
            {
                BarcodeReader barcodeReader = new BarcodeReader();
                var result = barcodeReader.Decode(bitmap);
                if (result != null)
                {
                    txtInfo.Text = result.ToString();
                    if (result.ToString().StartsWith("{"))
                    {
                        var data = JsonConvert.DeserializeObject<CodeData>(result.ToString());
                        switch (data.c.ToUpper())
                        {
                            case "G":
                                txtCodeColor.Text = "绿码";
                                break;
                            case "Y":
                                txtCodeColor.Text = "黄码";
                                break;
                            case "R":
                                txtCodeColor.Text = "红码";
                                break;
                        }
                    }
                }
            }));
            return Task.CompletedTask;
        }
    }

    public class CodeData
    {
        public string label { get; set; }
        public string cid { get; set; }
        public string cidtype { get; set; }
        public string name { get; set; }
        public string phone { get; set; }
        public string encode { get; set; }
        /// <summary>
        /// 颜色,绿码G,黄码Y,红码R
        /// </summary>
        public string c { get; set; }
        public string t { get; set; }
        public string v { get; set; }
        public string s { get; set; }
    }
}

以上就是WPF实现可视化扫码器的示例代码的详细内容,更多关于WPF可视化扫码器的资料请关注脚本之家其它相关文章!

相关文章

  • c# winform 解决PictureBox 无法打印全部图片的问题

    c# winform 解决PictureBox 无法打印全部图片的问题

    这篇文章主要介绍了c# winform 解决PictureBox 无法打印全部图片的问题,帮助大家更好进行c# winform开发,感兴趣的朋友可以了解下
    2020-12-12
  • C# .NET 中的缓存实现详情

    C# .NET 中的缓存实现详情

    软件开发中最常用的模式之一是 缓存 ,其包括进程内缓存、持久性进程内缓存和分布式缓存,本文我们将主要介绍进程内缓存,需要的朋友可以参考下面文章的具体内容
    2021-09-09
  • C# Split函数根据特定分隔符分割字符串的操作

    C# Split函数根据特定分隔符分割字符串的操作

    这篇文章主要介绍了C# Split函数根据特定分隔符分割字符串的操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-12-12
  • WinForm单例窗体用法实例

    WinForm单例窗体用法实例

    这篇文章主要介绍了WinForm单例窗体,结合实例形式分析了窗体的单例模式定义、实现与使用技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2016-07-07
  • 在WinForm应用程序中快速实现多语言的处理的方法

    在WinForm应用程序中快速实现多语言的处理的方法

    在国际化环境下,越来越多的程序需要做多语言版本,这篇文章主要介绍了在WinForm应用程序中快速实现多语言的处理的方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下。
    2018-07-07
  • C#基础语法:方法参数详解

    C#基础语法:方法参数详解

    这篇文章主要介绍了C#基础语法:方法参数详解,本文讲解了值参数、引用参数、输出参数、参数数组等参数类型,并分别给出代码实例,需要的朋友可以参考下
    2015-06-06
  • C#中如何分割字符串

    C#中如何分割字符串

    这篇文章主要介绍了C#中如何分割字符串问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-02-02
  • C#调用和实现WebService,纯手工打造!

    C#调用和实现WebService,纯手工打造!

    C#调用和实现WebService,纯手工打造! 需要的朋友可以参考一下
    2013-02-02
  • 基于WPF简单实现Meesage消息提醒

    基于WPF简单实现Meesage消息提醒

    这篇文章主要介绍了如何利用WPF简单实现Meesage消息提醒,文中的示例代码讲解详细,对我们学习或工作有一定帮助,需要的可以参考一下
    2023-07-07
  • C#实现滑动开关效果

    C#实现滑动开关效果

    这篇文章主要为大家详细介绍了C#实现滑动开关效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-07-07

最新评论