IRONSOFTWAREHOME
视频

从BarcodeScanning.Native.Maui迁移到IronBarcode

Curtis Chau
Curtis Chau
Updated: 2026年5月3日

本指南提供了从 BarcodeScanning.Native.Maui 到IronBarcode的完整迁移路径,涵盖了相机事件模式替换、命名空间更改、代码迁移示例以及 BarcodeScanning.Native.Maui 无法处理的场景的处理——Windows MAUI、文件和 PDF 输入、服务器端处理和条形码生成。

为什么要从 BarcodeScanning.MAUI 迁移?

从 BarcodeScanning.Native.Maui 迁移的团队报告了以下触发事件:

Windows MAUI 目标平台要求: BarcodeScanning.Native.Maui 封装了 iOS 和 Android 的原生 API。它目前没有 Windows 版本,也没有相关计划。 如果您的 MAUI 应用同时面向 Windows、iOS 和 Android,则需要一个能够在所有三个目标平台上运行且没有平台特定分支的库。

文件或 PDF 输入已添加到要求中: BarcodeScanning.Native.Maui 仅接受实时摄像头帧。 当用户需要从图库上传图片,或者服务器端端点需要从 PDF 中提取条形码时,该库没有可提供的代码路径。 任何文件或 PDF 条形码应用场景都需要不同的工具。

**iOS UPC-A 数据在生产环境中出现错误:**苹果公司的 Vision 框架为 UPC-A 条形码(EAN-13 编码)返回 13 位数字。 BarcodeScanning.Native.Maui 会直接传递未经校正的数据。 如果 UPC-A 条码以零开头存储,则库存记录、销售点查询或供应链集成可能会悄无声息地遭到破坏。 IronBarcode无需手动规范化即可返回正确的 12 位 UPC-A 值。

**PDF417扫描功能不稳定:**图书馆自身的GitHub问题记录显示,PDF417"问题非常严重——大多数扫描都无法完成"。对于货运标签、驾驶执照和登机牌等扫描件而言,这直接阻碍了扫描工作。

需要生成: BarcodeScanning.Native.Maui 无法生成条形码。 IronBarcode可将 Code128、QR、DataMatrix 和其他格式生成为图像文件或字节数组。

引入服务器端处理: BarcodeScanning.Native.Maui 是一个相机 UI 控件——它不能在服务器进程中运行。 当需要同时进行服务器端条形码读取和移动端扫描时, IronBarcode可以使用相同的软件包和相同的 API 来满足这两个方面的需求。

基本问题

BarcodeScanning.Native.Maui 将条形码读取完全与实时摄像头事件模型绑定在一起。 一旦任何需求不符合该模型,该库就无法提供任何功能:

private void OnBarcodeDetected(object sender, OnDetectionFinishedEventArg e)
{
    var barcode = e.BarcodeResults.FirstOrDefault();
    if (barcode != null)
        ResultLabel.Text = barcode.DisplayValue;
}

IronBarcode接受任何数据输入——相机拍摄的图像、文件、PDF、字节数组——并且可以在所有平台上运行:

using IronBarCode;

private async void ScanBarcodeButton_Clicked(object sender, EventArgs e)
{
    var photo = await MediaPicker.CapturePhotoAsync();
    if (photo == null) return;

    using var stream = await photo.OpenReadAsync();
    using var ms = new MemoryStream();
    await stream.CopyToAsync(ms);

    var results = BarcodeReader.Read(ms.ToArray());
    ResultLabel.Text = results.FirstOrDefault()?.Value ?? "No barcode found";
}

IronBarcode与 BarcodeScanning.MAUI:功能对比

特征BarcodeScanning.MAUIIronBarcode
实时摄像机帧读取是的——CameraView 控件否(使用 MediaPicker 捕获,然后读取)
应用内相机取景器是的——实时连续否——使用通过 MediaPicker 的系统相机 UI
从图像文件中读取是 — BarcodeReader.Read(path)
从字节数组读取数据是 — BarcodeReader.Read(bytes)
从流中读取是 — BarcodeReader.Read(stream)
从PDF文件阅读是 — BarcodeReader.Read(pdf)
条形码生成是 — BarcodeWriter + QRCodeWriter
Windows MAUI 支持
iOS MAUI 支持
Android MAUI 支持
macOS MAUI 支持未记录。
服务器端ASP.NET
Docker / Azure / AWS Lambda
iOS UPC-A 准确性返回 13 位数字(错误),需要手动规范化返回正确的 12 位 UPC-A
PDF417 可靠性"大多数扫描从未发生"(GitHub问题)支持
多条形码检测是(每个框架多个通过 e.BarcodeResults是(ExpectMultipleBarcodes 选项)
阅读速度控制NoneReadingSpeed.Faster / Balanced / Detailed / ExtremeDetail
许可MIT(开源,免费)商业版——Lite749 美元,Plus1499 美元,Professional2999 美元,无限版 5999 美元
.NET Framework支持不(仅限毛伊岛)是的.NET Framework 4.6.2+

快速入门:BarcodeScanning.MAUI 到IronBarcode 的迁移

步骤 1:替换 NuGet 软件包

移除 BarcodeScanning.Native.Maui:

dotnet remove package BarcodeScanning.Native.Maui
SHELL

安装IronBarcode:

dotnet add package IronBarcode
SHELL

步骤 2:更新命名空间

从所有文件中移除 BarcodeScanning 命名空间:

// Remove
using BarcodeScanning;

添加IronBarcode命名空间:

// Add
using IronBarCode;

在XAML文件中,移除scanner: XML命名空间声明:

<!-- Remove this line from ContentPage attributes -->
xmlns:scanner="clr-namespace:BarcodeScanning;assembly=BarcodeScanning.Native.Maui"
XML

步骤 3:初始化许可证

在应用程序启动时添加许可证初始化—在App.xaml.cs

IronBarCode.License.LicenseKey = "YOUR-LICENSE-KEY";

代码迁移示例

相机扫描:将 CameraView 转换为 MediaPicker

CameraView 控件提供了带有连续帧检测的实时取景器。 IronBarcode替代品使用MAUI的MediaPicker打开系统相机,捕获照片并处理结果图像。

条形码扫描.MAUI 方法 — XAML:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:scanner="clr-namespace:BarcodeScanning;assembly=BarcodeScanning.Native.Maui">
    <StackLayout>
        <scanner:CameraView x:Name="CameraView"
                            OnDetectionFinished="OnBarcodeDetected"
                            CameraEnabled="True"
                            BarcodeFormats="All"
                            VerticalOptions="FillAndExpand" />
        <Label x:Name="ResultLabel" Text="Waiting for scan..." />
    </StackLayout>
</ContentPage>
XML

条形码扫描.MAUI 方法 — 代码隐藏:

using BarcodeScanning;

private void OnBarcodeDetected(object sender, OnDetectionFinishedEventArg e)
{
    var barcode = e.BarcodeResults.FirstOrDefault();
    if (barcode != null)
        MainThread.BeginInvokeOnMainThread(() =>
            ResultLabel.Text = barcode.DisplayValue);
}

IronBarcode方法 — XAML:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui">
    <StackLayout>
        <Button Text="Scan Barcode" Clicked="ScanButton_Clicked" />
        <Label x:Name="ResultLabel" Text="Tap to scan..." />
    </StackLayout>
</ContentPage>
XML

IronBarcode方法——代码隐藏:

using IronBarCode;

private async void ScanButton_Clicked(object sender, EventArgs e)
{
    var photo = await MediaPicker.CapturePhotoAsync();
    if (photo == null) return;

    using var stream = await photo.OpenReadAsync();
    using var ms = new MemoryStream();
    await stream.CopyToAsync(ms);

    var results = BarcodeReader.Read(ms.ToArray());
    var first = results.FirstOrDefault();
    ResultLabel.Text = first?.Value ?? "No barcode found";
}

这段代码可以在 iOS、Android 和 Windows MAUI 上运行,无需任何平台特定的分支。 用户体验从应用内实时取景器变为平台的原生相机屏幕——适用于大多数商业应用。 IronBarcode MAUI 阅读指南涵盖了其他配置选项。

每次扫描处理多个条形码

条形码扫描.MAUI 方法:

private void OnBarcodeDetected(object sender, OnDetectionFinishedEventArg e)
{
    foreach (var barcode in e.BarcodeResults)
    {
        MainThread.BeginInvokeOnMainThread(() =>
            Console.WriteLine($"Found: {barcode.DisplayValue}"));
    }
}

IronBarcode方法:

using IronBarCode;

private async void ScanButton_Clicked(object sender, EventArgs e)
{
    var photo = await MediaPicker.CapturePhotoAsync();
    if (photo == null) return;

    using var stream = await photo.OpenReadAsync();
    using var ms = new MemoryStream();
    await stream.CopyToAsync(ms);

    var options = new BarcodeReaderOptions
    {
        Speed = ReadingSpeed.Balanced,
        ExpectMultipleBarcodes = true
    };

    var results = BarcodeReader.Read(ms.ToArray(), options);
    foreach (var result in results)
        Console.WriteLine($"{result.Format}: {result.Value}");
}

ExpectMultipleBarcodes = true 告诉读者在找到第一个条形码后继续扫描。 如果没有这个选项,调用会在第一次匹配时返回,这对于单个条形码的情况来说速度更快。

iOS UPC-A 修复:移除标准化变通方案

如果你的代码库中有 UPC-A 前导零的变通方案,请将其完全删除。 IronBarcode无需任何人工干预即可返回正确的 12 位数值。

条形码扫描.MAUI 方法——已采取变通方案:

private void OnBarcodeDetected(object sender, OnDetectionFinishedEventArg e)
{
    var barcode = e.BarcodeResults.FirstOrDefault();
    if (barcode == null) return;

    var value = barcode.DisplayValue;

    // Workaround: Apple Vision returns 13 digits for UPC-A
    if (barcode.BarcodeFormat == BarcodeFormats.Upca && value.Length == 13)
        value = value.Substring(1);

    ProcessBarcode(value, barcode.BarcodeFormat.ToString());
}

IronBarcode方案——无需任何变通方法:

using IronBarCode;

private async void ScanButton_Clicked(object sender, EventArgs e)
{
    var photo = await MediaPicker.CapturePhotoAsync();
    if (photo == null) return;

    using var stream = await photo.OpenReadAsync();
    using var ms = new MemoryStream();
    await stream.CopyToAsync(ms);

    var results = BarcodeReader.Read(ms.ToArray());
    var first = results.FirstOrDefault();
    if (first == null) return;

    // result.Value is the correct 12-digit UPC-A — no normalization needed
    ProcessBarcode(first.Value, first.Format.ToString());
}

删除与Substring(1)的任何匹配项 — 该代码在迁移后不起作用。

添加文件和 PDF 支持

BarcodeScanning.Native.Maui 没有用于文件或 PDF 输入的等效功能。 如果这是在迁移时需要满足的新要求:

条形码扫描.MAUI 方法:

// 否 equivalent exists — BarcodeScanning.Native.Maui cannot read from files or PDFs
C#

IronBarcode方法:

using IronBarCode;

// Read from a file the user picked with FilePicker
private async void ReadFileButton_Clicked(object sender, EventArgs e)
{
    var file = await FilePicker.PickAsync(new PickOptions
    {
        PickerTitle = "Select image or PDF"
    });
    if (file == null) return;

    var results = BarcodeReader.Read(file.FullPath);
    foreach (var result in results)
        ResultLabel.Text += $"\n{result.Format}: {result.Value}";
}

// Read barcodes from a PDF directly — no intermediate image step
private void ReadPdfBarcodes()
{
    var results = BarcodeReader.Read("shipment-manifest.pdf");
    foreach (var result in results)
        Console.WriteLine($"{result.Format}: {result.Value}");
}

IronBarcode PDF 阅读文档涵盖多页 PDF 支持和页面范围选择。

服务器端条形码处理

如果您的应用程序有需要条形码处理的后端ASP.NET API,同样的BarcodeReader.Read()调用可以在不修改的情况下运行。 BarcodeScanning.Native.Maui 没有服务器端对应的功能。

条形码扫描.MAUI 方法:

// 否 equivalent exists — BarcodeScanning.Native.Maui is a camera UI control
// and cannot run in a server process
C#

IronBarcode方法:

using IronBarCode;

// ASP.NET endpoint — reads barcodes from an uploaded file
[HttpPost("scan")]
public async Task<IActionResult> ScanBarcode(IFormFile file)
{
    using var ms = new MemoryStream();
    await file.CopyToAsync(ms);

    var results = BarcodeReader.Read(ms.ToArray());
    var values = results.Select(r => new { r.Value, Format = r.Format.ToString() });
    return Ok(values);
}

相同的软件包、相同的 API、相同的行为——在移动端和服务器端。

生成条形码

BarcodeScanning.Native.Maui 没有生成 API。 IronBarcode可生成多种格式。

条形码扫描.MAUI 方法:

// 否 equivalent exists — BarcodeScanning.Native.Maui cannot generate barcodes
C#

IronBarcode方法:

using IronBarCode;

// QR code
QRCodeWriter.CreateQrCode("https://example.com/product/12345", 500)
    .SaveAsPng("qr.png");

// Code128 barcode sized to specific dimensions
BarcodeWriter.CreateBarcode("ITEM-98765", BarcodeEncoding.Code128)
    .ResizeTo(400, 100)
    .SaveAsPng("label.png");

// Get bytes for returning from an API or storing in a database
byte[] barcodeBytes = BarcodeWriter.CreateBarcode("ITEM-98765", BarcodeEncoding.Code128)
    .ToPngBinaryData();

IronBarcode生成文档涵盖了所有支持的格式和样式选项。

条形码扫描.MAUI API 到IronBarcode映射参考

BarcodeScanning.Native.MauiIronBarcode
CameraView XAML 控件移除 — 使用 Button + MediaPicker.CapturePhotoAsync()
OnDetectionFinished 事件BarcodeReader.Read(imageBytes) 返回值
OnDetectionFinishedEventArg eBarcodeReader.Read() 的 IEnumerable 结果
e.BarcodeResultsBarcodeReader.Read() 的返回值
e.BarcodeResults.FirstOrDefault()results.FirstOrDefault()
barcode.DisplayValueresult.Value
barcode.BarcodeFormatresult.Format
BarcodeFormats="All"自动检测——无需配置
CameraEnabled="True"await MediaPicker.CapturePhotoAsync()
仅限 iOS 和 AndroidiOS、Android、Windows、macOS、MAUI
无需输入文件BarcodeReader.Read(filePath)
无 PDF 输入BarcodeReader.Read("document.pdf")
没有一代BarcodeWriter.CreateBarcode() / QRCodeWriter.CreateQrCode()
iOS UPC-A 返回 13 位数字返回正确的 12 位数字——无需归一化
PDF417 不可靠支持

常见迁移问题和解决方案

问题一:实时取景器体验丢失

BarcodeScanning.MAUI: CameraView 控件将实时相机预览直接嵌入到MAUI页面中。 用户可以看到摄像头画面并对准条形码——无需按任何按钮即可自动检测。

方案: MediaPicker.CapturePhotoAsync() 显示平台相机屏幕。 对于大多数业务流程而言,这是可以接受的。 对于需要连续实时预览的消费类应用,摄像头帧可以直接传递给BarcodeReader.Read()

using IronBarCode;

// Continuous scanning: pass camera frame bytes to BarcodeReader.Read()
// (frame capture depends on your MAUI camera frame source)
private void ProcessCameraFrame(byte[] frameBytes)
{
    var results = BarcodeReader.Read(frameBytes);
    if (results.Any())
    {
        var first = results.First();
        MainThread.BeginInvokeOnMainThread(() =>
            ResultLabel.Text = first.Value);
    }
}

这需要将相机帧源与IronBarcode分开连接。 在采取此方法之前,请评估是否真的需要实时预览,或者系统摄像头用户界面是否足够。

问题 2:e.BarcodeResults 属性名称和枚举值变更

BarcodeScanning.MAUI: barcode.DisplayValue 返回解码后的字符串; barcode.BarcodeFormat 返回一个 BarcodeScanning 库的枚举值。

方案:barcode.BarcodeFormat。 迭代模式相同:

// Before
foreach (var barcode in e.BarcodeResults)
    Console.WriteLine(barcode.DisplayValue);

// After
var results = BarcodeReader.Read(imageBytes);
foreach (var result in results)
    Console.WriteLine(result.Value);

问题 3:用于 UI 更新的线程封送

BarcodeScanning.MAUI: OnDetectionFinished 在后台线程触发,因此所有UI更新都需要MainThread.BeginInvokeOnMainThread().

方案: 使用MediaPicker + await返回之后的继续会出现在调用上下文中 — 通常是主线程。 围绕结果显示的MainThread.BeginInvokeOnMainThread()包装器通常可以移除,从而简化处理代码。

问题 4:MAUI 相机权限

BarcodeScanning.MAUI: 包会在设置中自动将相机权限添加到Info.plist中。

方案: 使用IronBarcode的MediaPicker,标准的MAUI相机权限必须手动存在。 这些是任何MAUI应用程序用于MediaPicker.CapturePhotoAsync()所需的相同权限,通常已经存在。 在设备上测试之前,确认Info.plist中设置。

条形码扫描.MAUI 迁移清单

迁移前任务

在进行任何更改之前,请运行以下搜索以查找所有 BarcodeScanning.Native.Maui 的使用情况:

grep -rn "using BarcodeScanning" --include="*.cs" .
grep -rn "using BarcodeScanning" --include="*.xaml" .
grep -rn "CameraView" --include="*.cs" .
grep -rn "CameraView" --include="*.xaml" .
grep -rn "OnDetectionFinished" --include="*.cs" .
grep -rn "OnDetectionFinishedEventArg" --include="*.cs" .
grep -rn "e\.BarcodeResults" --include="*.cs" .
grep -rn "DisplayValue" --include="*.cs" .
grep -rn "BarcodeFormats\.Upca" --include="*.cs" .
grep -rn "scanner:" --include="*.xaml" .
SHELL

记录每一次命中。 注意哪些文件包含CameraView XAML使用(需要XAML更改),哪些只包含代码隐藏更改。 确定迁移后必须删除的任何 UPC-A 规范化变通方案。

代码更新任务

  1. 移除BarcodeScanning.Native.Maui NuGet 包
  2. 安装IronBarcode NuGet 包
  3. IronBarCode.License.LicenseKey = "YOUR-LICENSE-KEY";
  4. 在所有using BarcodeScanning;
  5. 从所有XAML文件中移除xmlns:scanner="..."命名空间声明
  6. 在XAML中用触发scanner:CameraView控件
  7. 从XAML中移除OnDetectionFinished="..."事件连接
  8. 使用async按钮点击处理程序
  9. 全面用barcode.DisplayValue
  10. 全面用barcode.BarcodeFormat
  11. 删除所有BarcodeFormats.Upca + Substring(1)规范化变通方案
  12. 在之前依赖BarcodeReaderOptions
  13. 在结果显示代码中移除MainThread.BeginInvokeOnMainThread()包装器,异步模式使其不再需要
  14. 验证Info.plist相机权限是否存在

迁移后测试

  • 验证 iOS 条形码扫描功能是否正常,以及 UPC-A 值是否以不带前导零的 12 位字符串形式返回。
  • 验证 Android 条形码扫描功能能否针对应用程序中使用的所有格式生成正确的值。
  • 验证 Windows MAUI 条形码扫描功能是否正常工作(如果 Windows 是构建目标)。
  • 如果使用真实的货运标签、驾驶执照或登机牌,请使用这些文件测试 PDF417 扫描功能。
  • 测试使用ExpectMultipleBarcodes = true的多条形码场景,并确认图像中的所有条形码都已返回
  • 验证文件选择器扫描(BarcodeReader.Read(filePath))在所有MAUI目标上是否工作
  • 如果 PDF 条形码读取是迁移过程中新增的功能,请验证其是否能够读取。
  • 确认如果添加了后端组件,服务器端BarcodeReader.Read()是否产生正确的结果
  • 运行所有现有的自动化测试,并将条形码值输出与迁移前的基线进行比较。

迁移到IronBarcode的主要优势

完全支持 Windows MAUI: IronBarcode可在所有四个 MAUI 目标平台(iOS、Android、Windows 和 macOS)上运行,使用相同的代码和相同的软件包。 适用于Windows的平台特定条形码实现是不需要的,应用程序代码中也无需#if WINDOWS块。

任何输入源: BarcodeReader.Read() 接受文件路径、字节数组、流和PDF文档。 任何条形码应用场景——相机拍摄、文件上传、图库图像、服务器端 PDF 处理——都使用相同的静态方法,并具有相同的结果类型。

正确的 UPC-A 值: IronBarcode在 iOS 上无需任何标准化代码即可返回正确的 12 位 UPC-A 值。 由于 BarcodeScanning.Native.Maui 的行为,历史 UPC-A 数据以前导零存储,但这不会影响迁移后读取值的准确性。

**可靠的 PDF417:**完全支持 PDF417,读取可靠。 货运标签、驾驶执照和登机牌均可扫描,而不会出现 BarcodeScanning.Native.Maui 的GitHub问题中记录的"大多数扫描从未发生"的限制。

条形码生成: BarcodeWriter.CreateBarcode()QRCodeWriter.CreateQrCode()生成Code128、QR、DataMatrix等格式为PNG文件或字节数组。 生成和读取功能均来自同一个软件包,无需额外依赖项。

服务器端部署: 同样的BarcodeReader.Read()调用在ASP.NET、Azure Functions、Docker容器和AWS Lambda中运行。 移动端和服务器端的条形码逻辑可以共享相同的 API、相同的格式支持和相同的结果类型,而无需维护两个独立的条形码实现。

Curtis Chau
技术作家

Curtis Chau 拥有卡尔顿大学的计算机科学学士学位,专注于前端开发,精通 Node.js、TypeScript、JavaScript 和 React。他热衷于打造直观且美观的用户界面,喜欢使用现代框架并创建结构良好、视觉吸引力强的手册。

...
阅读更多

相关文章

Key in blue circle

立即获取免费的 30 天试用版密钥

Your trial license will be sent to your email address

无任何限制。100% 解锁。无需信用卡。

bullet_checked无需信用卡或创建账户无任何限制。100% 解锁。无需信用卡。
  • Logo Aetna
  • Logo NASA
  • Logo GE
  • Logo Porsche
  • Logo USDA
  • Logo Qatar
Join Millions of Engineers who’ve tried IronPDF
预约您的免费现场演示
Booking Badge

深受全球数百万工程师信赖

Iron Software 的客户徽标
获取您的无义务咨询
填写下面的表格或通过sales@ironsoftware.com
您的资料将始终保密。
深受全球数百万工程师信赖
Iron Software 的客户徽标
立即获取您的免费30 天试用密钥
无需信用卡或创建账户