You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Maui Blazor Hybrid中摄像头扫码(QR Code)识别失败求助

解决.NET Maui Blazor Hybrid中ZXing扫码无法识别QR Code的问题

问题背景

在.NET Maui Blazor Hybrid项目中,使用ZXing.Net.Maui.Controls实现扫码功能,通过MediaPicker拍摄照片后解码QR Code,始终提示“未找到QR Code”,无法正常识别内容。

核心问题原因

原代码中创建RGBLuminanceSource时硬编码了固定尺寸2000x2000,但实际拍摄的照片尺寸与该值不匹配,导致ZXing无法正确解析图片的亮度数据,最终解码失败。

解决方案

方案一:修复拍照解码的尺寸匹配问题

通过获取图片实际尺寸来创建正确的LuminanceSource,步骤如下:

  1. 安装SkiaSharp.NativeAssets.Maui NuGet包,用于读取图片的实际宽高。
  2. 修改解码方法,替换硬编码尺寸为图片实际尺寸:
// 从流中解码QR Code的方法
private async Task<Result?> DecodeQrCodeFromStream(Stream stream)
{
    try
    {
        // 重置流位置,确保从开头读取
        stream.Position = 0;
        using var bitmap = SKBitmap.Decode(stream);
        if (bitmap == null)
        {
            Logger.LogError("无法解码图片");
            return null;
        }

        // 使用图片实际尺寸创建LuminanceSource
        var luminanceSource = new BitmapLuminanceSource(bitmap);
        var barcodeReader = new BarcodeReaderGeneric();
        // 指定仅扫描QR Code,提升识别效率与准确性
        barcodeReader.Options.PossibleFormats = new List<BarcodeFormat> { BarcodeFormat.QR_CODE };
        
        return barcodeReader.Decode(luminanceSource);
    }
    catch (Exception ex)
    {
        Logger.LogError(ex, "解码QR Code出错: {Message}", ex.Message);
        return null;
    }
}
  1. 调整扫码方法中的流读取逻辑,确保流位置正确:
await using var stream = await photo.OpenReadAsync();
stream.Position = 0; // 重置流起始位置
var result = await DecodeQrCodeFromStream(stream);

方案二:改用ZXing实时扫描控件(推荐)

使用ZXing.Net.Maui提供的BarcodeReaderView实现实时扫码,无需手动拍照解码,体验更流畅且可靠性更高:

  1. 在Razor页面中添加实时扫描控件:
@page "/UserProfile"
@using ZXing.Net.Maui.Controls

<BarcodeReaderView 
    @ref="_barcodeReaderView"
    IsScanning="false" 
    IsDetecting="false"
    BarcodesDetected="BarcodesDetected"
    WidthRequest="350"
    HeightRequest="350">
    <CameraPreviewView />
</BarcodeReaderView>

<CustomButtonComponent OnClick="ToggleScanning">
    @(_isScanning ? "停止扫描" : "开始扫描")
</CustomButtonComponent>
        
<div>@_qrCodeResult</div>

<ErrorMessageComponent @ref="_errorMessage"/>

@code {
    private string? _loggedUserId;
    private User? _user;
    private ErrorMessageComponent? _errorMessage;
    private string? _qrCodeResult = "Not Scanned";
    private bool _isScanning = false;
    private BarcodeReaderView? _barcodeReaderView;

    private void ToggleScanning()
    {
        _isScanning = !_isScanning;
        if (_barcodeReaderView != null)
        {
            _barcodeReaderView.IsScanning = _isScanning;
            _barcodeReaderView.IsDetecting = _isScanning;
        }
    }

    private async void BarcodesDetected(object sender, BarcodeDetectionEventArgs e)
    {
        if (e.Results.Any())
        {
            var result = e.Results.First();
            _qrCodeResult = result.Value;
            Logger.LogInformation($"QR Code识别结果: {_qrCodeResult}");
            
            // 识别成功后停止扫描
            _isScanning = false;
            if (_barcodeReaderView != null)
            {
                _barcodeReaderView.IsScanning = false;
                _barcodeReaderView.IsDetecting = false;
            }
            
            // 处理关联请求
            await SendLinkRequest(_qrCodeResult);
            StateHasChanged(); // 更新UI显示
        }
    }
    
    private async Task SendLinkRequest(string scannedUrl)
    {
        // 实现接口调用逻辑
    }
}

额外注意事项

  • 确保ZXing.Net.Maui.Controls NuGet包为最新版本,避免兼容性问题。
  • 确认Android和iOS项目的相机权限已正确配置并授予。
  • 方案二的实时扫描功能无需手动处理图片解码,能有效避免尺寸匹配、图片模糊等问题,优先推荐使用。

内容的提问来源于stack exchange,提问作者Sławomir Majchrzak

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 14:48:12