从Google ML Kit条形码扫描迁移到IronBarcode
本指南适用于以下两种情况之一的团队:您正在将 Android 应用程序移植到.NET MAUI或.NET 9,并且需要用托管替代方案替换 ML Kit 的条形码扫描器;或者您在跨平台条形码讨论中被推荐使用 Google ML Kit,但在添加NuGet包时发现它并不存在。
Google ML Kit 条形码扫描是一个原生 Android 和 iOS 库。 它作为Maven依赖项发布(GoogleMLKit/BarcodeScanning)用于Swift。 ML Kit自2020年6月起成为独立产品,不再需要Firebase,但没有官方的.NET SDK,也没有dotnet add package google-mlkit-barcode,以及来自Google的第一方C# API。 社区维护的Xamarin/MAUI绑定多年来曾经出现过,但每次ML Kit更新其基础SDK时都会破裂。
IronBarcode是一个原生.NET库,可通过NuGet安装,与标准.NET模式集成,并可在 Windows、Linux、macOS、Docker、Azure 和 AWS 上运行。 本指南展示了如何将您用 Kotlin 或 Java 编写的模式转换为等效的 C# 代码。
移植背景
从 ML Kit 移植到IronBarcode时,一些结构上的变化不仅仅是语法上的变化:
回调变为返回值。 ML Kit使用Android的Task API与addOnFailureListener。 IronBarcode的BarcodeReader.Read()同步返回一个集合。 你直接迭代它。 没有回调注册,没有线程协调。
无扫描器对象。 ML Kit要求您构建一个scanner.process(inputImage)。 IronBarcode使用静态方法—BarcodeReader.Read()是入口点。 没有需要管理或处置的实例。
无InputImage构造。 ML Kit的InputImage.fromMediaImage(image, rotation)。 IronBarcode接受文件路径字符串、一个System.Drawing.Bitmap。 没有 Android 上下文,没有 URI,没有旋转元数据。
**没有Google Play服务。**未捆绑的ML Kit模型通过Google Play服务运行。 捆绑变体将模型打包在APK内(增加约2.4 MB),避免了Play服务检查,但无论变体如何,.NET目标上均不可用。 IronBarcode没有这种依赖性——它在任何.NET支持的平台上都能完全运行。
.NET快速安装
如果您的项目中存在 Xamarin/MAUI ML Kit 绑定包,请将其移除,然后安装IronBarcode:
在应用程序启动时添加许可证密钥—在Startup.cs中,具体取决于您的应用类型:
// NuGet: dotnet add package BarCode
using IronBarCode;
IronBarCode.License.LicenseKey = "YOUR-LICENSE-KEY";Imports IronBarCode
IronBarCode.License.LicenseKey = "YOUR-LICENSE-KEY"许可证可以在第一个BarcodeWriter.CreateBarcode()调用之前的任何时候设置。 提供免费试用; 试用模式下会生成带有水印的条形码,但不限制读取。
条形码读取:Kotlin 到 C#
基本单条码读取
以下是 Kotlin 中典型的 ML Kit 读取示例,它扫描文件 URI 中的单个二维码:
// Android Kotlin — ML Kit
val options = BarcodeScannerOptions.Builder()
.setBarcodeFormats(Barcode.FORMAT_QR_CODE)
.build()
val scanner = BarcodeScanning.getClient(options)
val inputImage = InputImage.fromFilePath(context, imageUri)
scanner.process(inputImage)
.addOnSuccessListener { barcodes ->
val barcode = barcodes.firstOrNull()
if (barcode != null) {
Log.d("MLKit", "Value: ${barcode.rawValue}")
Log.d("MLKit", "Format: ${barcode.format}")
}
}
.addOnFailureListener { e ->
Log.e("MLKit", "Scan failed: ${e.message}")
}
在C#中使用IronBarcode实现的等效功能:
using IronBarCode;
try
{
var results = BarcodeReader.Read("captured-image.jpg");
var barcode = results.FirstOrDefault();
if (barcode != null)
{
Console.WriteLine($"Value: {barcode.Value}");
Console.WriteLine($"Format: {barcode.Format}");
}
}
catch (Exception ex)
{
Console.WriteLine($"Scan failed: {ex.Message}");
}Imports IronBarCode
Try
Dim results = BarcodeReader.Read("captured-image.jpg")
Dim barcode = results.FirstOrDefault()
If barcode IsNot Nothing Then
Console.WriteLine($"Value: {barcode.Value}")
Console.WriteLine($"Format: {barcode.Format}")
End If
Catch ex As Exception
Console.WriteLine($"Scan failed: {ex.Message}")
End Try结果会立即以返回值的形式提供。 barcode.rawValue。 barcode.format。 错误处理采用标准的 try/catch 语句,而不是单独的失败监听器。
多条形码读取
ML Kit扫描一个InputImage并返回一个列表。对于一张图像中的多个条码,您需要迭代成功监听器的列表:
// Android Kotlin — ML Kit, multiple barcodes
val options = BarcodeScannerOptions.Builder()
.setBarcodeFormats(Barcode.FORMAT_ALL_FORMATS)
.build()
val scanner = BarcodeScanning.getClient(options)
val inputImage = InputImage.fromFilePath(context, imageUri)
scanner.process(inputImage)
.addOnSuccessListener { barcodes ->
for (barcode in barcodes) {
val rawValue = barcode.rawValue
val format = barcode.format
processBarcode(rawValue, format)
}
}
.addOnFailureListener { e -> Log.e("MLKit", e.message ?: "Unknown error") }
使用IronBarcode,在ExpectMultipleBarcodes = true并迭代结果集合:
using IronBarCode;
var options = new BarcodeReaderOptions
{
Speed = ReadingSpeed.Balanced,
ExpectMultipleBarcodes = true
};
var results = BarcodeReader.Read("warehouse-shelf.jpg", options);
foreach (var barcode in results)
{
Console.WriteLine($"Format: {barcode.Format}, Value: {barcode.Value}");
ProcessBarcode(barcode.Value, barcode.Format);
}Imports IronBarCode
Dim options As New BarcodeReaderOptions With {
.Speed = ReadingSpeed.Balanced,
.ExpectMultipleBarcodes = True
}
Dim results = BarcodeReader.Read("warehouse-shelf.jpg", options)
For Each barcode In results
Console.WriteLine($"Format: {barcode.Format}, Value: {barcode.Value}")
ProcessBarcode(barcode.Value, barcode.Format)
Next格式规范:将条形码格式设置为 BarcodeReaderOptions
ML Kit要求您通过setBarcodeFormats()指定要查找的格式。 如果省略,ML Kit 将搜索所有格式。IronBarcode的工作原理相同——省略格式约束会搜索所有内容,但指定预期类型可以提高性能。
| ML Kit Kotlin | IronBarcode C# |
|---|---|
Barcode.FORMAT_QR_CODE | BarcodeEncoding.QRCode |
Barcode.FORMAT_CODE_128 | BarcodeEncoding.Code128 |
Barcode.FORMAT_CODE_39 | BarcodeEncoding.Code39 |
Barcode.FORMAT_CODE_93 | BarcodeEncoding.Code93 |
Barcode.FORMAT_EAN_13 | BarcodeEncoding.EAN13 |
Barcode.FORMAT_EAN_8 | BarcodeEncoding.EAN8 |
Barcode.FORMAT_UPC_A | BarcodeEncoding.UPCA |
Barcode.FORMAT_UPC_E | BarcodeEncoding.UPCE |
Barcode.FORMAT_PDF417 | BarcodeEncoding.PDF417 |
Barcode.FORMAT_DATA_MATRIX | BarcodeEncoding.DataMatrix |
Barcode.FORMAT_AZTEC | BarcodeEncoding.Aztec |
Barcode.FORMAT_ITF | BarcodeEncoding.ITF |
Barcode.FORMAT_CODABAR | BarcodeEncoding.Codabar |
Barcode.FORMAT_ALL_FORMATS | 省略ExpectBarcodeTypes |
在IronBarcode中使用格式标志:
using IronBarCode;
var options = new BarcodeReaderOptions
{
Speed = ReadingSpeed.Balanced,
ExpectMultipleBarcodes = true,
ExpectBarcodeTypes = BarcodeEncoding.QRCode | BarcodeEncoding.Code128 | BarcodeEncoding.EAN13
};
var results = BarcodeReader.Read("product-image.jpg", options);Imports IronBarCode
Dim options As New BarcodeReaderOptions With {
.Speed = ReadingSpeed.Balanced,
.ExpectMultipleBarcodes = True,
.ExpectBarcodeTypes = BarcodeEncoding.QRCode Or BarcodeEncoding.Code128 Or BarcodeEncoding.EAN13
}
Dim results = BarcodeReader.Read("product-image.jpg", options)按位或运算组合的工作方式与 ML Kit 的可变参数格式列表相同。
结果访问:原始值和格式
ML Kit的结果对象公开Int常量)。 IronBarcode的结果公开BarcodeEncoding枚举值)。
//ML Kit Kotlin— result fields
val rawValue: String? = barcode.rawValue
val format: Int = barcode.format
val boundingBox: Rect? = barcode.boundingBox
val displayValue: String? = barcode.displayValue
//IronBarcode C#— result fields
string value = barcode.Value;
BarcodeEncoding format = barcode.Format;
int page = barcode.PageNumber; // populated for PDF / multi-page input
barcode.Value在IronBarcode中始终是一个不为null的字符串—如果读取成功,值是存在的。 if (barcode.Format == BarcodeEncoding.QRCode)。
.NET有什么不同之处
**使用同步 API 而非回调函数。**这是最重要的结构性变化。 ML Kit的Task<List<Barcode>>—您连接监听器。 IronBarcode的Task.Run()中:
using IronBarCode;
// In a MAUI ViewModel or page code-behind
var results = await Task.Run(() => BarcodeReader.Read(imagePath));
foreach (var barcode in results)
{
// update UI on main thread
MainThread.BeginInvokeOnMainThread(() =>
{
ResultLabel.Text = barcode.Value;
});
}Imports IronBarCode
Imports System.Threading.Tasks
Imports Microsoft.Maui.Dispatching
' In a MAUI ViewModel or page code-behind
Dim results = Await Task.Run(Function() BarcodeReader.Read(imagePath))
For Each barcode In results
' update UI on main thread
MainThread.BeginInvokeOnMainThread(Sub()
ResultLabel.Text = barcode.Value
End Sub)
Next没有上下文参数。 每一个构建InputImage的ML Kit调用都需要一个Android Context。 IronBarcode只需要文件路径或流即可。 从条形码逻辑中移除上下文线程可以大大简化代码。
没有Google Play服务。 标准ML Kit模型通过Play服务运行—BarcodeScanning.getClient()在运行时检查Play服务的可用性,如果不可用则会抛出异常。 IronBarcode没有运行时服务检查。 它要么读取图像,要么抛出一个标准异常。
标准异常处理。 ML Kit的addOnFailureListener接收一个Java Exception子类。 在.NET中,失败作为标准System.Exception抛出,按常规方式可通过try/catch捕获。
读取PDF文档
ML Kit 不支持 PDF。 具有.pdf URI的InputImage.fromFilePath()要么失败,要么根据Android版本仅以光栅化图像读取第一页。 如果您的移植场景涉及文档(例如发票处理、物流清单、表单扫描), IronBarcode可以原生处理 PDF 文件:
using IronBarCode;
// Read all barcodes from all pages of a PDF
var options = new BarcodeReaderOptions
{
Speed = ReadingSpeed.Balanced,
ExpectMultipleBarcodes = true
};
var results = BarcodeReader.Read("invoice-batch.pdf", options);
foreach (var barcode in results)
{
Console.WriteLine($"Page {barcode.PageNumber}: {barcode.Format} — {barcode.Value}");
}Imports IronBarCode
' Read all barcodes from all pages of a PDF
Dim options As New BarcodeReaderOptions With {
.Speed = ReadingSpeed.Balanced,
.ExpectMultipleBarcodes = True
}
Dim results = BarcodeReader.Read("invoice-batch.pdf", options)
For Each barcode In results
Console.WriteLine($"Page {barcode.PageNumber}: {barcode.Format} — {barcode.Value}")
Next无需图像提取步骤,无需第三方 PDF 库,无需页面迭代循环和单独渲染。 传入 PDF 路径,获取所有条形码值及其页码。
新功能:一代
ML Kit 不生成条形码,它只读取条形码。 如果您的移植应用程序需要生成标签、票据或二维码,IronBarcode的同一个软件包就能满足这些需求。
货运标签代码 128:
using IronBarCode;
BarcodeWriter.CreateBarcode("SHIP-2024-98341", BarcodeEncoding.Code128)
.ResizeTo(400, 120)
.SaveAsPng("shipping-label.png");Imports IronBarCode
BarcodeWriter.CreateBarcode("SHIP-2024-98341", BarcodeEncoding.Code128) _
.ResizeTo(400, 120) _
.SaveAsPng("shipping-label.png")二维码生成:
using IronBarCode;
QRCodeWriter.CreateQrCode("https://example.com/track/98341", 500)
.SaveAsPng("tracking-qr.png");Imports IronBarCode
QRCodeWriter.CreateQrCode("https://example.com/track/98341", 500) _
.SaveAsPng("tracking-qr.png")带有徽标和颜色的二维码:
using IronBarCode;
QRCodeWriter.CreateQrCode("https://example.com/product/4821", 500)
.AddBrandLogo("company-logo.png")
.ChangeBarCodeColor(System.Drawing.Color.DarkBlue)
.SaveAsPng("product-qr.png");Imports IronBarCode
QRCodeWriter.CreateQrCode("https://example.com/product/4821", 500) _
.AddBrandLogo("company-logo.png") _
.ChangeBarCodeColor(System.Drawing.Color.DarkBlue) _
.SaveAsPng("product-qr.png")作为 HTTP 响应的字节数组返回条形码:
using IronBarCode;
// In anASP.NET Corecontroller action
byte[] barcodeBytes = BarcodeWriter.CreateBarcode("ORDER-7734", BarcodeEncoding.QRCode)
.ToPngBinaryData();
return File(barcodeBytes, "image/png");
这些模式在 ML Kit 中都没有对应的模式。 由于您使用的是完整的.NET条形码库,而不是仅限移动设备的扫描器,因此可以使用这些新功能。
服务器端批处理
ML Kit 每次调用处理一张图像,需要 Android/iOS 运行时环境,并且没有服务器端执行的概念。 IronBarcode以循环方式处理文件,在ASP.NET Core中运行,并且可以正常扩展:
using IronBarCode;
// Process a folder of scanned document images
var imageFiles = Directory.GetFiles("/data/scans", "*.jpg");
var allResults = new List<(string File, string Value, BarcodeEncoding Format)>();
foreach (var file in imageFiles)
{
var options = new BarcodeReaderOptions
{
Speed = ReadingSpeed.Faster,
ExpectMultipleBarcodes = false
};
var results = BarcodeReader.Read(file, options);
foreach (var barcode in results)
{
allResults.Add((file, barcode.Value, barcode.Format));
}
}
// Write results to CSV, database, etc.
foreach (var (file, value, format) in allResults)
{
Console.WriteLine($"{file}: [{format}] {value}");
}Imports IronBarCode
Imports System.IO
' Process a folder of scanned document images
Dim imageFiles = Directory.GetFiles("/data/scans", "*.jpg")
Dim allResults = New List(Of (File As String, Value As String, Format As BarcodeEncoding))()
For Each file In imageFiles
Dim options = New BarcodeReaderOptions With {
.Speed = ReadingSpeed.Faster,
.ExpectMultipleBarcodes = False
}
Dim results = BarcodeReader.Read(file, options)
For Each barcode In results
allResults.Add((file, barcode.Value, barcode.Format))
Next
Next
' Write results to CSV, database, etc.
For Each result In allResults
Console.WriteLine($"{result.File}: [{result.Format}] {result.Value}")
Next这种模式——读取图像文件夹、提取条形码、汇总结果——在 ML Kit 中是不可能的。 这是IronBarcode的标准工作流程。
功能对比
| 特征 | Google ML Kit | IronBarcode |
|---|---|---|
| .NET NuGet包 | None | BarCode |
| C# / .NET API | None | 是 |
| 条形码读取 | 是的(Android/iOS) | 是的(所有平台) |
| 条形码生成 | 否 | 是 |
| 二维码生成 | 否 | 是 |
| 二维码标志嵌入 | 否 | 是 |
| PDF 输入 | 否 | 是 |
| 支持多页文档 | 否 | 是 |
| 摄像头/帧输入 | 是 | 通过图像文件 |
| 服务器端部署 | 否 | 是 |
| ASP.NET Core | 否 | 是 |
| Azure Functions | 否 | 是 |
| Docker / Linux | 否 | 是 |
| 需要 Google Play 服务 | 只支持未捆绑变体 | 否 |
| Firebase依赖 | 不(自2020年6月以来独立) | 否 |
| 同步.NET API | 否 | 是 |
| 支持依赖注入 | 否 | 是的(静态 API) |
ExpectMultipleBarcodes选项 | 通过结果列表 | BarcodeReaderOptions |
| 格式规范 | setBarcodeFormats() | ExpectBarcodeTypes |
| 速度/精度权衡 | 固定(基于模型) | ReadingSpeed枚举 |
| 定价 | 免费(仅限设备上的移动) | 从$999(Lite)永久 |
| 平台 | Android、iOS | Windows、Linux、macOS、Docker、Azure、AWS |
迁移清单
如果您正在移植 Android 代码库或替换非官方的 Xamarin ML Kit 绑定,请在您的项目中搜索这些模式并应用上述转换:
- Gradle文件中的
com.google.mlkit:barcode-scanning→ 移除,添加BarCodeNuGet BarcodeScannerOptions.Builder()→new BarcodeReaderOptions { }BarcodeScanning.getClient(options)→ 移除(IronBarcode中无扫描器实例)InputImage.fromFilePath(context, uri)→ 文件路径字符串参数InputImage.fromBitmap(bitmap, rotation)→BarcodeReader.Read(stream)或字节数组重载scanner.process(inputImage)→BarcodeReader.Read(path, options).addOnSuccessListener { barcodes -> }→ 迭代Read()的返回值.addOnFailureListener { e -> }→ 在Read()周围使用try/catchbarcode.rawValue→barcode.Valuebarcode.format→barcode.FormatBarcode.FORMAT_QR_CODE→BarcodeEncoding.QRCodeBarcode.FORMAT_CODE_128→BarcodeEncoding.Code128Barcode.FORMAT_ALL_FORMATS→ 省略ExpectBarcodeTypesusing Google.MLKit.BarcodeScanning;(Xamarin绑定)→using IronBarCode;- 应在
IronBarCode.License.LicenseKey
从基于回调的代码到同步代码的结构性改变是主要工作。 格式常量和结果字段名称是直接映射。 PDF 和生成支持完全是新增的——不需要迁移,只需要新的代码。

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