从Neodynamic条码迁移到IronBarcode
本指南提供了从Neodynamic.SDK.BarcodeReader迁移到IronBarcode的完整路径。 它涵盖了移除 Neodynamic 软件包、用单个密钥替换双许可证配置、转换生成和读取 API 调用,以及获得 Neodynamic 产品集无法实现的 2D 条形码读取功能的过程。 本指南是为拥有现有 Neodynamic 代码的开发人员编写的,他们需要采用系统化的、逐个文件的方法来完成迁移。
为什么要从新动态条形码迁移?
2D 阅读差距: Neodynamic 条码ProfessionalSDK 可生成 QR 码、DataMatrix、PDF417 和 Aztec 条码。 配套的条形码阅读器 SDK 无法读取这些格式中的任何一种。 一个用于生成产品标签、运输容器或文件跟踪的二维码的项目,无法通过与生成器一起购买的读取器读取这些二维码。 IronBarcode通过同一个库和同一个许可证读取和生成 QR 码、DataMatrix、PDF417、Aztec 以及所有其他支持的 2D 格式。
双产品开销: 每个使用Neodynamic SDKs的项目都要包含两个using指令、两个许可证块以及两个独立的更新周期。 这种开销会在每台开发人员机器、每个 CI 流水线和每个生产环境中重复出现。 将两个具有不同维护要求的软件包合并为一个具有单个许可证的单一依赖项,是此次迁移的机械结果。
**第三库问题:**遇到 2D 读取差距并选择绕过它而不是迁移的团队通常会添加第三个库——ZXing .NET是最常见的选择——专门用于覆盖二维码读取。 该决定用一个限制换取了另一个复杂性:三个与条形码相关的依赖项,每个依赖项都有自己的版本限制、自己的发行说明,并且在.NET运行时或依赖框架更新时,每个依赖项都有自己的潜在冲突。 IronBarcode可以替代这三者。
定价复杂性: Neodynamic条形码专业SDK按开发者定价(基本约$352,终极通过ComponentSource约$705)。 条形码阅读器SDK需单独付费。需要生成和1D读取的项目必须购买这两个,而且结合的成本会随着团队规模一起缩放,外加阅读器费用。 需要2D读取的项目,即使在Neodynamic产品家族内也无法满足这一要求。IronBarcodeLite涵盖了生成和读取——1D和2D——在一个许可证下。 当前定价在IronBarcode许可页面上。
基本问题
任何使用 Neodynamic SDK 实现完整条形码工作流程的代码库都存在一个核心问题:QR 码读取始终无法实现:
// Before: 新动力条形码阅读器 does not support QR codes
using Neodynamic.SDK.BarcodeReader;
using System.Drawing;
public string ReadQrCode(string imagePath)
{
using var bitmap = new Bitmap(imagePath);
var reader = new BarcodeReader();
var results = reader.Read(bitmap);
// Results are always null or empty for 2D barcodes
if (results == null || !results.Any())
{
throw new NotSupportedException(
"Neodynamic Barcode Reader does not support QR codes");
}
return results.First().Value;
}
迁移到IronBarcode后,相同的操作就变成了标准的读取调用,不再进行任何格式特定的处理:
// After:IronBarcodereads QR codes with the same call used for all formats
using IronBarCode;
public string ReadQrCode(string imagePath)
{
var result = BarcodeReader.Read(imagePath).FirstOrDefault();
return result?.Value;
}
在此迁移过程中,代码库中引用二维条码读取的每一个throw new NotSupportedException(...)占位符都被替换为可用的读取调用。
IronBarcode与 Neodynamic Barcode:功能对比
| 特征 | Neodynamic 条码Professional | 新动力条形码阅读器 | IronBarcode |
|---|---|---|---|
| Code 128、EAN-13、UPC-A 代 | 是 | 不适用 | 是 |
| QR码、DataMatrix码、PDF417码生成 | 是 | 不适用 | 是 |
| 一维条形码读取 | 不适用 | 是 | 是 |
| 二维码读取 | 不适用 | 不 | 是 |
| DataMatrix 读取 | 不适用 | 不 | 是 |
| PDF417 阅读 | 不适用 | 不 | 是 |
| 原生 PDF 条形码读取 | 否 | 否 | 是 |
| 自动格式检测 | 不适用 | 否 | 是 |
| 需要NuGet包 | 1 | 1 | 1(涵盖两者) |
| 需要许可证密钥 | 1 | 1(单独) | 1(涵盖所有) |
| 系统绘图依赖项 | 是 | 是 | 否 |
| Linux/Docker 支持 | 有限的 | 有限的 | 是 |
| 支持.NET 8 / .NET 9 | 是 | 有限的 | 是 |
| 异步批量读取 | 否 | 否 | 是 |
快速入门:Neodynamic 条码到IronBarcode 的迁移
第一步:移除两个新动力软件包
两个包裹都必须移除。 它们之间没有影响移除顺序的共同依赖关系:
dotnet remove package Neodynamic.SDK.Barcode
dotnet remove package Neodynamic.SDK.BarcodeReader
在继续之前,请验证这两个条目已经从.csproj文件中删除。
步骤 2:添加IronBarcode
dotnet add package IronBarcode
步骤 3:替换双许可证配置
移除两个 Neodynamic 许可证块,并用单个IronBarcode密钥分配替换它们。 此分配在应用程序启动时进行一次——在Startup.cs或应用程序的组合根中:
// Before: two license blocks, two products
using Neodynamic.SDK.Barcode;
using Neodynamic.SDK.BarcodeReader;
BarcodeProfessional.LicenseOwner = "Your Company";
BarcodeProfessional.LicenseKey = "GEN-LICENSE-KEY";
Neodynamic.SDK.BarcodeReader.BarcodeReader.LicenseOwner = "Your Company";
Neodynamic.SDK.BarcodeReader.BarcodeReader.LicenseKey = "READ-LICENSE-KEY";Imports Neodynamic.SDK.Barcode
Imports Neodynamic.SDK.BarcodeReader
BarcodeProfessional.LicenseOwner = "Your Company"
BarcodeProfessional.LicenseKey = "GEN-LICENSE-KEY"
Neodynamic.SDK.BarcodeReader.BarcodeReader.LicenseOwner = "Your Company"
Neodynamic.SDK.BarcodeReader.BarcodeReader.LicenseKey = "READ-LICENSE-KEY"// After: one key covers generation and reading across all formats
using IronBarCode;
IronBarCode.License.LicenseKey = "YOUR-LICENSE-KEY";Imports IronBarCode
' After: one key covers generation and reading across all formats
IronBarCode.License.LicenseKey = "YOUR-LICENSE-KEY"迁移验证完成后,可以停用任何保存 Neodynamic 许可证密钥的配置文件、环境变量或密钥存储。
代码迁移示例
生成 Code 128 条形码
新动力学方法:
using Neodynamic.SDK.Barcode;
using System.Drawing.Imaging;
public void GenerateCode128(string data, string outputPath)
{
var barcode = new BarcodeProfessional();
barcode.Code = data;
barcode.Symbology = Symbology.Code128;
barcode.BarcodeUnit = BarcodeUnit.Pixel;
System.Drawing.Image image = barcode.GetBarcodeImage();
image.Save(outputPath, ImageFormat.Png);
}Imports Neodynamic.SDK.Barcode
Imports System.Drawing.Imaging
Public Sub GenerateCode128(data As String, outputPath As String)
Dim barcode As New BarcodeProfessional()
barcode.Code = data
barcode.Symbology = Symbology.Code128
barcode.BarcodeUnit = BarcodeUnit.Pixel
Dim image As System.Drawing.Image = barcode.GetBarcodeImage()
image.Save(outputPath, ImageFormat.Png)
End SubIronBarcode方法:
using IronBarCode;
public void GenerateCode128(string data, string outputPath)
{
BarcodeWriter.CreateBarcode(data, BarcodeEncoding.Code128)
.SaveAsPng(outputPath);
}Imports IronBarCode
Public Sub GenerateCode128(data As String, outputPath As String)
BarcodeWriter.CreateBarcode(data, BarcodeEncoding.Code128) _
.SaveAsPng(outputPath)
End Sub不再需要System.Drawing.Imaging导入。 BarcodeInfo实例及其属性分配合并为一个方法调用。 有关尺寸、注释和输出格式选项,请参阅创建一维条形码指南。
生成二维码
新动力学方法:
using Neodynamic.SDK.Barcode;
public void GenerateQrCode(string data, string outputPath)
{
var barcode = new BarcodeProfessional();
barcode.Code = data;
barcode.Symbology = Symbology.QRCode;
barcode.QRCodeECL = QRCodeErrorCorrectionLevel.H;
barcode.GetBarcodeImage().Save(outputPath, System.Drawing.Imaging.ImageFormat.Png);
}Imports Neodynamic.SDK.Barcode
Imports System.Drawing.Imaging
Public Sub GenerateQrCode(data As String, outputPath As String)
Dim barcode As New BarcodeProfessional()
barcode.Code = data
barcode.Symbology = Symbology.QRCode
barcode.QRCodeECL = QRCodeErrorCorrectionLevel.H
barcode.GetBarcodeImage().Save(outputPath, ImageFormat.Png)
End SubIronBarcode方法:
using IronBarCode;
public void GenerateQrCode(string data, string outputPath)
{
QRCodeWriter.CreateQrCode(data, 500, QRCodeWriter.QrErrorCorrectionLevel.Highest)
.SaveAsPng(outputPath);
}Imports IronBarCode
Public Sub GenerateQrCode(data As String, outputPath As String)
QRCodeWriter.CreateQrCode(data, 500, QRCodeWriter.QrErrorCorrectionLevel.Highest) _
.SaveAsPng(outputPath)
End Sub版本转换仅更改 API 接口。 此次迁移带来的关键区别在于,同一个应用程序现在也可以通过同一个IronBarcode库和同一个许可证读取它生成的二维码。 有关二维条形码创建的完整说明,请参阅二维条形码创建指南。
读取一维条形码
新动力学方法:
using Neodynamic.SDK.BarcodeReader;
using System.Drawing;
public string[] Read1DBarcodes(string imagePath)
{
using var bitmap = new Bitmap(imagePath);
var reader = new BarcodeReader();
var results = reader.Read(bitmap);
return results?.Select(r => r.Value).ToArray() ?? Array.Empty<string>();
}Imports Neodynamic.SDK.BarcodeReader
Imports System.Drawing
Public Function Read1DBarcodes(imagePath As String) As String()
Using bitmap As New Bitmap(imagePath)
Dim reader As New BarcodeReader()
Dim results = reader.Read(bitmap)
Return If(results?.Select(Function(r) r.Value).ToArray(), Array.Empty(Of String)())
End Using
End FunctionIronBarcode方法:
using IronBarCode;
public string[] Read1DBarcodes(string imagePath)
{
var results = BarcodeReader.Read(imagePath);
return results.Select(r => r.Value).ToArray();
}Imports IronBarCode
Public Function Read1DBarcodes(imagePath As String) As String()
Dim results = BarcodeReader.Read(imagePath)
Return results.Select(Function(r) r.Value).ToArray()
End Function已删除System.Drawing导入。 IronBarcode直接接受文件路径。 result.Value属性名称在两个API中相同,因此处理返回值的下游代码无需更改。 有关多条形码图像读取和预处理选项,请参阅从图像读取条形码指南。
读取二维码(以前不可能)
新动力学方法:
// This method could not be implemented with Neodynamic Barcode Reader
public string ReadQrCode(string imagePath)
{
throw new NotSupportedException(
"Neodynamic Barcode Reader does not support QR codes");
}' This method could not be implemented with Neodynamic Barcode Reader
Public Function ReadQrCode(imagePath As String) As String
Throw New NotSupportedException("Neodynamic Barcode Reader does not support QR codes")
End FunctionIronBarcode方法:
using IronBarCode;
public string ReadQrCode(string imagePath)
{
var result = BarcodeReader.Read(imagePath).FirstOrDefault();
return result?.Value;
}Imports IronBarCode
Public Function ReadQrCode(imagePath As String) As String
Dim result = BarcodeReader.Read(imagePath).FirstOrDefault()
Return If(result?.Value, Nothing)
End Function引用二维条码读取的每一个throw new NotSupportedException(...)占位符变为标准读取调用。 方法体从抛出的异常变为可执行的实现。 二维码无需特殊处理; IronBarcode可自动识别格式。
从PDF文档中读取条形码(新功能)
新动力学方法:
// Neodynamic Reader cannot read barcodes from PDF files directly
// An image extraction step using a separate library was required before reading
// 否 direct equivalent exists
IronBarcode方法:
using IronBarCode;
public void ReadBarcodesFromPdf(string pdfPath)
{
var results = BarcodeReader.Read(pdfPath);
foreach (var result in results)
{
Console.WriteLine($"Value: {result.Value} | Format: {result.Format} | Page: {result.PageNumber}");
}
}Imports IronBarCode
Public Sub ReadBarcodesFromPdf(pdfPath As String)
Dim results = BarcodeReader.Read(pdfPath)
For Each result In results
Console.WriteLine($"Value: {result.Value} | Format: {result.Format} | Page: {result.PageNumber}")
Next
End SubIronBarcode可以直接读取 PDF 文档所有页面上的条形码。 结果中会返回每个条形码所在的页码。 此功能无需额外的库,也无需中间图像提取步骤。
Neodynamic 条形码 API 到IronBarcode映射参考
| 新动态 API | IronBarcode等效物 | 备注 |
|---|---|---|
BarcodeInfo.LicenseOwner = "..." | IronBarCode.License.LicenseKey = "key" | 合并为单个密钥 |
BarcodeInfo.LicenseKey = "..." | (part of single key above) | 没有单独的所有者字段 |
Neodynamic.SDK.BarcodeReader.BarcodeReader.LicenseOwner | (removed) | 不要求 |
Neodynamic.SDK.BarcodeReader.BarcodeReader.LicenseKey | (removed) | 不要求 |
new BarcodeInfo() | BarcodeWriter.CreateBarcode(data, encoding) | 静态,无实例 |
barcode.Value = data | CreateBarcode的第一个参数 | 施工期间通过 |
barcode.Symbology = Symbology.Code128 | BarcodeEncoding.Code128 | 第二个参数 |
barcode.Symbology = Symbology.QRCode | BarcodeEncoding.QRCode | 现在支持全程往返 |
barcode.QRCodeECL = QRCodeErrorCorrectionLevel.H | QRCodeWriter.QrErrorCorrectionLevel.Highest | 不同的阶级入口点 |
barcode.GetImage().Save(path, ImageFormat.Png) | .SaveAsPng(path) | Fluent,没有 ImageFormat 枚举 |
BarcodeReader.Read(bitmap) | BarcodeReader.Read(imagePath) | 文件路径替换位图 |
result.Value | result.Value | 相同的属性名称 |
Symbology.DataMatrix | BarcodeEncoding.DataMatrix | 仅限世代 → 世代与阅读 |
用于二维读取的throw new NotSupportedException(...) | BarcodeReader.Read(imagePath) | 替换为可行的实施方案 |
常见迁移问题和解决方案
问题 1:双包裹移除令
**问题:**开发者仅移除一个 Neodynamic 包而保留另一个包会导致编译错误,因为这两个 SDK 没有共享类型,但某些源文件可能在同一个文件中导入两个命名空间。
**解决方法:**在对源代码进行任何更改之前,先移除这两个软件包。 在删除两者后,搜索所有using Neodynamic.SDK.BarcodeReader指令并一起删除它们:
dotnet remove package Neodynamic.SDK.Barcode
dotnet remove package Neodynamic.SDK.BarcodeReader
然后使用以下工具进行审核:
grep -r "Neodynamic.SDK" --include="*.cs" .
问题 2:双许可证配置清理
问题: 两个Neodynamic许可证块通常出现在不同位置——一个在应用程序启动类,一个在服务初始化程序中。 如果只删除一个代码块,剩余的代码将引用一个不再存在的命名空间,从而导致编译失败。
**解决方案:**查找所有四个 Neodynamic 许可证属性分配,并在添加IronBarcode密钥之前将它们一起删除:
grep -r "LicenseOwner\|LicenseKey" --include="*.cs" .
将所有四行代码替换为一行赋值语句:
IronBarCode.License.LicenseKey = "YOUR-LICENSE-KEY";Imports IronBarCode
IronBarCode.License.LicenseKey = "YOUR-LICENSE-KEY"问题 3:从 catch 代码块中移除 NotSupportedException
问题: 使用过Neodynamic Reader的某些代码库专门添加了catch (NotSupportedException)块来处理二维条码读取的静默失败。 必须移除这些 catch 代码块以及抛出异常的代码; 否则,catch子句引用了一个不能再发生的代码路径。
解决方案: 在条码相关文件中搜索NotSupportedException并检查每次出现。 如果异常是由于尝试读取二维格式而引发的,则删除 throw 和 catch 语句:
grep -r "NotSupportedException" --include="*.cs" .
用BarcodeReader.Read(imagePath)替换抛出的方法体,并从任何调用方中移除相应的catch子句。
新动态条形码迁移检查清单
迁移前
- 搜索所有Neodynamic包引用:
grep -r "Neodynamic.SDK" --include="*.csproj" . - 搜索所有Neodynamic使用指令:
grep -r "using Neodynamic" --include="*.cs" . - 搜索许可证配置位置:
grep -r "LicenseOwner\|LicenseKey" --include="*.cs" . - 搜索所有
grep -r "new BarcodeInfo\(\)" --include="*.cs" . - 搜索所有Neodynamic读取调用:
grep -r "BarcodeReader.Read" --include="*.cs" . - 搜索条码路径中所有
grep -r "NotSupportedException" --include="*.cs" . - 找出任何专门为弥补二维阅读缺陷而添加的第三方库(例如 ZXing .NET或类似库)——这些库可以在迁移后移除。
- 记录所有 Neodynamic 许可证密钥,以便在验证后从密钥库中将其停用。
代码更新任务
- 运行
dotnet remove package Neodynamic.SDK.Barcode - 运行
dotnet remove package Neodynamic.SDK.BarcodeReader - 运行
dotnet add package IronBarcode - 删除所有
using Neodynamic.SDK.BarcodeReader指令 - 在执行条码操作的所有文件中添加
using IronBarCode - 移除两个 Neodynamic 许可证配置块
- 在应用程序启动时添加一次
IronBarCode.License.LicenseKey = "YOUR-LICENSE-KEY" - 用
new BarcodeInfo()+ 属性分配 +barcode.GetImage().Save(...) - 使用
QRCodeWriter模式 - 通过删除
BarcodeReader.Read(imagePath) - 删除所有二维读取的
BarcodeReader.Read(imagePath) - 从调用方中移除相应的
catch (NotSupportedException)块 - 移除所有仅为弥补 Neodynamic 2D 阅读缺陷而添加的第三方库。
迁移后测试
- 验证 Code 128 条形码的生成结果是否与之前的尺寸和 DPI 设置相符
- 验证二维码生成器是否能生成可扫描的输出
- 验证一维条形码读取返回的值与之前的 Neodynamic Reader 实现返回的值相同
- 验证先前抛出
NotSupportedException的图像上的二维码读取是否成功 - 如果应用程序的输入中包含 DataMatrix 和 PDF417 格式,请验证这两种格式的读取是否成功
- 测试应用程序是否能够读取 PDF 条形码
- 确认已从配置文件和环境变量中移除所有 Neodynamic 许可证密钥引用
- 确认第三方 2D 库(如果存在)已完全移除,并且没有任何残留的导入语句引用它。
迁移到IronBarcode的主要优势
**统一的读写能力:**迁移后, IronBarcode生成的每一种符号体系都可以通过同一个库读取回来。 Neodynamic 的生成器和读取器之间的不对称性(QR 码、DataMatrix、PDF417 和 Aztec 可以生成但不能使用)被消除了。 以前需要变通方法或第三方库才能读取 2D 数据的应用程序,现在无需任何额外的集成工作即可获得该功能。
**单一许可证管理:**一个NuGet包、一个许可证密钥和一个配置块取代两个独立的产品订阅。 更新、关键轮换和环境因素管理变得不那么复杂了。 行政开支的减少是一个持续的过程,而不是一次性的收益。
原生 PDF 条形码读取: IronBarcode直接从 PDF 文档读取条形码,并返回条形码值以及页码元数据。 处理包含嵌入式条形码的货运清单、发票文件或医疗记录的应用程序不再需要中间图像提取步骤或额外的 PDF 库来支持条形码读取。 请参阅支持的条形码格式完整列表,了解所涵盖的全部符号体系和输入类型。
消除System.Drawing依赖: Neodynamic的SDK依赖于System.Drawing,这需要在Linux和Docker容器上进行额外的本地库配置。 IronBarcode不依赖System.Drawing,这意味着相同的代码库可以在Windows、Linux和容器化的云环境中运行而无需进行特定于平台的配置更改。
**简化许可成本,实现完整功能:**一个项目需要 Neodynamic SDK和第三个用于 2D 读取的库,却要为三个依赖项付费才能实现IronBarcode只需一个许可证即可提供的功能。 对于需要生成Plus和读取二维图像的项目,迁移将技术占用空间和许可成本整合到一个商业产品中。 当前定价信息可在IronBarcode许可页面上找到。

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