MAUI Blazor学习10-BarcodeScanner扫描二维码
MAUI Blazor学习10-BarcodeScanner扫描二维码
MAUI Blazor系列目录
- MAUI Blazor学习1-移动客户端Shell布局 - SunnyTrudeau - 博客园 (cnblogs.com)
- MAUI Blazor学习2-创建移动客户端Razor页面 - SunnyTrudeau - 博客园 (cnblogs.com)
- MAUI Blazor学习3-绘制ECharts图表 - SunnyTrudeau - 博客园 (cnblogs.com)
- MAUI Blazor学习4-绘制BootstrapBlazor.Chart图表 - SunnyTrudeau - 博客园 (cnblogs.com)
- MAUI Blazor学习5-BLE低功耗蓝牙 - SunnyTrudeau - 博客园 (cnblogs.com)
- MAUI Blazor学习6-扫描二维码 - SunnyTrudeau - 博客园 (cnblogs.com)
- MAUI Blazor学习7-实现登录跳转页面 - SunnyTrudeau - 博客园 (cnblogs.com)
- MAUI Blazor学习8-支持多语言 - SunnyTrudeau - 博客园 (cnblogs.com)
- 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