如何從多頁Gif和Tiff圖像中讀取條碼C#
從Scanbot SDK遷移到IronBarcode
本指南是為將條碼處理由Scanbot SDK轉移到IronBarcode的.NET開發團隊編寫的,適用於伺服器端、桌面或擴展的基於文件的場景。 這不是一個對等替換:Scanbot SDK是移動相機掃描組件,而IronBarcode是一個文件和文件處理程式庫。 遷移是由於相機限定模型無法滿足的需求驅動的範圍變更。 取代活生生的移動相機掃描UI而不新增其他要求的團隊在進行之前應該評估遷移的合適性。
對於以Scanbot開始的MAUI移動應用程式的團隊,現在需要在ASP.NET Core、桌面建置或文件管道中進行條碼處理,機械遷移是直接的。 核心變更是將source可以是檔案路徑、流、位元組陣列或PDF。
為何從Scanbot SDK遷移
伺服器端處理要求: Scanbot SDK不會編譯在ASP.NET Core、控制台應用程式、Azure Functions或任何非MAUI專案中。 當移動應用程式需要一個伺服器端夥伴來處理條碼時 — 從上傳的PDF中擷取它們或驗證傳入文件中的條碼值 — Scanbot無法跨越這一邊界。 IronBarcode在所有這些上下文中運行,並具有相同的BarcodeReader.Read() API。
桌面MAUI支持: Scanbot的封裝目標為net10.0-ios。 一個MAUI專案新增了TargetFrameworks將會失敗以建置桌面目標,因為Scanbot封裝未提供這些平台的組件。IronBarcode支持Windows和macOS MAUI,並與iOS和Android 一起,這意味著相同的包在多目標MAUI專案中工作,無需平台專屬排除或條件引用。
PDF文件工作流程:Scanbot中沒有BarcodeScanner.Read(filePath)。 當一個工作流程擴展到包括從文件上傳、掃描的圖像存檔或PDF發票中讀取條碼時,Scanbot的架構無法滿足這一需求。 IronBarcode可以直接讀取PDF和圖像,每個結果都帶有條碼發現的頁碼。
定價模式可預測性: Scanbot使用年度統一費用。 對於某些組織來說,年度續約是評估替代方案的契機 — 尤其是當專案範圍已經擴展到包括Scanbot無法涵蓋的伺服器端或桌面目標時。 IronBarcode是一種一次性永久購買,消除了年度續約義務。
基本問題
Scanbot SDK需要活相機饋送。 當需求超出移動端時,現有的依賴路徑中沒有等效的路徑:
// Scanbot SDK: camera-only — no file or server equivalent exists
var configuration = new BarcodeScannerScreenConfiguration
{
BarcodeFormats = new[] { BarcodeFormat.Code128, BarcodeFormat.QrCode }
};
// This call requires iOS or Android hardware and a MAUI camera UI
// It cannot be redirected to a file path, stream, or server context
var result = await ScanbotSDKMain.Barcode.StartScannerAsync(configuration);
// Scanbot SDK: camera-only — no file or server equivalent exists
var configuration = new BarcodeScannerScreenConfiguration
{
BarcodeFormats = new[] { BarcodeFormat.Code128, BarcodeFormat.QrCode }
};
// This call requires iOS or Android hardware and a MAUI camera UI
// It cannot be redirected to a file path, stream, or server context
var result = await ScanbotSDKMain.Barcode.StartScannerAsync(configuration);
Imports System.Threading.Tasks
' Scanbot SDK: camera-only — no file or server equivalent exists
Dim configuration As New BarcodeScannerScreenConfiguration With {
.BarcodeFormats = {BarcodeFormat.Code128, BarcodeFormat.QrCode}
}
' This call requires iOS or Android hardware and a MAUI camera UI
' It cannot be redirected to a file path, stream, or server context
Dim result = Await ScanbotSDKMain.Barcode.StartScannerAsync(configuration)
IronBarcode接受相同的來源型別 — 檔案、流、位元組陣列或PDF — 在任何專案上下文中:
// IronBarcode: the same call works in MAUI, ASP.NET Core, console, WPF, Azure Functions
IronBarCode.License.LicenseKey = "YOUR-LICENSE-KEY";
// From a file — works on any platform
var results = BarcodeReader.Read("invoice.pdf");
foreach (var result in results)
Console.WriteLine($"Page {result.PageNumber}: {result.Value} ({result.BarcodeType})");
// IronBarcode: the same call works in MAUI, ASP.NET Core, console, WPF, Azure Functions
IronBarCode.License.LicenseKey = "YOUR-LICENSE-KEY";
// From a file — works on any platform
var results = BarcodeReader.Read("invoice.pdf");
foreach (var result in results)
Console.WriteLine($"Page {result.PageNumber}: {result.Value} ({result.BarcodeType})");
Imports IronBarCode
' IronBarcode: the same call works in MAUI, ASP.NET Core, console, WPF, Azure Functions
License.LicenseKey = "YOUR-LICENSE-KEY"
' From a file — works on any platform
Dim results = BarcodeReader.Read("invoice.pdf")
For Each result In results
Console.WriteLine($"Page {result.PageNumber}: {result.Value} ({result.BarcodeType})")
Next
IronBarcode與Scanbot SDK:功能比較
| 功能 | Scanbot SDK | IronBarcode |
|---|---|---|
| 從文件路徑輸入 | 否 | 是 |
| 從流輸入 | 否 | 是 |
| 從位元組陣列輸入 | 否 | 是 |
| PDF條碼提取 | 否 | 是 |
| 活相機取景器 | 是 | 否(使用MediaPicker) |
| 條碼生成 | 否 | 是 |
| iOS MAUI | 是 | 是 |
| Android MAUI | 是 | 是 |
| Windows MAUI | 否 | 是 |
| macOS MAUI | 否 | 是 |
| ASP.NET Core | 否 | 是 |
| 控制台/伺服器 | 否 | 是 |
| Azure / Lambda / Docker | 否 | 是 |
| .NET Framework 4.6.2+ | 否 | 是 |
| ML錯誤校正 | 否 | 是 |
| 損壞的條碼恢復 | 否 | 是 |
| 自動格式檢測 | 是 | 是 |
| 1D格式 | 20+ | 30+ |
| 2D格式 | QR、DataMatrix、PDF417、Aztec | QR、DataMatrix、PDF417、Aztec、MaxiCode |
| 授權模式 | 年度統一費用 | 一次性永久 |
| 已發布的定價 | 聯繫銷售 | 是($999–$5,999) |
快速開始:Scanbot SDK到IronBarcode遷移
步驟 1:替換 NuGet 包
移除Scanbot封裝:
dotnet remove package ScanbotBarcodeSDK.MAUI
dotnet remove package ScanbotBarcodeSDK.MAUI
如果專案在.csproj文件中使用條件包引用,則也需移除這些條目:
<PackageReference Include="ScanbotBarcodeSDK.MAUI" Version="8.0.0" />
<PackageReference Include="ScanbotBarcodeSDK.MAUI" Version="8.0.0" />
安裝IronBarcode:
dotnet add package IronBarcode
dotnet add package IronBarcode
IronBarcode在NuGet上可用,並支持.NET 6、7、8、9,以及.NET Framework 4.6.2+。 對於MAUI多目標專案,單一dotnet add package在所有目標上工作 — 無需平台條件包引用。
步驟 2:更新命名空間
用IronBarcode命名空間替換Scanbot命名空間:
// Remove
using ScanbotSDK.MAUI;
// Add
using IronBarCode;
// Remove
using ScanbotSDK.MAUI;
// Add
using IronBarCode;
Imports IronBarCode
步驟 3:初始化授權
移除Scanbot初始化區塊,並將其替換為IronBarcode授權金鑰。 根據專案型別,在Program.cs中新增應用程式啟動時的授權初始化:
// Remove this
ScanbotSDKMain.Initialize(new SdkConfiguration
{
LicenseKey = "YOUR-SCANBOT-LICENSE-KEY",
LoggingEnabled = false
});
// Add this — one line, placed once at startup
IronBarCode.License.LicenseKey = "YOUR-LICENSE-KEY";
// Remove this
ScanbotSDKMain.Initialize(new SdkConfiguration
{
LicenseKey = "YOUR-SCANBOT-LICENSE-KEY",
LoggingEnabled = false
});
// Add this — one line, placed once at startup
IronBarCode.License.LicenseKey = "YOUR-LICENSE-KEY";
' Remove this
ScanbotSDKMain.Initialize(New SdkConfiguration With {
.LicenseKey = "YOUR-SCANBOT-LICENSE-KEY",
.LoggingEnabled = False
})
' Add this — one line, placed once at startup
IronBarCode.License.LicenseKey = "YOUR-LICENSE-KEY"
程式碼遷移範例
MAUI照片捕捉
Scanbot的掃描呼叫會打開全屏相機UI,並在使用者掃描條碼或取消時返回。 IronBarcode不提供相機UI; 替換使用MAUI的BarcodeReader.Read()。
Scanbot SDK方法:
using ScanbotSDK.MAUI;
private async void ScanButton_Clicked(object sender, EventArgs e)
{
var configuration = new BarcodeScannerScreenConfiguration
{
BarcodeFormats = new[]
{
BarcodeFormat.Code128,
BarcodeFormat.QrCode,
BarcodeFormat.Ean13
},
FinderAspectRatio = new AspectRatio(1, 1),
TopBarBackgroundColor = Colors.DarkBlue
};
var result = await ScanbotSDKMain.Barcode.StartScannerAsync(configuration);
if (result.Status == OperationResult.Ok)
{
foreach (var barcode in result.Barcodes)
ResultLabel.Text = $"{barcode.Format}: {barcode.Text}";
}
}
using ScanbotSDK.MAUI;
private async void ScanButton_Clicked(object sender, EventArgs e)
{
var configuration = new BarcodeScannerScreenConfiguration
{
BarcodeFormats = new[]
{
BarcodeFormat.Code128,
BarcodeFormat.QrCode,
BarcodeFormat.Ean13
},
FinderAspectRatio = new AspectRatio(1, 1),
TopBarBackgroundColor = Colors.DarkBlue
};
var result = await ScanbotSDKMain.Barcode.StartScannerAsync(configuration);
if (result.Status == OperationResult.Ok)
{
foreach (var barcode in result.Barcodes)
ResultLabel.Text = $"{barcode.Format}: {barcode.Text}";
}
}
Imports ScanbotSDK.MAUI
Private Async Sub ScanButton_Clicked(sender As Object, e As EventArgs)
Dim configuration = New BarcodeScannerScreenConfiguration With {
.BarcodeFormats = New BarcodeFormat() {
BarcodeFormat.Code128,
BarcodeFormat.QrCode,
BarcodeFormat.Ean13
},
.FinderAspectRatio = New AspectRatio(1, 1),
.TopBarBackgroundColor = Colors.DarkBlue
}
Dim result = Await ScanbotSDKMain.Barcode.StartScannerAsync(configuration)
If result.Status = OperationResult.Ok Then
For Each barcode In result.Barcodes
ResultLabel.Text = $"{barcode.Format}: {barcode.Text}"
Next
End If
End Sub
IronBarcode 方法:
// NuGet: dotnet add package 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 != null
? $"{first.BarcodeType}: {first.Value}"
: "No barcode found";
}
// NuGet: dotnet add package 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 != null
? $"{first.BarcodeType}: {first.Value}"
: "No barcode found";
}
Imports IronBarCode
Imports System.IO
Imports System.Linq
Imports System.Threading.Tasks
Private Async Sub ScanButton_Clicked(sender As Object, e As EventArgs)
Dim photo = Await MediaPicker.CapturePhotoAsync()
If photo Is Nothing Then Return
Using stream = Await photo.OpenReadAsync()
Using ms As New MemoryStream()
Await stream.CopyToAsync(ms)
Dim results = BarcodeReader.Read(ms.ToArray())
Dim first = results.FirstOrDefault()
ResultLabel.Text = If(first IsNot Nothing, $"{first.BarcodeType}: {first.Value}", "No barcode found")
End Using
End Using
End Sub
使用者體驗變更在於使用者看到系統相機畫面,而不是Scanbot嵌入的帶有掃描區域覆蓋的取景器。 對於業務應用 - 庫存、物流、文件工作流程 - 系統相機是足夠的。 .NET MAUI條碼掃描教程 包括iOS和Android目標的完整整合模式,包括許可處理。
掃描選項和配置
Scanbot的BarcodeScannerScreenConfiguration控制掃描器接受哪些格式以及相機UI的外觀。 IronBarcode的BarcodeReaderOptions控制圖像的分析方式 — 處理速度、多條碼檢測和類似參數。 配置概念映射到不同的關注點,因為基礎操作是不同的。
Scanbot SDK方法:
var configuration = new BarcodeScannerScreenConfiguration
{
BarcodeFormats = new[] { BarcodeFormat.Code128, BarcodeFormat.QrCode },
FinderAspectRatio = new AspectRatio(1, 1),
FlashEnabled = false,
OrientationLockMode = OrientationLockMode.Portrait
};
var result = await ScanbotSDKMain.Barcode.StartScannerAsync(configuration);
if (result.Status == OperationResult.Ok)
{
foreach (var barcode in result.Barcodes)
Console.WriteLine($"{barcode.Format}: {barcode.Text}");
}
var configuration = new BarcodeScannerScreenConfiguration
{
BarcodeFormats = new[] { BarcodeFormat.Code128, BarcodeFormat.QrCode },
FinderAspectRatio = new AspectRatio(1, 1),
FlashEnabled = false,
OrientationLockMode = OrientationLockMode.Portrait
};
var result = await ScanbotSDKMain.Barcode.StartScannerAsync(configuration);
if (result.Status == OperationResult.Ok)
{
foreach (var barcode in result.Barcodes)
Console.WriteLine($"{barcode.Format}: {barcode.Text}");
}
Imports System
Imports System.Threading.Tasks
Dim configuration As New BarcodeScannerScreenConfiguration With {
.BarcodeFormats = {BarcodeFormat.Code128, BarcodeFormat.QrCode},
.FinderAspectRatio = New AspectRatio(1, 1),
.FlashEnabled = False,
.OrientationLockMode = OrientationLockMode.Portrait
}
Dim result = Await ScanbotSDKMain.Barcode.StartScannerAsync(configuration)
If result.Status = OperationResult.Ok Then
For Each barcode In result.Barcodes
Console.WriteLine($"{barcode.Format}: {barcode.Text}")
Next
End If
IronBarcode 方法:
using IronBarCode;
// Format detection is automatic — BarcodeReaderOptions controls processing behavior
var options = new BarcodeReaderOptions
{
Speed = ReadingSpeed.Balanced,
ExpectMultipleBarcodes = false
};
// Combined with the MediaPicker capture pattern
var photo = await MediaPicker.CapturePhotoAsync();
if (photo == null) return;
using var photoStream = await photo.OpenReadAsync();
using var ms = new MemoryStream();
await photoStream.CopyToAsync(ms);
var results = BarcodeReader.Read(ms.ToArray(), options);
foreach (var result in results)
Console.WriteLine($"{result.BarcodeType}: {result.Value}");
using IronBarCode;
// Format detection is automatic — BarcodeReaderOptions controls processing behavior
var options = new BarcodeReaderOptions
{
Speed = ReadingSpeed.Balanced,
ExpectMultipleBarcodes = false
};
// Combined with the MediaPicker capture pattern
var photo = await MediaPicker.CapturePhotoAsync();
if (photo == null) return;
using var photoStream = await photo.OpenReadAsync();
using var ms = new MemoryStream();
await photoStream.CopyToAsync(ms);
var results = BarcodeReader.Read(ms.ToArray(), options);
foreach (var result in results)
Console.WriteLine($"{result.BarcodeType}: {result.Value}");
Imports IronBarCode
Imports System.IO
' Format detection is automatic — BarcodeReaderOptions controls processing behavior
Dim options As New BarcodeReaderOptions With {
.Speed = ReadingSpeed.Balanced,
.ExpectMultipleBarcodes = False
}
' Combined with the MediaPicker capture pattern
Dim photo = Await MediaPicker.CapturePhotoAsync()
If photo Is Nothing Then Return
Using photoStream = Await photo.OpenReadAsync()
Using ms As New MemoryStream()
Await photoStream.CopyToAsync(ms)
Dim results = BarcodeReader.Read(ms.ToArray(), options)
For Each result In results
Console.WriteLine($"{result.BarcodeType}: {result.Value}")
Next
End Using
End Using
不需要格式規範 — IronBarcode會自動檢測所有支持的格式。 與Scanbot配置最直接對應的ExpectMultipleBarcodes(在匹配到第一個條碼後繼續掃描)。
伺服器端PDF處理
該場景沒有Scanbot等效品。 使用IronBarcode,為MAUI移動應用程式安裝的相同包可以在伺服器端ASP.NET Core端點中從PDF中擷取條碼,給團隊一個單一的條碼依賴項,適用於各種部署上下文。
Scanbot SDK方法:
//Scanbot SDKcannot be used here — the package does not compile
// in ASP.NET Core, Azure Functions, console apps, or any non-MAUI project.
// There is no server-side Scanbot equivalent for this endpoint.
//Scanbot SDKcannot be used here — the package does not compile
// in ASP.NET Core, Azure Functions, console apps, or any non-MAUI project.
// There is no server-side Scanbot equivalent for this endpoint.
'Scanbot SDK cannot be used here — the package does not compile
' in ASP.NET Core, Azure Functions, console apps, or any non-MAUI project.
' There is no server-side Scanbot equivalent for this endpoint.
IronBarcode 方法:
// NuGet: dotnet add package IronBarcode
// Works in ASP.NET Core, console apps, Azure Functions, Docker — the same package as MAUI
using IronBarCode;
[HttpPost("extract-barcodes")]
public async Task<IActionResult> ExtractBarcodes(IFormFile file)
{
using var ms = new MemoryStream();
await file.CopyToAsync(ms);
// Reads all barcodes from all pages of the uploaded PDF
var results = BarcodeReader.Read(ms.ToArray());
var values = results.Select(r => new
{
r.Value,
Format = r.Format.ToString(),
r.PageNumber
});
return Ok(values);
}
// NuGet: dotnet add package IronBarcode
// Works in ASP.NET Core, console apps, Azure Functions, Docker — the same package as MAUI
using IronBarCode;
[HttpPost("extract-barcodes")]
public async Task<IActionResult> ExtractBarcodes(IFormFile file)
{
using var ms = new MemoryStream();
await file.CopyToAsync(ms);
// Reads all barcodes from all pages of the uploaded PDF
var results = BarcodeReader.Read(ms.ToArray());
var values = results.Select(r => new
{
r.Value,
Format = r.Format.ToString(),
r.PageNumber
});
return Ok(values);
}
Imports IronBarCode
Imports Microsoft.AspNetCore.Mvc
Imports System.IO
Imports System.Threading.Tasks
<HttpPost("extract-barcodes")>
Public Async Function ExtractBarcodes(file As IFormFile) As Task(Of IActionResult)
Using ms As New MemoryStream()
Await file.CopyToAsync(ms)
' Reads all barcodes from all pages of the uploaded PDF
Dim results = BarcodeReader.Read(ms.ToArray())
Dim values = results.Select(Function(r) New With {
.Value = r.Value,
.Format = r.Format.ToString(),
.PageNumber = r.PageNumber
})
Return Ok(values)
End Using
End Function
IronBarcode本地處理多頁PDF — 每個結果都攜帶指示條碼所在頁面的PageNumber屬性。 PDF條碼擷取指南 涵蓋了完整的PDF閱讀選項,包括頁面範圍選擇和對大量文件批次的性能調整。
ASP.NET Core背景處理
對於批次工作流程,如Azure Functions或Worker Services處理已存檔的PDF文件,IronBarcode提供與MAUI應用程式和ASP.NET Core控制器中使用的相同API。
Scanbot SDK方法:
//Scanbot SDKdoes not support this deployment context.
// The package will not compile in Azure Functions or Worker Services.
//Scanbot SDKdoes not support this deployment context.
// The package will not compile in Azure Functions or Worker Services.
'Scanbot SDK does not support this deployment context.
' The package will not compile in Azure Functions or Worker Services.
IronBarcode 方法:
// NuGet: dotnet add package IronBarcode
using IronBarCode;
// Azure Function or Worker Service batch processing
public void ProcessInvoiceBatch(IEnumerable<string> filePaths)
{
foreach (var filePath in filePaths)
{
var results = BarcodeReader.Read(filePath);
foreach (var result in results)
Console.WriteLine($"File: {filePath} | Page {result.PageNumber}: {result.Value} ({result.BarcodeType})");
}
}
// NuGet: dotnet add package IronBarcode
using IronBarCode;
// Azure Function or Worker Service batch processing
public void ProcessInvoiceBatch(IEnumerable<string> filePaths)
{
foreach (var filePath in filePaths)
{
var results = BarcodeReader.Read(filePath);
foreach (var result in results)
Console.WriteLine($"File: {filePath} | Page {result.PageNumber}: {result.Value} ({result.BarcodeType})");
}
}
Imports IronBarCode
Public Sub ProcessInvoiceBatch(filePaths As IEnumerable(Of String))
For Each filePath In filePaths
Dim results = BarcodeReader.Read(filePath)
For Each result In results
Console.WriteLine($"File: {filePath} | Page {result.PageNumber}: {result.Value} ({result.BarcodeType})")
Next
Next
End Sub
Scanbot SDKAPI到IronBarcode映射參考
| Scanbot SDK | IronBarcode |
|---|---|
ScanbotSDKMain.Initialize(new SdkConfiguration { LicenseKey = "..." }) |
IronBarCode.License.LicenseKey = "key" |
new BarcodeScannerScreenConfiguration() |
new BarcodeReaderOptions() |
ScanbotSDKMain.Barcode.StartScannerAsync(configuration) |
BarcodeReader.Read(path / stream / bytes) |
result.Status == OperationResult.Ok |
results.FirstOrDefault() != null |
result.Barcodes |
BarcodeReader.Read()的返回值 |
barcode.Format |
result.BarcodeType(IronBarCode.BarcodeEncoding) |
barcode.Text |
result.Value |
BarcodeFormat.Code128 |
BarcodeEncoding.Code128 |
BarcodeFormat.QrCode |
BarcodeEncoding.QRCode |
BarcodeFormat.Ean13 |
BarcodeEncoding.EAN13 |
BarcodeScannerScreenConfiguration.FinderAspectRatio |
無對應 — 影像框架由MediaPicker處理 |
BarcodeScannerScreenConfiguration.FlashEnabled |
無對應 — 使用MediaPicker選項 |
| 相機要求的輸入 | 文件路徑,流,位元組陣列或PDF |
| 僅iOS和Android MAUI | 所有.NET平台和專案型別 |
常見遷移問題及解決方案
問題1:沒有活取景器等效品
Scanbot SDK:提供嵌入在掃描體驗中的即時相機取景器,具有掃描區域覆蓋,觸感反饋和在現場影片饋送中不斷條碼檢測。
解決方案:使用MAUI的MediaPicker.CapturePhotoAsync()來打開系統相機並捕捉靜態圖像以進行處理:
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 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());
Imports System.IO
Dim photo = Await MediaPicker.CapturePhotoAsync()
If photo Is Nothing Then Return
Using stream = Await photo.OpenReadAsync()
Using ms As New MemoryStream()
Await stream.CopyToAsync(ms)
Dim results = BarcodeReader.Read(ms.ToArray())
End Using
End Using
對於業務應用程式,系統相機是足夠的。 對於使用現場覆蓋作為核心使用者體驗的消費者應用,評估此使用者體驗變更是否可接受後再進行遷移。
問題2:相機權限差異
Scanbot SDK: Scanbot封裝處理相機權限要求作為其UI流程的一部分,因此相機權限由SDK初始化和掃描程式啟動隱式管理。
解決方案:使用MediaPicker,MAUI通過標準機制處理許可權。 確認NSCameraUsageDescription金鑰。 這些條目通常存在於生成的MAUI專案模板中。 如果應用僅在先前使用Scanbot存取相機,請在測試前確認這些清單條目已到位:
<uses-permission android:name="android.permission.CAMERA" />
<key>NSCameraUsageDescription</key>
<string>This app uses the camera to scan barcodes.</string>
<uses-permission android:name="android.permission.CAMERA" />
<key>NSCameraUsageDescription</key>
<string>This app uses the camera to scan barcodes.</string>
問題3:Windows編譯錯誤已消除
Scanbot SDK: TargetFrameworks時導致編譯失敗。
解決方案:移除Scanbot封裝引用可以解決Windows編譯失敗問題。 IronBarcode在沒有平台條件設置的情況下可正確解決所有MAUI目標:
# Verify the build succeeds on all targets after removing Scanbot and adding IronBarcode
dotnet build -f net10.0-windows10.0.19041.0
dotnet build -f net10.0-ios
dotnet build -f net10.0-android
# Verify the build succeeds on all targets after removing Scanbot and adding IronBarcode
dotnet build -f net10.0-windows10.0.19041.0
dotnet build -f net10.0-ios
dotnet build -f net10.0-android
問題4:格式枚舉命名空間變更
Scanbot SDK:使用BarcodeFormat.Code128。
解決方案:IronBarcode使用IronBarCode命名空間中。 更新所有格式引用和任何儲存、比較或切換格式枚舉值的程式碼:
// Before (Scanbot)
BarcodeFormat.Code128
BarcodeFormat.QrCode
BarcodeFormat.Ean13
// After (IronBarcode)
BarcodeEncoding.Code128
BarcodeEncoding.QRCode
BarcodeEncoding.EAN13
// Before (Scanbot)
BarcodeFormat.Code128
BarcodeFormat.QrCode
BarcodeFormat.Ean13
// After (IronBarcode)
BarcodeEncoding.Code128
BarcodeEncoding.QRCode
BarcodeEncoding.EAN13
' Before (Scanbot)
BarcodeFormat.Code128
BarcodeFormat.QrCode
BarcodeFormat.Ean13
' After (IronBarcode)
BarcodeEncoding.Code128
BarcodeEncoding.QRCode
BarcodeEncoding.EAN13
請注意,IronBarcode預設會自動檢測所有支持的格式 — 僅在預期格式已知時通過BarcodeReaderOptions進行性能優化需要顯式格式篩選。
Scanbot SDK遷移清單
遷移前任務
審查程式碼庫以識別所有Scanbot SDK的使用:
grep -rn "ScanbotSDK.Initialize" --include="*.cs" .
grep -rn "BarcodeScannerScreenConfiguration" --include="*.cs" .
grep -rn "ScanbotSDKMain.Barcode.StartScannerAsync" --include="*.cs" .
grep -rn "result\.Barcodes" --include="*.cs" .
grep -rn "barcode\.Format" --include="*.cs" .
grep -rn "barcode\.Text" --include="*.cs" .
grep -rn "OperationResult\.Ok" --include="*.cs" .
grep -rn "using ScanbotBarcodeSDK" --include="*.cs" .
grep -rn "BarcodeFormat\." --include="*.cs" .
grep -rn "ScanbotSDK.Initialize" --include="*.cs" .
grep -rn "BarcodeScannerScreenConfiguration" --include="*.cs" .
grep -rn "ScanbotSDKMain.Barcode.StartScannerAsync" --include="*.cs" .
grep -rn "result\.Barcodes" --include="*.cs" .
grep -rn "barcode\.Format" --include="*.cs" .
grep -rn "barcode\.Text" --include="*.cs" .
grep -rn "OperationResult\.Ok" --include="*.cs" .
grep -rn "using ScanbotBarcodeSDK" --include="*.cs" .
grep -rn "BarcodeFormat\." --include="*.cs" .
- 記錄所有掃描呼叫位置,並註明它們是否在共享程式碼、平台特定程式碼或UI事件處理程式中
- 確定有無頁面或流依賴Scanbot的即時取景器作為主要使用者交互
- 確認在
Info.plist中存在相機許可權聲明 - 檢查
.csproj中有無與Scanbot相關的條件包引用
程式碼更新任務
- 移除
ScanbotSDK.MAUINuGet包 - 從
<PackageReference>條目 - 安裝
IronBarcodeNuGet包 - 在所有文件中將
using IronBarCode; - 在應用程式啟動時將
IronBarCode.License.LicenseKey = "key" - 在MAUI相機工作流中將
BarcodeReader.Read(bytes) - 在伺服器端和文件處理上下文中將
BarcodeReader.Read(stream) - 將
results.FirstOrDefault() != null - 將
BarcodeReader.Read()的返回值 - 將
result.Value - 將
BarcodeEncoding.</em>等效物 - 在需要處理選項的位置將
new BarcodeReaderOptions()
遷移後測試
- 驗證編譯在所有MAUI目標平台上成功,包括Windows和macOS(如果存在)
- 在實體iOS裝置和實體Android裝置上測試
MediaPicker.CapturePhotoAsync()流 - 確認IronBarcode解碼的條碼值與Scanbot先前解碼的相同實體條碼的值一致
- 如果專案包括文件處理工作流程,則測試多頁PDF提取
- 確認格式檢測涵蓋在
BarcodeScannerScreenConfiguration.BarcodeFormats中先前配置的所有條碼型別 - 確認伺服器端端點或背景作業在相同文件範本上產生正確結果
- 驗證在首次啟動時iOS和Android上正確顯示相機許可權提示
遷移到IronBarcode的主要優勢
所有部署目標的統一包: IronBarcode安裝一次並在MAUI移動、MAUI桌面、ASP.NET Core、Azure功能、控制台應用程式和Windows桌面應用程式中運行。 團隊不再需要為相同系統的不同部分提供不同的條碼依赖。
PDF和文件處理: IronBarcode本地從PDF文件中讀取條碼,每個結果都帶有發現的頁碼。 在Scanbot模型中先前不可能的文件工作流程在有了BarcodeReader.Read("document.pdf")後變得簡單。
Windows和macOS桌面MAUI支持:移除Scanbot後包含Windows或macOS的多目標MAUI專案編譯無誤。 IronBarcode在所有四個MAUI目標上提供相同的條碼讀取API,消除了Scanbot所需的平台條件依賴管理。
永久授權擁有權: 一次性購買模式消除了年度續約義務。 一旦授權,IronBarcode可以在購買的層級中無限期使用,無需經常性費用。 那些專案範圍超出Scanbot的移動覆蓋範圍的團隊會發現永久模型更符合長期成本規劃。
條碼生成: IronBarcode可以生成所有支持的格式為圖像文件,流或嵌入內容的條碼。 需要讀取和生成功能的專案不再需要Scanbot旁的第二個程式庫。
機器學習輔助閱讀: IronBarcode應用基於機器學習的錯誤校正和損壞條碼恢復,針對困難的現實世界圖像 — 低對比度、局部損壞、印刷質量差 — 標準檢測演算法無法解碼。 此功能對於圖像質量可變的文件處理工作流程特別相關。
常見問題
我為什麼應該從Scanbot SDK遷移到IronBarcode?
常見的理由包括簡化授權(去除SDK +運行時鑰匙的複雜性)、消除吞吐量限制、獲得原生PDF支持、改善Docker/CI/CD部署,並減少生產程式碼中的API樣板。
如何將Scanbot API呼叫替換為IronBarcode?
用IronBarCode.License.LicenseKey = "key"替換實例建立和授權樣板。用BarcodeReader.Read(path)替換讀取呼叫,用BarcodeWriter.CreateBarcode(data, encoding)替換寫入呼叫。靜態方法不需要實例管理。
從Scanbot SDK遷移到IronBarcode時,需要多少程式碼更改?
大多數遷移會導致較少的程式碼行。授權樣板、實例構造函式和顯式格式配置被移除。核心讀/寫操作映射為較短的IronBarcode等價物,且結果物件更清晰。
遷移期間是否需要同時安裝Scanbot SDK和IronBarcode?
不需要。大多數遷移是直接替換而不是並行操作。一次遷移一個服務類,替換NuGet引用,並更新實例化和API呼叫模式後再移動到下一個類。
IronBarcode的NuGet包名稱是什麼?
包名是'IronBarCode'(大寫B和C)。可以用'Install-Package IronBarCode'或'dotnet add package IronBarCode'安裝。程式碼中的using指令是'using IronBarCode;'。
IronBarcode如何簡化Docker部署,相較於Scanbot SDK?
IronBarcode是沒有外部SDK文件或掛載許可配置的NuGet封裝。在Docker中,設置IRONBARCODE_LICENSE_KEY環境變數,包在啟動時處理許可驗證。
從Scanbot遷移後,IronBarcode能自動檢測所有條碼格式嗎?
是的。IronBarcode自動檢測所有支持的格式的符號學。不需要顯式的BarcodeTypes枚舉。如果格式已經知道並且性能很重要,BarcodeReaderOptions允許限制搜索空間作為優化。
IronBarcode是否可以不使用單獨的庫讀取PDF中的條碼?
可以。BarcodeReader.Read("document.pdf")原生處理PDF文件。結果包括每個條碼發現的頁碼、格式、值和置信度。不需要外部PDF渲染步驟。
IronBarcode如何處理並行條碼處理?
IronBarcode的靜態方法是無狀態且執行緒安全的。直接使用Parallel.ForEach遍歷文件列表,不需要每個執行緒的實例管理。BarcodeReaderOptions.MaxParallelThreads控制內部執行緒預算。
從Scanbot SDK遷移到IronBarcode時,哪些結果屬性會改變?
常見的重命名:BarcodeValue變為Value,BarcodeType變為Format。IronBarcode結果還新增了Confidence和PageNumber。整個解決方案的搜索和替換可處理現有結果處理程式碼中的重新命名。
我如何在CI/CD管道中設置IronBarcode授權?
將IRONBARCODE_LICENSE_KEY作為管道機密儲存,在應用程式啟動程式碼中分配IronBarCode.License.LicenseKey。一個機密涵蓋所有環境,包括開發、測試、分期和生產。
IronBarcode是否支持生成帶有自定義樣式的QR碼?
支持。QRCodeWriter.CreateQrCode()支持通過ChangeBarCodeColor()自定義顏色,通過AddBrandLogo()嵌入logo,可配置錯誤校正級別,以及包括PNG、JPG、PDF和流在內的多種輸出格式。

