IronBarcode 和 ZXing Net 库的比较
从Scandit SDK迁移到IronBarcode
Scandit SDK 是一个专为实时移动条形码检测而构建的相机扫描平台。 IronBarcode是一个用于.NET的服务器端和基于文件的条形码处理库。 这两个库的主要用途不同,从一个库迁移到另一个库只有在特定情况下才有意义。
本指南涵盖了使用 Scandit 的.NET程序包处理文件、PDF 或服务器端文档流的团队的迁移路径——在这些场景中,Scandit 的相机管道架构带来的不是价值而是摩擦。 如果您的核心需求是将移动摄像头对准物理对象,并通过增强现实叠加层接收实时反馈,那么 Scandit 仍然是合适的工具,本指南不适用。 如果您需要从上传的图像中读取条形码、从 PDF 文档中提取条形码数据,或者在ASP.NET Core、Azure Functions、Docker 容器或后台处理服务中运行条形码检测,本指南将提供完整的迁移路径。
为什么要从Scandit SDK迁移
相机管道开销: 每个Scandit集成都以相同的初始化顺序开始,无论部署环境中是否存在相机:构造Camera实例,将其指定为帧源,将相机转换为活动状态,并启用条形码捕获。 之所以需要进行此初始化,是因为 Scandit 会处理实时视频帧。 对于服务器端文件处理而言,该序列没有任何好处,反而引入了目标环境中不存在的状态复杂性——Docker 容器中没有摄像头,Azure 函数中也没有帧源。
不公开定价: Scandit 不公布定价。 SparkScan、MatrixScan、ID 扫描、AR 叠加层和解析器均为单独定价的产品,每款产品都需要单独询价。 在进入销售周期之前,无法完成预算提案、供应商比较或成本效益分析。 IronBarcode公开列出了其定价——749 美元、1499 美元或 2999 美元(一次性永久购买)——因此在编写任何代码之前,价格就已经在页面上了。
强制性条码格式声明: Scandit 要求在扫描会话开始之前明确启用每种条码格式。 在实时相机扫描中,这是一种性能优化——限制符号体系可以减少每帧的处理开销。 在基于文件的文档处理中,传入的文档可能带有来自任何供应商或合作伙伴的任何条形码格式,因此强制格式声明成为一种限制。 列举所有可能的符号体系会消除性能优势; 在库之上编写格式猜测逻辑会增加工程开销。
无PDF支持: 在Scandit的API中没有与BarcodeReader.Read("invoice.pdf")直接对应的功能。 从 PDF 文档中提取条形码需要使用单独的库将每一页渲染成光栅图像,然后将这些渲染后的图像输入到相机模拟流程中。这种方法引入了额外的依赖项、额外的许可费用以及大量的工程工作,而这项任务在文档处理工作流程中原本是常规操作。
基本问题
Scandit要求在开始任何条形码扫描工作之前,摄像头必须处于运行状态。 IronBarcode只需要文件路径:
// Scandit SDK: mandatory camera pipeline before first barcode read
var dataCaptureContext = DataCaptureContext.ForLicenseKey("YOUR-SCANDIT-LICENSE");
var settings = BarcodeCaptureSettings.Create();
settings.EnableSymbologies(new HashSet<Symbology>
{
Symbology.Ean13Upca,
Symbology.Ean8,
Symbology.Code128,
Symbology.QrCode
});
var barcodeCapture = BarcodeCapture.Create(dataCaptureContext, settings);
var camera = Camera.GetDefaultCamera();
await dataCaptureContext.SetFrameSourceAsync(camera);
await camera.SwitchToDesiredStateAsync(FrameSourceState.On);
barcodeCapture.IsEnabled = true;
// Results arrive later via BarcodeScanned event callback
// Scandit SDK: mandatory camera pipeline before first barcode read
var dataCaptureContext = DataCaptureContext.ForLicenseKey("YOUR-SCANDIT-LICENSE");
var settings = BarcodeCaptureSettings.Create();
settings.EnableSymbologies(new HashSet<Symbology>
{
Symbology.Ean13Upca,
Symbology.Ean8,
Symbology.Code128,
Symbology.QrCode
});
var barcodeCapture = BarcodeCapture.Create(dataCaptureContext, settings);
var camera = Camera.GetDefaultCamera();
await dataCaptureContext.SetFrameSourceAsync(camera);
await camera.SwitchToDesiredStateAsync(FrameSourceState.On);
barcodeCapture.IsEnabled = true;
// Results arrive later via BarcodeScanned event callback
Imports Scandit.DataCapture.Core
Imports Scandit.DataCapture.Barcode
Imports System.Collections.Generic
' Scandit SDK: mandatory camera pipeline before first barcode read
Dim dataCaptureContext = DataCaptureContext.ForLicenseKey("YOUR-SCANDIT-LICENSE")
Dim settings = BarcodeCaptureSettings.Create()
settings.EnableSymbologies(New HashSet(Of Symbology) From {
Symbology.Ean13Upca,
Symbology.Ean8,
Symbology.Code128,
Symbology.QrCode
})
Dim barcodeCapture = BarcodeCapture.Create(dataCaptureContext, settings)
Dim camera = Camera.GetDefaultCamera()
Await dataCaptureContext.SetFrameSourceAsync(camera)
Await camera.SwitchToDesiredStateAsync(FrameSourceState.On)
barcodeCapture.IsEnabled = True
' Results arrive later via BarcodeScanned event callback
// IronBarcode: direct file reading
// NuGet: dotnet add package IronBarcode
IronBarCode.License.LicenseKey = "YOUR-LICENSE-KEY";
var results = BarcodeReader.Read("barcode.png");
foreach (var result in results)
Console.WriteLine($"{result.Value} ({result.Format})");
// IronBarcode: direct file reading
// NuGet: dotnet add package IronBarcode
IronBarCode.License.LicenseKey = "YOUR-LICENSE-KEY";
var results = BarcodeReader.Read("barcode.png");
foreach (var result in results)
Console.WriteLine($"{result.Value} ({result.Format})");
Imports IronBarCode
' IronBarcode: direct file reading
' NuGet: dotnet add package IronBarcode
IronBarCode.License.LicenseKey = "YOUR-LICENSE-KEY"
Dim results = BarcodeReader.Read("barcode.png")
For Each result In results
Console.WriteLine($"{result.Value} ({result.Format})")
Next
整个相机流程模块——上下文创建、设置、符号启用、相机采集、帧源分配、状态转换——都被许可证密钥分配和单个方法调用所取代。
IronBarcode与 Scandit SDK:功能对比
| 特征 | Scandit SDK | IronBarcode |
|---|---|---|
| 主要部署 | 手机摄像头扫描 | 服务器、云、桌面文件处理 |
| 需要摄像头 | 是 | 否 |
| 图像文件读取 | 并非设计用于 | 主要输入类型 |
| PDF条形码提取 | 不支持 | 原生多页面支持 |
| 流/字节数组输入 | 不支持 | 是 |
| 自动格式检测 | 否(必须注明) | 是的(默认行为) |
| 事件驱动型结果 | 是的(条形码扫描回调) | 否(同步返回) |
| ASP.NET Core / 服务器端 | 并非设计用于 | 完全支持 |
| Azure Functions / 无服务器 | 不切实际 | 完全支持 |
| Docker / Linux | 不支持 | 完全支持 |
| 条形码生成 | 不支持 | 包装内含 |
| 多条形码检测 | MatrixScan(独立产品) | 包装内含 |
| 定价模式 | 联系销售人员(按产品) | 已发布的永久层级 |
| 按扫描/按设备收费 | 是 | 否 |
快速入门
步骤 1:替换 NuGet 软件包
移除 Scandit 软件包:
dotnet remove package Scandit.BarcodePicker
dotnet remove package Scandit.DataCapture.Core
dotnet remove package Scandit.DataCapture.Barcode
dotnet remove package Scandit.BarcodePicker
dotnet remove package Scandit.DataCapture.Core
dotnet remove package Scandit.DataCapture.Barcode
安装IronBarcode:
dotnet add package IronBarcode
dotnet add package IronBarcode
步骤 2:更新命名空间
用IronBarcode命名空间替换Scandit命名空间导入:
// Before (Scandit SDK)
using Scandit.DataCapture.Core;
using Scandit.DataCapture.Barcode;
using Scandit.DataCapture.Barcode.Data;
// After (IronBarcode)
using IronBarCode;
// Before (Scandit SDK)
using Scandit.DataCapture.Core;
using Scandit.DataCapture.Barcode;
using Scandit.DataCapture.Barcode.Data;
// After (IronBarcode)
using IronBarCode;
' Before (Scandit SDK)
Imports Scandit.DataCapture.Core
Imports Scandit.DataCapture.Barcode
Imports Scandit.DataCapture.Barcode.Data
' After (IronBarcode)
Imports IronBarCode
步骤 3:初始化许可证
在应用程序启动时添加许可证初始化,替换DataCaptureContext.ForLicenseKey调用:
// Before (Scandit SDK)
var dataCaptureContext = DataCaptureContext.ForLicenseKey("YOUR-SCANDIT-LICENSE");
// After (IronBarcode)
IronBarCode.License.LicenseKey = "YOUR-LICENSE-KEY";
// Before (Scandit SDK)
var dataCaptureContext = DataCaptureContext.ForLicenseKey("YOUR-SCANDIT-LICENSE");
// After (IronBarcode)
IronBarCode.License.LicenseKey = "YOUR-LICENSE-KEY";
' Before (Scandit SDK)
Dim dataCaptureContext = DataCaptureContext.ForLicenseKey("YOUR-SCANDIT-LICENSE")
' After (IronBarcode)
IronBarCode.License.LicenseKey = "YOUR-LICENSE-KEY"
代码迁移示例
从图像文件中读取条形码
处理静态图像文件是IronBarcode的核心支持场景,也是 Scandit 不支持的工作流程。Scandit SDK处理实时摄像头帧; 读取文件需要调整捕获管道,将位图视为帧源,而这没有原生实现。
Scandit SDK 方法:
//Scandit SDKhas no direct file-read API.
// Reading a static image requires constructing a bitmap frame source
// and routing it through the capture pipeline — an unsupported workaround.
// The standard Scandit integration assumes a running camera at all times.
//Scandit SDKhas no direct file-read API.
// Reading a static image requires constructing a bitmap frame source
// and routing it through the capture pipeline — an unsupported workaround.
// The standard Scandit integration assumes a running camera at all times.
' Scandit SDK has no direct file-read API.
' Reading a static image requires constructing a bitmap frame source
' and routing it through the capture pipeline — an unsupported workaround.
' The standard Scandit integration assumes a running camera at all times.
IronBarcode方法:
// NuGet: dotnet add package IronBarcode
using IronBarCode;
IronBarCode.License.LicenseKey = "YOUR-LICENSE-KEY";
var results = BarcodeReader.Read("product-label.png");
foreach (var result in results)
{
Console.WriteLine($"Value: {result.Value}");
Console.WriteLine($"Format: {result.Format}");
Console.WriteLine($"Confidence: {result.Confidence}%");
}
// NuGet: dotnet add package IronBarcode
using IronBarCode;
IronBarCode.License.LicenseKey = "YOUR-LICENSE-KEY";
var results = BarcodeReader.Read("product-label.png");
foreach (var result in results)
{
Console.WriteLine($"Value: {result.Value}");
Console.WriteLine($"Format: {result.Format}");
Console.WriteLine($"Confidence: {result.Confidence}%");
}
Imports IronBarCode
IronBarCode.License.LicenseKey = "YOUR-LICENSE-KEY"
Dim results = BarcodeReader.Read("product-label.png")
For Each result In results
Console.WriteLine($"Value: {result.Value}")
Console.WriteLine($"Format: {result.Format}")
Console.WriteLine($"Confidence: {result.Confidence}%")
Next
使用IronBarcode从图像中读取条形码无需任何管道设置。方法返回后即可立即获取结果集合,无需订阅事件。
从 PDF 文档中提取条形码
从不支持 PDF 的 Scandit 迁移过来时,PDF 条形码提取是一个全新的领域。 IronBarcode直接读取 PDF 文档,并按页码索引返回结果。
Scandit SDK 方法:
// Scandit SDK: no PDF support.
// Implementing PDF barcode extraction with Scandit requires:
// 1. A separate PDF rendering library to convert pages to raster images
// 2. Routing each rendered image through the camera simulation pipeline
// 3. Correlating results back to page numbers manually
// This is not a supported workflow and requires significant custom engineering.
// Scandit SDK: no PDF support.
// Implementing PDF barcode extraction with Scandit requires:
// 1. A separate PDF rendering library to convert pages to raster images
// 2. Routing each rendered image through the camera simulation pipeline
// 3. Correlating results back to page numbers manually
// This is not a supported workflow and requires significant custom engineering.
' Scandit SDK: no PDF support.
' Implementing PDF barcode extraction with Scandit requires:
' 1. A separate PDF rendering library to convert pages to raster images
' 2. Routing each rendered image through the camera simulation pipeline
' 3. Correlating results back to page numbers manually
' This is not a supported workflow and requires significant custom engineering.
IronBarcode方法:
// NuGet: dotnet add package IronBarcode
using IronBarCode;
IronBarCode.License.LicenseKey = "YOUR-LICENSE-KEY";
var results = BarcodeReader.Read("shipping-manifest.pdf");
foreach (var result in results)
{
Console.WriteLine($"Page {result.PageNumber}: {result.Value} ({result.Format})");
}
// NuGet: dotnet add package IronBarcode
using IronBarCode;
IronBarCode.License.LicenseKey = "YOUR-LICENSE-KEY";
var results = BarcodeReader.Read("shipping-manifest.pdf");
foreach (var result in results)
{
Console.WriteLine($"Page {result.PageNumber}: {result.Value} ({result.Format})");
}
Imports IronBarCode
IronBarCode.License.LicenseKey = "YOUR-LICENSE-KEY"
Dim results = BarcodeReader.Read("shipping-manifest.pdf")
For Each result In results
Console.WriteLine($"Page {result.PageNumber}: {result.Value} ({result.Format})")
Next
有关从 PDF 文档中读取条形码的完整指南,包括页面范围选择和多条形码处理, IronBarcode文档涵盖了所有 PDF 处理场景。 无需额外依赖PDF库。
将事件回调转换为直接返回值
由于实时相机扫描本质上是异步的,Scandit通过BarcodeScanned事件提供条形码结果——当相机在当前帧中检测到条形码时,结果会到达。 IronBarcode将结果作为类型化集合返回,因为基于文件的读取具有已知的完成边界。 这是人口迁移中最具结构性意义的变化之一。
Scandit SDK 方法:
// Scandit SDK: event-driven result delivery
barcodeCapture.BarcodeScanned += (sender, args) =>
{
foreach (var barcode in args.Session.NewlyRecognizedBarcodes)
{
string value = barcode.Data;
string symbology = barcode.Symbology.ToString();
// Processing logic embedded inside event handler
LogBarcodeResult(value, symbology);
UpdateInventory(value);
}
};
// Scan continues indefinitely until camera session is terminated
// Scandit SDK: event-driven result delivery
barcodeCapture.BarcodeScanned += (sender, args) =>
{
foreach (var barcode in args.Session.NewlyRecognizedBarcodes)
{
string value = barcode.Data;
string symbology = barcode.Symbology.ToString();
// Processing logic embedded inside event handler
LogBarcodeResult(value, symbology);
UpdateInventory(value);
}
};
// Scan continues indefinitely until camera session is terminated
Imports System
' Scandit SDK: event-driven result delivery
AddHandler barcodeCapture.BarcodeScanned, Sub(sender, args)
For Each barcode In args.Session.NewlyRecognizedBarcodes
Dim value As String = barcode.Data
Dim symbology As String = barcode.Symbology.ToString()
' Processing logic embedded inside event handler
LogBarcodeResult(value, symbology)
UpdateInventory(value)
Next
End Sub
' Scan continues indefinitely until camera session is terminated
IronBarcode方法:
// NuGet: dotnet add package IronBarcode
using IronBarCode;
IronBarCode.License.LicenseKey = "YOUR-LICENSE-KEY";
var results = BarcodeReader.Read("document.png");
foreach (var result in results)
{
// Same processing logic, now in standard control flow
LogBarcodeResult(result.Value, result.Format.ToString());
UpdateInventory(result.Value);
}
// NuGet: dotnet add package IronBarcode
using IronBarCode;
IronBarCode.License.LicenseKey = "YOUR-LICENSE-KEY";
var results = BarcodeReader.Read("document.png");
foreach (var result in results)
{
// Same processing logic, now in standard control flow
LogBarcodeResult(result.Value, result.Format.ToString());
UpdateInventory(result.Value);
}
Imports IronBarCode
IronBarCode.License.LicenseKey = "YOUR-LICENSE-KEY"
Dim results = BarcodeReader.Read("document.png")
For Each result In results
' Same processing logic, now in standard control flow
LogBarcodeResult(result.Value, result.Format.ToString())
UpdateInventory(result.Value)
Next
所有嵌入在事件处理程序回调中的处理逻辑都移到了标准顺序代码中。 错误处理、日志记录和下游操作可以使用普通的控制流而不是事件处理程序模式来构建。
用于文件上传的ASP.NET Core端点
无状态服务器端点从上传的文件中读取条形码,代表了IronBarcode的主要服务器端用例。 Scandit 的相机流水线架构不支持这种模式。
Scandit SDK 方法:
// Scandit SDK: not applicable to ASP.NET Core file upload scenarios.
// The DataCaptureContext requires a camera hardware session.
// There is no mechanism to process an IFormFile through the Scandit pipeline
// without substantial custom camera-simulation infrastructure.
// Scandit SDK: not applicable to ASP.NET Core file upload scenarios.
// The DataCaptureContext requires a camera hardware session.
// There is no mechanism to process an IFormFile through the Scandit pipeline
// without substantial custom camera-simulation infrastructure.
' Scandit SDK: not applicable to ASP.NET Core file upload scenarios.
' The DataCaptureContext requires a camera hardware session.
' There is no mechanism to process an IFormFile through the Scandit pipeline
' without substantial custom camera-simulation infrastructure.
IronBarcode方法:
// NuGet: dotnet add package IronBarcode
using IronBarCode;
[ApiController]
[Route("api/[controller]")]
public class BarcodeController : ControllerBase
{
[HttpPost("scan")]
public IActionResult ScanUploadedDocument(IFormFile file)
{
if (file == null || file.Length == 0)
return BadRequest("No file provided");
using var stream = file.OpenReadStream();
var results = BarcodeReader.Read(stream);
if (!results.Any())
return NotFound("No barcodes detected");
return Ok(results.Select(r => new
{
r.Value,
Format = r.Format.ToString(),
r.PageNumber
}));
}
}
// NuGet: dotnet add package IronBarcode
using IronBarCode;
[ApiController]
[Route("api/[controller]")]
public class BarcodeController : ControllerBase
{
[HttpPost("scan")]
public IActionResult ScanUploadedDocument(IFormFile file)
{
if (file == null || file.Length == 0)
return BadRequest("No file provided");
using var stream = file.OpenReadStream();
var results = BarcodeReader.Read(stream);
if (!results.Any())
return NotFound("No barcodes detected");
return Ok(results.Select(r => new
{
r.Value,
Format = r.Format.ToString(),
r.PageNumber
}));
}
}
Imports IronBarCode
Imports Microsoft.AspNetCore.Mvc
<ApiController>
<Route("api/[controller]")>
Public Class BarcodeController
Inherits ControllerBase
<HttpPost("scan")>
Public Function ScanUploadedDocument(file As IFormFile) As IActionResult
If file Is Nothing OrElse file.Length = 0 Then
Return BadRequest("No file provided")
End If
Using stream = file.OpenReadStream()
Dim results = BarcodeReader.Read(stream)
If Not results.Any() Then
Return NotFound("No barcodes detected")
End If
Return Ok(results.Select(Function(r) New With {
.Value = r.Value,
.Format = r.Format.ToString(),
.PageNumber = r.PageNumber
}))
End Using
End Function
End Class
Stream,不需要创建临时文件。 结果在请求-响应周期内同步返回,没有异步相机管理。
跨多个文档的并发批处理
大量文档队列需要跨多个线程进行并行处理。 因为IronBarcode的API是无状态的,本质上是线程安全的,并直接与Parallel.ForEach和异步任务模式集成。
Scandit SDK 方法:
// Scandit SDK: no supported batch file processing pattern.
// The FrameSourceState model assumes a continuous camera session,
// not a queue of discrete documents. Batch processing would require
// one camera simulation pipeline per document or serialized processing
// through a shared pipeline — neither is a supported workflow.
// Scandit SDK: no supported batch file processing pattern.
// The FrameSourceState model assumes a continuous camera session,
// not a queue of discrete documents. Batch processing would require
// one camera simulation pipeline per document or serialized processing
// through a shared pipeline — neither is a supported workflow.
' Scandit SDK: no supported batch file processing pattern.
' The FrameSourceState model assumes a continuous camera session,
' not a queue of discrete documents. Batch processing would require
' one camera simulation pipeline per document or serialized processing
' through a shared pipeline — neither is a supported workflow.
IronBarcode方法:
// NuGet: dotnet add package IronBarcode
using IronBarCode;
using System.Collections.Concurrent;
IronBarCode.License.LicenseKey = "YOUR-LICENSE-KEY";
var options = new BarcodeReaderOptions
{
Speed = ReadingSpeed.Balanced,
ExpectMultipleBarcodes = true,
MaxParallelThreads = 4
};
var files = Directory.GetFiles("./documents/", "*.pdf");
var allResults = new ConcurrentBag<(string File, BarcodeResult Result)>();
Parallel.ForEach(files, file =>
{
var results = BarcodeReader.Read(file, options);
foreach (var result in results)
allResults.Add((file, result));
});
foreach (var (file, result) in allResults)
Console.WriteLine($"{Path.GetFileName(file)}: {result.Value} ({result.Format})");
// NuGet: dotnet add package IronBarcode
using IronBarCode;
using System.Collections.Concurrent;
IronBarCode.License.LicenseKey = "YOUR-LICENSE-KEY";
var options = new BarcodeReaderOptions
{
Speed = ReadingSpeed.Balanced,
ExpectMultipleBarcodes = true,
MaxParallelThreads = 4
};
var files = Directory.GetFiles("./documents/", "*.pdf");
var allResults = new ConcurrentBag<(string File, BarcodeResult Result)>();
Parallel.ForEach(files, file =>
{
var results = BarcodeReader.Read(file, options);
foreach (var result in results)
allResults.Add((file, result));
});
foreach (var (file, result) in allResults)
Console.WriteLine($"{Path.GetFileName(file)}: {result.Value} ({result.Format})");
Imports IronBarCode
Imports System.Collections.Concurrent
Imports System.IO
Imports System.Threading.Tasks
IronBarCode.License.LicenseKey = "YOUR-LICENSE-KEY"
Dim options As New BarcodeReaderOptions With {
.Speed = ReadingSpeed.Balanced,
.ExpectMultipleBarcodes = True,
.MaxParallelThreads = 4
}
Dim files = Directory.GetFiles("./documents/", "*.pdf")
Dim allResults As New ConcurrentBag(Of (File As String, Result As BarcodeResult))()
Parallel.ForEach(files, Sub(file)
Dim results = BarcodeReader.Read(file, options)
For Each result In results
allResults.Add((file, result))
Next
End Sub)
For Each item In allResults
Console.WriteLine($"{Path.GetFileName(item.File)}: {item.Result.Value} ({item.Result.Format})")
Next
对于涵盖异步和多线程条形码读取的高级模式,包括吞吐量调整和线程数配置, IronBarcode文档提供了详细的指导。
Scandit SDKAPI 到IronBarcode映射参考
| Scandit SDK | IronBarcode | 备注 |
|---|---|---|
DataCaptureContext.ForLicenseKey("key") |
IronBarCode.License.LicenseKey = "key" |
一项任务; 没有上下文对象 |
BarcodeCaptureSettings.Create() |
new BarcodeReaderOptions() |
选修的; 无需基础阅读 |
settings.EnableSymbologies(Symbology.Code128, ...) |
(not needed) | IronBarcode可自动检测所有格式 |
Camera.GetDefaultCamera() |
(not applicable) | 无摄像头概念 |
dataCaptureContext.SetFrameSourceAsync(camera) |
(not applicable) | 无帧源 |
camera.SwitchToDesiredStateAsync(FrameSourceState.On) |
(not applicable) | 无摄像头状态机 |
barcodeCapture.IsEnabled = true |
BarcodeReader.Read(path) |
单次调用即可启动读取 |
BarcodeScanned +=事件处理程序 |
返回值上的标准foreach |
无需事件系统 |
args.Session.NewlyRecognizedBarcodes |
BarcodeReader.Read() 的返回值 |
直接收款 |
barcode.Data |
result.Value |
相同的语义内容 |
barcode.Symbology |
result.Format |
等效格式枚举 |
using Scandit.DataCapture.Core |
using IronBarCode |
单一命名空间 |
using Scandit.DataCapture.Barcode |
using IronBarCode |
包含在同一命名空间中 |
| SparkScan产品 | BarcodeReader.Read(path) |
无需另购产品 |
| MatrixScan 产品 | BarcodeReaderOptions { ExpectMultipleBarcodes = true } |
包含在基础套餐中 |
常见迁移问题和解决方案
问题 1:相机管线代码没有直接翻译
Scandit SDK: BarcodeCapture设置块跨越7–10行初始化代码,具有异步状态转换。
解决方法:将此代码块完全删除。 它没有IronBarcode 的等效功能,因为IronBarcode基于文件的 API 不需要会话初始化。 将整个代码块替换为:
IronBarCode.License.LicenseKey = "YOUR-LICENSE-KEY";
IronBarCode.License.LicenseKey = "YOUR-LICENSE-KEY";
Imports IronBarCode
IronBarCode.License.LicenseKey = "YOUR-LICENSE-KEY"
问题 2:条形码扫描事件处理程序逻辑
Scandit SDK: 处理逻辑嵌入在BarcodeScanned +=事件处理程序lambda或方法内。 IronBarcode中不存在这种模式。
解决方案: 将处理程序主体移动到BarcodeReader.Read调用后的标准代码中:
// Before: event handler
barcodeCapture.BarcodeScanned += (s, args) =>
{
foreach (var b in args.Session.NewlyRecognizedBarcodes)
Console.WriteLine(b.Data);
};
// After: direct iteration
foreach (var result in BarcodeReader.Read("document.png"))
Console.WriteLine(result.Value);
// Before: event handler
barcodeCapture.BarcodeScanned += (s, args) =>
{
foreach (var b in args.Session.NewlyRecognizedBarcodes)
Console.WriteLine(b.Data);
};
// After: direct iteration
foreach (var result in BarcodeReader.Read("document.png"))
Console.WriteLine(result.Value);
Imports System
' Before: event handler
AddHandler barcodeCapture.BarcodeScanned, Sub(s, args)
For Each b In args.Session.NewlyRecognizedBarcodes
Console.WriteLine(b.Data)
Next
End Sub
' After: direct iteration
For Each result In BarcodeReader.Read("document.png")
Console.WriteLine(result.Value)
Next
问题 3:EnableSymbologies 调用分散在代码库各处
Scandit SDK: 代码库中的多个地方可能使用不同的符号集调用settings.EnableSymbologies(...)以适应不同的扫描上下文。
解决方案: 移除所有EnableSymbologies调用。 IronBarcode默认会自动检测所有支持的格式。 如果在特定场景中需要格式限制以提高性能,请使用BarcodeReaderOptions.ExpectBarcodeTypes:
var options = new BarcodeReaderOptions
{
ExpectBarcodeTypes = BarcodeEncoding.Code128 | BarcodeEncoding.QRCode
};
var results = BarcodeReader.Read("document.png", options);
var options = new BarcodeReaderOptions
{
ExpectBarcodeTypes = BarcodeEncoding.Code128 | BarcodeEncoding.QRCode
};
var results = BarcodeReader.Read("document.png", options);
Imports System
Dim options As New BarcodeReaderOptions With {
.ExpectBarcodeTypes = BarcodeEncoding.Code128 Or BarcodeEncoding.QRCode
}
Dim results = BarcodeReader.Read("document.png", options)
问题 4:现有代码库无法读取 PDF 文件
Scandit SDK:如果现有代码库在将 PDF 页面输入 Scandit 管道之前将其转换为图像,则不再需要此自定义渲染基础架构。
解决方案:完全移除 PDF 转图像渲染步骤。 将 PDF 路径直接传递给IronBarcode:
// Before: render PDF pages to images, then pass each image to Scandit pipeline
// (multiple steps, external PDF library dependency)
// After: pass PDF directly to IronBarcode
var results = BarcodeReader.Read("document.pdf");
// Results include PageNumber property for each detected barcode
// Before: render PDF pages to images, then pass each image to Scandit pipeline
// (multiple steps, external PDF library dependency)
// After: pass PDF directly to IronBarcode
var results = BarcodeReader.Read("document.pdf");
// Results include PageNumber property for each detected barcode
' Before: render PDF pages to images, then pass each image to Scandit pipeline
' (multiple steps, external PDF library dependency)
' After: pass PDF directly to IronBarcode
Dim results = BarcodeReader.Read("document.pdf")
' Results include PageNumber property for each detected barcode
问题 5:异步相机初始化模式
Scandit SDK: 相机初始化使用SwitchToDesiredStateAsync。 如果调用代码是围绕这些异步操作构建的,那么删除它们可以简化异步链。
解决方案:完全移除异步相机初始化。 BarcodeReader.Read是同步的。 如果在UI或服务器上下文中需要异步执行以提高响应性,将其包装在Task.Run中:
// Async wrapper for non-blocking execution
var results = await Task.Run(() => BarcodeReader.Read("document.png"));
// Async wrapper for non-blocking execution
var results = await Task.Run(() => BarcodeReader.Read("document.png"));
Imports System.Threading.Tasks
' Async wrapper for non-blocking execution
Dim results = Await Task.Run(Function() BarcodeReader.Read("document.png"))
Scandit SDK迁移清单
迁移前任务
审核代码库中所有 Scandit 集成点:
grep -r "DataCaptureContext\|BarcodeCaptureSettings\|BarcodeCapture" --include="*.cs" .
grep -r "EnableSymbologies\|BarcodeScanned\|NewlyRecognizedBarcodes" --include="*.cs" .
grep -r "using Scandit" --include="*.cs" .
grep -r "barcode\.Data\|barcode\.Symbology\|FrameSourceState" --include="*.cs" .
grep -r "DataCaptureContext\|BarcodeCaptureSettings\|BarcodeCapture" --include="*.cs" .
grep -r "EnableSymbologies\|BarcodeScanned\|NewlyRecognizedBarcodes" --include="*.cs" .
grep -r "using Scandit" --include="*.cs" .
grep -r "barcode\.Data\|barcode\.Symbology\|FrameSourceState" --include="*.cs" .
记录所有扫描上下文——确定哪些代码路径处理实时相机扫描(继续使用 Scandit),哪些处理文件或文档处理(迁移到IronBarcode)。 请注意所有在 Scandit 处理之前将 PDF 页面渲染成图像的地方,因为此渲染步骤将被省略。
代码更新任务
- 移除Scandit NuGet包(
Scandit.BarcodePicker,Scandit.DataCapture.Core,Scandit.DataCapture.Barcode) - 安装
IronBarcodeNuGet包 - 用
using Scandit.DataCapture.*导入 - 删除
DataCaptureContext初始化块的全部内容 - 删除所有
SetFrameSourceAsync调用 - 删除所有
EnableSymbologies调用 - 将
BarcodeReader.Read(filePath) - 转换
BarcodeReader.Read()结果 - 将
result.Value - 将
result.Format - 移除IronBarcode直接读取PDF文件时使用的PDF转图像渲染流程。
- 在应用程序启动时添加
IronBarCode.License.LicenseKey = "YOUR-LICENSE-KEY"
迁移后测试
代码更新完成后,请核实以下内容:
- 确认IronBarcode返回的条形码值与 Scandit 之前针对同一输入文档返回的值是否一致
- 验证在文档集中所有支持的条形码格式在没有
ExpectBarcodeTypes配置的情况下都能被检测到 - 测试PDF提取是否为多页文档返回正确的
PageNumber值 - 确认ASP.NET Core端点在预期负载下能在可接受的响应时间内返回结果
- 验证 Docker 或容器化部署是否能在没有摄像头硬件的情况下成功完成条形码读取
- 测试并发批量处理与
Parallel.ForEach无竞争状态下产生正确结果 - 确认应用程序能够使用IronBarcode许可证密钥(而非 Scandit 上下文)正确启动和初始化
迁移到IronBarcode的主要优势
消除相机管道开销: 移除DataCaptureContext初始化序列可消除状态相机管理、异步状态转换和特定平台相机API从服务器端代码中。 生成的代码更简单、更短,并且没有平台限制,因此可以部署在 Linux、Docker 容器或无服务器计算环境中。
直接 PDF 处理:原生 PDF 条形码提取消除了对单独的 PDF 渲染库的依赖、页面到图像管道的工程开销以及该依赖项的额外许可成本。 多页 PDF 文档通过一次方法调用进行处理,并立即提供按页索引的结果。
同步无状态 API:直接返回值模型用标准顺序代码取代了事件驱动的回调模式。 错误处理、日志记录和下游处理与现有应用程序架构自然集成,无需事件订阅管理或异步状态机协调。
公开透明定价:永久许可级别公开列出,价格分别为 749 美元、1499 美元和 2999 美元,使得预算提案、供应商比较和采购流程无需销售周期即可进行。 在编写任何集成代码之前,许可费用即可确定。
完全云和容器支持:IronBarcode的无状态、硬件无关的 API 无需修改即可在 Azure Functions、AWS Lambda、Linux 上的 Docker 容器以及任何其他.NET运行时可用的计算环境中运行。 在这些环境中部署无需相机模拟、无需硬件依赖性变通方法、也无需特定于平台的配置。
自动格式检测: 移除EnableSymbologies声明意味着处理意外条形码格式的传入文档无需代码更改。 当传入文档中的格式发生变化时——例如新的供应商、新的标签格式、新的文档类型IronBarcode会自动处理这些新格式。
常见问题解答
我为什么要从 Scandit SDK 迁移到 IronBarcode?
常见原因包括简化许可(消除 SDK + 运行时密钥的复杂性)、消除吞吐量限制、获得原生 PDF 支持、改进 Docker/CI/CD 部署以及减少生产代码中的 API 样板代码。
如何用 IronBarcode 替换 Scandit API 调用?
用 `IronBarCode.License.LicenseKey = "key"` 替换实例创建和许可相关的样板代码。用 `BarcodeReader.Read(path)` 替换读取器调用,用 `BarcodeWriter.CreateBarcode(data, encoding)` 替换写入器调用。静态方法无需实例管理。
从 Scandit SDK 迁移到 IronBarcode 时,代码需要做多少更改?
大多数迁移都能减少代码行数。许可样板代码、实例构造函数和显式格式配置都被移除。核心读/写操作映射到更简洁的 IronBarcode 等效代码,并生成更清晰的结果对象。
迁移过程中是否需要同时保留 Scandit SDK 和 IronBarcode?
不。大多数迁移都是直接替换,而不是并行操作。一次迁移一个服务类,替换 NuGet 引用,并更新实例化和 API 调用模式,然后再迁移下一个类。
IronBarcode 的 NuGet 包名称是什么?
该软件包名为“IronBarCode”(B 和 C 大写)。使用“Install-Package IronBarCode”或“dotnet add package IronBarCode”进行安装。代码中的 using 指令为“using IronBarCode;”。
与 Scandit SDK 相比,IronBarcode 如何简化 Docker 部署?
IronBarcode 是一个 NuGet 包,不包含任何外部 SDK 文件或已挂载的许可证配置。在 Docker 环境中,设置 IRONBARCODE_LICENSE_KEY 环境变量后,该包会在启动时自动处理许可证验证。
从 Scandit 迁移后,IronBarcode 是否能自动检测所有条形码格式?
是的。IronBarcode 可以自动检测所有支持格式的条码符号,无需显式枚举 BarcodeTypes。如果已知条码格式且性能至关重要,BarcodeReaderOptions 允许缩小搜索范围以进行优化。
IronBarcode 能否在不使用单独库的情况下读取 PDF 中的条形码?
是的。`BarcodeReader.Read("document.pdf")` 可以直接处理 PDF 文件。结果包括每个条形码的页码、格式、值和置信度。无需外部 PDF 渲染步骤。
IronBarcode如何处理并行条码处理?
IronBarcode 的静态方法是无状态且线程安全的。可以直接对文件列表使用 Parallel.ForEach,无需进行线程级实例管理。BarcodeReaderOptions.MaxParallelThreads 控制内部线程预算。
从 Scandit SDK 迁移到 IronBarcode 时,哪些结果属性会发生变化?
常见重命名:BarcodeValue 变为 Value,BarcodeType 变为 Format。IronBarcode 结果还会添加 Confidence 和 PageNumber。解决方案范围内的查找替换功能会处理现有结果处理代码中的重命名。
如何在 CI/CD 流水线中设置 IronBarcode 许可?
将 IRONBARCODE_LICENSE_KEY 存储为管道密钥,并在应用程序启动代码中赋值 IronBarCode.License.LicenseKey。一个密钥即可覆盖所有环境,包括开发、测试、预发布和生产环境。
IronBarcode是否支持生成自定义样式的二维码?
是的。QRCodeWriter.CreateQrCode() 支持通过 ChangeBarCodeColor() 自定义颜色、通过 AddBrandLogo() 嵌入徽标、可配置纠错级别以及多种输出格式,包括 PNG、JPG、PDF 和流媒体。

