.NET MAUI Windows平台ZXing二维码扫描器实现问题求助
.NET MAUI Windows平台ZXing二维码扫描解决方案
1. 确认依赖包版本
确保使用ZXing.Net.Maui的v0.13.0及以上稳定版本(该版本开始完善Windows平台支持)。项目文件中确认包引用:
<PackageReference Include="ZXing.Net.Maui" Version="0.13.0" />
2. 配置Windows平台摄像头权限
在Windows项目的Package.appxmanifest中添加摄像头权限:
- 打开文件切换到功能标签,勾选网络摄像头
- 或直接编辑XML,在
<Capabilities>节点下添加:
<DeviceCapability Name="webcam" />
3. 初始化ZXing服务
在MauiProgram.cs中注册ZXing服务,确保自动适配Windows平台:
using ZXing.Net.Maui; public static MauiApp CreateMauiApp() { var builder = MauiApp.CreateBuilder(); builder .UseMauiApp<App>() .UseBarcodeReader(); // 自动初始化各平台扫描服务 // 其他服务注册逻辑 return builder.Build(); }
4. 适配扫描控件的Windows逻辑
使用BarcodeReaderView控件时,若自动启动扫描失败,可手动适配Windows平台的MediaCapture:
XAML代码
<zxing:BarcodeReaderView x:Name="BarcodeReader" BarcodesDetected="BarcodeReader_BarcodesDetected"> <zxing:BarcodeReaderView.Options> <zxing:BarcodeReaderOptions Formats="QR_CODE" /> </zxing:BarcodeReaderView.Options> </zxing:BarcodeReaderView>
后台代码
#if WINDOWS using Windows.Media.Capture; #endif private void StartScan_Clicked(object sender, EventArgs e) { #if WINDOWS // 手动初始化MediaCapture(自动启动失败时使用) var mediaCapture = new MediaCapture(); await mediaCapture.InitializeAsync(); BarcodeReader.MediaCapture = mediaCapture; #endif BarcodeReader.IsScanning = true; } private void BarcodeReader_BarcodesDetected(object sender, BarcodeDetectedEventArgs e) { var scanResult = e.Results[0].Value; // 切换到UI线程处理结果 MainThread.BeginInvokeOnMainThread(() => { DisplayAlert("扫描结果", scanResult, "确认"); BarcodeReader.IsScanning = false; }); }
5. 原生替代方案(若ZXing.Net.Maui仍有问题)
直接使用Windows原生MediaCapture捕获帧,搭配ZXing.Net解码:
- 安装
ZXing.Net包:
<PackageReference Include="ZXing.Net" Version="0.16.8" />
- 实现帧捕获与解码逻辑:
#if WINDOWS using Windows.Media; using Windows.Media.Capture; using Windows.Media.MediaProperties; using Windows.Storage.Streams; using ZXing; #endif private MediaCapture _mediaCapture; private BarcodeReader _barcodeReader; #if WINDOWS private async Task InitializeScanner() { _mediaCapture = new MediaCapture(); await _mediaCapture.InitializeAsync(); // 设置预览分辨率 var previewProps = _mediaCapture.VideoDeviceController.GetMediaStreamProperties(MediaStreamType.VideoPreview) as VideoEncodingProperties; previewProps.Width = 640; previewProps.Height = 480; await _mediaCapture.VideoDeviceController.SetMediaStreamPropertiesAsync(MediaStreamType.VideoPreview, previewProps); _barcodeReader = new BarcodeReader { Options = new ZXing.Common.DecodingOptions { PossibleFormats = new List<BarcodeFormat> { BarcodeFormat.QR_CODE } } }; // 注册帧捕获事件 _mediaCapture.VideoFrameArrived += MediaCapture_VideoFrameArrived; } private async void MediaCapture_VideoFrameArrived(MediaCapture sender, MediaCaptureVideoFrameArrivedEventArgs args) { using var frame = sender.GetPreviewFrameAsync().GetAwaiter().GetResult(); using var softwareBitmap = frame.SoftwareBitmap; // 转换为ZXing可处理的字节数据 var buffer = softwareBitmap.LockBuffer(BitmapBufferAccessMode.Read); var iBuffer = buffer.CreateReference() as IBuffer; var bytes = new byte[iBuffer.Length]; await iBuffer.ReadAsync(bytes.AsBuffer(), (uint)iBuffer.Length, InputStreamOptions.None); var result = _barcodeReader.Decode(bytes, softwareBitmap.PixelWidth, softwareBitmap.PixelHeight, ZXing.Common.RGBLuminanceSource.BitmapFormat.Gray8); if (result != null) { MainThread.BeginInvokeOnMainThread(() => { DisplayAlert("扫描结果", result.Text, "确认"); _mediaCapture.StopPreviewAsync(); }); } } #endif
常见问题排查
- 检查Windows系统权限:设置→隐私和安全性→摄像头,确保应用已获得权限
- 未打包的桌面应用需通过代码手动请求权限,打包为MSIX应用则依赖
Package.appxmanifest的权限声明 - 解码逻辑需放在后台线程,避免阻塞UI
内容的提问来源于stack exchange,提问作者Muhammad Abdul Rafay
相关产品推荐
相关产品推荐

