MAUI Blazor学习10-BarcodeScanner扫描二维码

发布时间 2023-10-24 22:16:51作者: SunnyTrudeau

MAUI Blazor学习10-BarcodeScanner扫描二维码

MAUI Blazor系列目录

  1. MAUI Blazor学习1-移动客户端Shell布局 - SunnyTrudeau - 博客园 (cnblogs.com)
  2. MAUI Blazor学习2-创建移动客户端Razor页面 - SunnyTrudeau - 博客园 (cnblogs.com)
  3. MAUI Blazor学习3-绘制ECharts图表 - SunnyTrudeau - 博客园 (cnblogs.com)
  4. MAUI Blazor学习4-绘制BootstrapBlazor.Chart图表 - SunnyTrudeau - 博客园 (cnblogs.com)
  5. MAUI Blazor学习5-BLE低功耗蓝牙 - SunnyTrudeau - 博客园 (cnblogs.com)
  6. MAUI Blazor学习6-扫描二维码 - SunnyTrudeau - 博客园 (cnblogs.com)
  7. MAUI Blazor学习7-实现登录跳转页面 - SunnyTrudeau - 博客园 (cnblogs.com)
  8. MAUI Blazor学习8-支持多语言 - SunnyTrudeau - 博客园 (cnblogs.com)
  9. MAUI Blazor学习9-VS Code开发调试MAUI入门 - SunnyTrudeau - 博客园 (cnblogs.com)

  

MAUI可以用ZXing扫码,但是测试发现性能低下,有的二维码印刷在产品标签表面,受光线,薄膜遮盖等因素影响,ZXing无法识别二维码。但是微信,支付宝可以快速得到扫码结果,查看了网上一些资料,了解到大厂对于扫码这个功能是投入了大量的资源去优化的,因此扫码性能比主流的开源库好很多。微信2021年开源了自家的扫码库,使用了AI技术,需要下载model文件。参考:

https://blog.csdn.net/lw112190/article/details/130963780

C# OpenCvSharp+ 微信二维码引擎实现二维码识别_c# 微信二维码_天天代码码天天的博客-CSDN博客》

我用图片识别的方式做了微信扫码库测试,性能仍然很差。

 

BarcodeScanner.Mobile是一个高性能的扫码库,测试发现性能比ZXing好很多。参见:

https://github.com/JimmyPun610/BarcodeScanner.Mobile

Powerful barcode scanning library using Google MLKit API. For MAUI and Xamarin Forms.

 

MAUI项目使用BarcodeScanner.Mobile组件

NuGet安装依赖库,安装最新的预览版

<PackageReference Include="BarcodeScanner.Mobile.Maui" Version="7.0.0.1-pre" />

 

参考GitHub仓库DEMO写代码。初始化添加引用ConfigureMauiHandlers

D:\Software\gitee\mauiblazorapp\MaBlaApp\MauiProgram.cs

 

public static class MauiProgram
    {
        public static MauiApp CreateMauiApp()
        {
            var builder = MauiApp.CreateBuilder();
            builder
                .UseMauiApp<App>()
                .ConfigureFonts(fonts =>
                {
                    fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
                    fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold");
                })
                //.ConfigureBarcodeScanner();
                .ConfigureMauiHandlers(handlers =>
                {
                    handlers.AddBarcodeScannerHandler();
                });
            return builder.Build();
        }
    }

 

 

添加扫码功能辅助类

定义一个扫码功能辅助类,辅助调用扫码弹出页面

D:\Software\gitee\mauiblazorapp\MaBlaApp\Data\BarcodeScannerManager.cs

 

/// <summary>
/// 扫码功能辅助类
/// </summary>
public static class BarcodeScannerManager
{
    /// <summary>
    /// 扫码结果事件,通知订阅者处理扫码结果
    /// </summary>
    public static event EventHandler<BarcodeScannerResult>? HandleBarcodeResult;

    private static BarcodeScannerPage _barcodeScannerPage;

    /// <summary>
    /// 扫码页面传递扫码结果
    /// </summary>
    /// <param name="result"></param>
    public static void OnHandleBarcodeResult(string result)
    {
        HandleBarcodeResult?.Invoke(null, new BarcodeScannerResult(result));
    }

    /// <summary>
    /// 调用者打开扫码页面
    /// </summary>
    /// <returns></returns>
    public static async Task StartScan()
    {
        //Ask for permission first
        bool allowed = false;
        allowed = await BarcodeScanner.Mobile.Methods.AskForRequiredPermission();
        if (allowed)
        {
            if (_barcodeScannerPage is null)
            {
                _barcodeScannerPage = new BarcodeScannerPage();
            }

            _barcodeScannerPage.SetScannig(true);

            Application.Current.MainPage.Navigation.PushModalAsync(_barcodeScannerPage);
        }
        else
        {
            Application.Current.MainPage.DisplayAlert("Alert", "You have to provide Camera permission", "Ok");
        }
    }
}

/// <summary>
/// 扫码结果
/// </summary>
public class BarcodeScannerResult : EventArgs
{
    public string Result;
    public BarcodeScannerResult(string result)
    {
        Result = result;
    }
}

 

 

编写扫码页面

新建扫码页面BarcodeScannerPage

页面内容直接抄GitHub仓库的BarcodeScanner.Mobile-master\SampleApp.Maui\Page2.xaml.cs,只是把震动提示VibrationOnDetected关掉了。

D:\Software\gitee\mauiblazorapp\MaBlaApp\Pages\BarcodeScannerPage.xaml

 

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="MaBlaApp.Pages.BarcodeScannerPage"
             xmlns:gv="clr-namespace:BarcodeScanner.Mobile;assembly=BarcodeScanner.Mobile.Maui"
             Title="BarcodeScannerPage">
    <Grid HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="*" />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>
        <StackLayout
                Grid.Row="0"
                HorizontalOptions="FillAndExpand"
                Orientation="Horizontal">
            <Button
                    x:Name="CancelButton"
                    BackgroundColor="#FF0000"
                    Clicked="CancelButton_Clicked"
                    CornerRadius="0"
                    HorizontalOptions="StartAndExpand"
                    Text="Cancel"
                    TextColor="White"
                    />
            <Button
                    x:Name="FlashlightButton"
                    BackgroundColor="#0075FF"
                    Clicked="FlashlightButton_Clicked"
                    CornerRadius="0"
                    HorizontalOptions="CenterAndExpand"
                    Text="Flashlight"
                    TextColor="White"
                    />

            <Button
                    x:Name="SwitchCameraButton"
                    BackgroundColor="Brown"
                    Clicked="SwitchCameraButton_Clicked"
                    CornerRadius="0"
                    HorizontalOptions="EndAndExpand"
                    Text="Switch Camera"
                    TextColor="White"
                    />

        </StackLayout>
        <!--  Fill the screen with CameraView  -->
        <Grid
                Grid.Row="1"
                ColumnDefinitions="*,300,*"
                ColumnSpacing="0"
                RowDefinitions="*,200,*"
                RowSpacing="0">
            <gv:CameraView
                    x:Name="Camera"
                    Grid.Row="1"
                    Grid.Column="1"
                    OnDetected="CameraView_OnDetected"
                    PreviewHeight="200"
                    PreviewWidth="300"
                    TorchOn="True"
                    VibrationOnDetected="False" />
        </Grid>
        <Label
                Grid.Row="2"
                FontSize="Medium"
                HorizontalOptions="FillAndExpand"
                HorizontalTextAlignment="Center"
                Text="Scan QRCode"
                TextColor="Red" />
    </Grid>
</ContentPage>

 

扫码成功之后,调用BarcodeScannerManager.OnHandleBarcodeResult传递扫码结果给调用者去处理,然后关闭扫码页面。

 

public partial class BarcodeScannerPage : ContentPage
{
    public BarcodeScannerPage()
    {
        InitializeComponent();
        On<iOS>().SetUseSafeArea(true);
    }

    private async void CancelButton_Clicked(object sender, EventArgs e)
    {
        Debug.WriteLine($"取消扫码结果");

        SetScannig(false);

        await Navigation.PopModalAsync();
    }

    private void FlashlightButton_Clicked(object sender, EventArgs e)
    {
        Camera.TorchOn = !Camera.TorchOn;
    }

    private void SwitchCameraButton_Clicked(object sender, EventArgs e)
    {
        Camera.CameraFacing = Camera.CameraFacing == CameraFacing.Back
                                  ? CameraFacing.Front
                                  : CameraFacing.Back;
    }

    private void CameraView_OnDetected(object sender, OnDetectedEventArg e)
    {
        List<BarcodeResult> obj = e.BarcodeResults;

        string result = string.Empty;
        for (int i = 0; i < obj.Count; i++)
        {
            result += $"Type : {obj[i].BarcodeType}, Value : {obj[i].DisplayValue}{Environment.NewLine}";
        }
        
        Debug.WriteLine($"扫码结果: {result}");

        this.Dispatcher.Dispatch(async () =>
        {
            //await DisplayAlert("Result", result, "OK");
            //GoogleVisionBarCodeScanner.Methods.Reset();

            //调用订阅者处理扫码结果
            BarcodeScannerManager.OnHandleBarcodeResult(result);

            SetScannig(false);

            await Navigation.PopModalAsync();
        });

    }

    /// <summary>
    /// 打开扫码页面之前先设置开始扫描,关闭扫码页面之前先停止扫描
    /// </summary>
    /// <param name="isScanning"></param>
    public void SetScannig(bool isScanning)
    {
        Camera.IsScanning = isScanning;
    }
}

 

 

测试

使用华为手机鸿蒙4(安卓12)VS2022调试运行,找了一个有点小的二维码,在光线不太清晰的情况下,用ZXing扫不出来。

BarcodeScanner.Mobile不到1秒能扫到结果。

 

DEMO代码地址:https://gitee.com/woodsun/mauiblazorapp