從ZXing.Net遷移到IronBarcode
本指南涵蓋了從ZXing.Net遷移到IronBarcode的完整過程,適用於讀取和生成條碼的.NET應用程式。 它解決了移除ZXing.Net的核心包和綁定包的問題,消除了在使用PdfiumViewer時出現的變通辦法,以及用IronBarcode的靜態API替換每個有狀態的BarcodeReader實例。 每個部分都包括從ZXing.Net整合中最常見的範例中得出的程式碼前後比較。
為什麼從ZXing.Net遷移
ZXing.Net 作為一個免費的 Apache 2.0 條碼庫,為 .NET 社區服務了十多年。 然而,隨著應用程式規模或複雜度的增加,一些架構約束已成為運營成本。
執行緒安全擁有權: ZXing.Net 的BarcodeReader是一個有狀態的物件。 該庫的自身文件指出,不得跨執行緒共享實例。 在實踐中,這意味著每個並行處理路徑——每個控制器操作處理同時響應,每個並行批次中的任務——都必須分配、配置和丟棄其自己的讀取器。 隨著請求量的增加,這種分配模式會產生可測量的記憶體壓力。 ThreadLocal<BarcodeReader> 的替代方法減少了分配頻率,但引入了自己的銷毀複雜性。 在這兩種情況下,並行性下的正確性是呼叫者的問題,而不是由庫提供的保證。
格式規範風險: ZXing.Net 需要在每次解碼操作之前填充reader.Options.PossibleFormats。 如果條碼是該列表中不存在的格式,則返回null——沒有例外、沒有警告、沒有指示條碼存在但未被識別的提示。 對於接收來自外部合作夥伴的文件的應用程式,這種靜默錯失行為是一個可靠性風險:誤發的訂單、錯過的患者登記記錄,或審核記錄未曾寫入,這些都可能源於配置為先前需求且從未更新的格式列表。
PDF 處理缺口: ZXing.Net 僅讀取位圖。 當源文件是 PDFs——發票、運單、合規證書時——呼叫者必須整合一個單獨的 PDF 渲染庫(PdfiumViewer 是最常見的),實現頁面枚舉迴圈,配置 DPI,管理臨時文件,並在成功和失敗的路徑上進行清理。 這是一個僅為將ZXing.Net無法讀取的(PDFs)轉換成能讀取的(位圖)而存在的整合,每個整合大約需要30到50行基礎設施程式碼。 該基礎設施有其自己的依賴項、部署要求和失敗模式。
平台綁定碎片化: ZXing.Net 的圖像載入功能跨平台特定綁定包分割。 Windows 綁定使用 System.Drawing.Bitmap; 跨平台綁定使用 SixLabors.ImageSharp,具有不同的泛型型別參數和不同的 using 指令。一個在 Windows 上啟動後又在 Linux 上容器化的專案必須更改其 NuGet 參考和其圖像載入程式碼。 對同一操作的兩個程式碼路徑增加了錯誤的表面積,並增加了在掃描層進行未來更改的阻力。
基本問題
ZXing.Net 架構最清晰的說明是單一執行緒調用與並行調用之間的差距。 在 ZXing.Net 中,並行處理需要為每個並行操作建立一個完整的讀取器物件:
// ZXing.Net: full reader instantiation and configuration on every parallel task
Parallel.ForEach(files, file =>
{
var reader = new BarcodeReader();
reader.Options.PossibleFormats = new List<BarcodeFormat>
{
BarcodeFormat.QR_CODE,
BarcodeFormat.CODE_128,
BarcodeFormat.EAN_13
};
using var bitmap = new Bitmap(file);
var result = reader.Decode(bitmap);
if (result != null)
processed[file] = result.Text;
});Imports ZXing
Imports System.Drawing
Imports System.Threading.Tasks
Parallel.ForEach(files, Sub(file)
Dim reader As New BarcodeReader()
reader.Options.PossibleFormats = New List(Of BarcodeFormat) From {
BarcodeFormat.QR_CODE,
BarcodeFormat.CODE_128,
BarcodeFormat.EAN_13
}
Using bitmap As New Bitmap(file)
Dim result = reader.Decode(bitmap)
If result IsNot Nothing Then
processed(file) = result.Text
End If
End Using
End Sub)IronBarcode 完全移除了該物件。 無論是在一個執行緒上運行還是在一百個執行緒上運行,靜態調用都是相同的:
// IronBarcode: static call, same code for single-threaded and concurrent use
Parallel.ForEach(files, file =>
{
var result = BarcodeReader.Read(file).FirstOrDefault();
if (result != null)
processed[file] = result.Value;
});Imports IronBarCode
Imports System.Threading.Tasks
Parallel.ForEach(files, Sub(file)
Dim result = BarcodeReader.Read(file).FirstOrDefault()
If result IsNot Nothing Then
processed(file) = result.Value
End If
End Sub)##IronBarcodevs ZXing.Net:功能比較
| 功能 | ZXing.Net | IronBarcode |
|---|---|---|
| 許可 | Apache 2.0(免費) | 商業 |
| 執行緒安全 | 非執行緒安全——每個執行緒需要新實例 | 執行緒安全靜態 API |
| 格式檢測 | 手動——需要PossibleFormats列表 | 自動——50 多種格式 |
| PDF 讀取 | 否——需要 PdfiumViewer 或類似工具 | 原生——單一方法調用 |
| 平台支援 | 每個平台有單獨的綁定包 | 單一包,所有平台 |
| 每張圖像的多個條碼 | 是——DecodeMultiple | 是——預設行為 |
| 條碼生成 | 返回Bitmap,需要手動保存 | 具有內建輸出的簡化 API |
| QR碼標誌支持 | 否 | 是 |
| QR碼顏色控制 | 否 | 是 |
| 損壞的條碼恢復 | TryHarder標誌 | ML 驅動的圖像校正 |
| Docker 額外依賴 | 可能需要libgdiplus | None |
| 商業 SLA 支持 | 否 | 是 |
| 需要的 NuGet 包 | 2-3(核心+綁定+可選ImageSharp) | 1 |
快速開始
步驟1:移除ZXing.Net包
從專案中移除所有ZXing.Net和相關的包:
dotnet remove package ZXing.Net
dotnet remove package ZXing.Net.Bindings.Windows.Compatibility
dotnet remove package ZXing.Net.Bindings.ImageSharp
dotnet remove package PdfiumViewer
如果本地PdfiumViewer二進制文件作為單獨包安裝:
dotnet remove package PdfiumViewer.Native.x64.v8-xfa
如果Dockerfile包含System.Drawing而新增的——則在遷移後可以移除該行。
步驟2:安裝 IronBarcode
dotnet add package IronBarcode
不需要其他綁定包或平台特定的依賴項。 同一 NuGet 包在 Windows、Linux、macOS 和 Docker 容器中運行。 有關部署詳細資訊,IronBarcode Docker 和 Linux 設置指南涵蓋了具體的 Dockerfile 模板。
步驟3:更新命名空間並初始化授權
從每個使用條碼操作的文件中移除所有ZXing相關命名空間:
// Remove all of these:
using ZXing;
using ZXing.Common;
using ZXing.Windows.Compatibility;
using ZXing.ImageSharp;
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.PixelFormats;
using PdfiumViewer;
// Add this single import:
using IronBarCode;Imports IronBarCode在任何條碼操作之前,在應用程式啟動時新增授權初始化:
// Program.cs or Startup.cs — initialise once at startup
IronBarCode.License.LicenseKey = "YOUR-LICENSE-KEY";' Program.vb or Startup.vb — initialise once at startup
IronBarCode.License.LicenseKey = "YOUR-LICENSE-KEY"授權金鑰是一個普通字串,可以從環境變數、appsettings.json 或秘密管理器載入。 沒有要定位的文件,也沒有要配置的路徑。
程式碼遷移範例
從圖像中讀取單個條碼
此範例替換了最常見的ZXing.Net使用模式:實例化一個讀取器,配置格式列表,載入位圖並解碼。
ZXing.Net方法:
using ZXing;
using ZXing.Windows.Compatibility;
using System.Drawing;
public string ReadSingleBarcode(string imagePath)
{
var reader = new BarcodeReader();
reader.Options.PossibleFormats = new List<BarcodeFormat>
{
BarcodeFormat.QR_CODE,
BarcodeFormat.CODE_128,
BarcodeFormat.EAN_13
};
using var bitmap = new Bitmap(imagePath);
var result = reader.Decode(bitmap);
return result?.Text ?? string.Empty;
}Imports ZXing
Imports ZXing.Windows.Compatibility
Imports System.Drawing
Public Function ReadSingleBarcode(imagePath As String) As String
Dim reader = New BarcodeReader()
reader.Options.PossibleFormats = New List(Of BarcodeFormat) From {
BarcodeFormat.QR_CODE,
BarcodeFormat.CODE_128,
BarcodeFormat.EAN_13
}
Using bitmap As New Bitmap(imagePath)
Dim result = reader.Decode(bitmap)
Return If(result?.Text, String.Empty)
End Using
End FunctionIronBarcode 方法:
using IronBarCode;
public string ReadSingleBarcode(string imagePath)
{
var result = BarcodeReader.Read(imagePath).FirstOrDefault();
return result?.Value ?? string.Empty;
}Imports IronBarCode
Public Function ReadSingleBarcode(imagePath As String) As String
Dim result = BarcodeReader.Read(imagePath).FirstOrDefault()
Return If(result?.Value, String.Empty)
End Function格式列表、using塊全部移除。 IronBarcode直接接受文件路徑並自動檢測所有支持的格式。 以前返回解碼字串的屬性在ZXing.Net中是result.Text; 在IronBarcode中是result.Value。
從圖像中讀取所有條碼
此範例代替了DecodeMultiple,在ZXing.Net中需要詳盡的格式列表以避免靜默錯失。
ZXing.Net方法:
using ZXing;
using ZXing.Windows.Compatibility;
using System.Drawing;
public List<string> ReadAllBarcodes(string imagePath)
{
var reader = new BarcodeReader();
reader.Options.PossibleFormats = new List<BarcodeFormat>
{
BarcodeFormat.QR_CODE,
BarcodeFormat.CODE_128,
BarcodeFormat.CODE_39,
BarcodeFormat.EAN_13,
BarcodeFormat.EAN_8,
BarcodeFormat.UPC_A,
BarcodeFormat.DATA_MATRIX,
BarcodeFormat.PDF_417
};
reader.Options.TryHarder = true;
using var bitmap = new Bitmap(imagePath);
var results = reader.DecodeMultiple(bitmap);
return results?.Select(r => r.Text).ToList() ?? new List<string>();
}Imports ZXing
Imports ZXing.Windows.Compatibility
Imports System.Drawing
Public Function ReadAllBarcodes(imagePath As String) As List(Of String)
Dim reader = New BarcodeReader()
reader.Options.PossibleFormats = New List(Of BarcodeFormat) From {
BarcodeFormat.QR_CODE,
BarcodeFormat.CODE_128,
BarcodeFormat.CODE_39,
BarcodeFormat.EAN_13,
BarcodeFormat.EAN_8,
BarcodeFormat.UPC_A,
BarcodeFormat.DATA_MATRIX,
BarcodeFormat.PDF_417
}
reader.Options.TryHarder = True
Using bitmap As New Bitmap(imagePath)
Dim results = reader.DecodeMultiple(bitmap)
Return If(results?.Select(Function(r) r.Text).ToList(), New List(Of String)())
End Using
End FunctionIronBarcode 方法:
using IronBarCode;
public List<string> ReadAllBarcodes(string imagePath)
{
return BarcodeReader.Read(imagePath)
.Select(r => r.Value)
.ToList();
}Imports IronBarCode
Public Function ReadAllBarcodes(imagePath As String) As List(Of String)
Return BarcodeReader.Read(imagePath) _
.Select(Function(r) r.Value) _
.ToList()
End FunctionBarcodeReader.Read始終返回集合,從不返回null,消除了對結果的空檢查。 要調整準確性與速度的平衡,請參閱讀取速度選項指南,該指南涵蓋了ReadingSpeed枚舉,而不縮小格式範圍。
並行批處理
此範例最直接地顯示了執行緒安全差異。 ZXing.Net需要每個並行操作每次都建立一個新的讀取器; IronBarcode無論並行度如何,都使用相同的靜態調用。
ZXing.Net方法:
using ZXing;
using ZXing.Windows.Compatibility;
using System.Collections.Concurrent;
using System.Drawing;
public Dictionary<string, string> ProcessBatch(IEnumerable<string> filePaths)
{
var output = new ConcurrentDictionary<string, string>();
Parallel.ForEach(filePaths, new ParallelOptions { MaxDegreeOfParallelism = 4 }, file =>
{
// ZXing.Net is not thread-safe — a new reader is required per parallel operation
var reader = new BarcodeReader();
reader.Options.PossibleFormats = new List<BarcodeFormat>
{
BarcodeFormat.QR_CODE,
BarcodeFormat.CODE_128
};
using var bitmap = new Bitmap(file);
var result = reader.Decode(bitmap);
if (result != null)
output[file] = result.Text;
});
return output.ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
}Imports ZXing
Imports ZXing.Windows.Compatibility
Imports System.Collections.Concurrent
Imports System.Drawing
Public Function ProcessBatch(filePaths As IEnumerable(Of String)) As Dictionary(Of String, String)
Dim output = New ConcurrentDictionary(Of String, String)()
Parallel.ForEach(filePaths, New ParallelOptions With {.MaxDegreeOfParallelism = 4}, Sub(file)
' ZXing.Net is not thread-safe — a new reader is required per parallel operation
Dim reader = New BarcodeReader()
reader.Options.PossibleFormats = New List(Of BarcodeFormat) From {
BarcodeFormat.QR_CODE,
BarcodeFormat.CODE_128
}
Using bitmap As New Bitmap(file)
Dim result = reader.Decode(bitmap)
If result IsNot Nothing Then
output(file) = result.Text
End If
End Using
End Sub)
Return output.ToDictionary(Function(kvp) kvp.Key, Function(kvp) kvp.Value)
End FunctionIronBarcode 方法:
using IronBarCode;
using System.Collections.Concurrent;
public Dictionary<string, string> ProcessBatch(IEnumerable<string> filePaths)
{
var output = new ConcurrentDictionary<string, string>();
var options = new BarcodeReaderOptions { MaxParallelThreads = 4 };
Parallel.ForEach(filePaths, file =>
{
var result = BarcodeReader.Read(file, options).FirstOrDefault();
if (result != null)
output[file] = result.Value;
});
return output.ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
}Imports IronBarCode
Imports System.Collections.Concurrent
Public Function ProcessBatch(filePaths As IEnumerable(Of String)) As Dictionary(Of String, String)
Dim output = New ConcurrentDictionary(Of String, String)()
Dim options = New BarcodeReaderOptions With {.MaxParallelThreads = 4}
Parallel.ForEach(filePaths, Sub(file)
Dim result = BarcodeReader.Read(file, options).FirstOrDefault()
If result IsNot Nothing Then
output(file) = result.Value
End If
End Sub)
Return output.ToDictionary(Function(kvp) kvp.Key, Function(kvp) kvp.Value)
End Function沒有需要保護或隔離的讀取器實例。 要獲取有關異步管道模式和執行緒數配置的資訊,請參閱異步與多執行緒條碼讀取指南。
從PDF中提取條碼
此範例替代了PdfiumViewer渲染迴圈。如果現有整合使用Ghostscript或iText而不是PdfiumViewer,前面部分將在細節上有所不同,但結構上相同:一個頁面枚舉迴圈將位圖餵給ZXing.Net。
ZXing.Net方法:
using ZXing;
using ZXing.Windows.Compatibility;
using PdfiumViewer;
using System.Drawing;
using System.Drawing.Imaging;
public List<string> ExtractBarcodesFromPdf(string pdfPath)
{
var collected = new List<string>();
var reader = new BarcodeReader();
reader.Options.PossibleFormats = new List<BarcodeFormat>
{
BarcodeFormat.QR_CODE,
BarcodeFormat.CODE_128,
BarcodeFormat.PDF_417
};
using var document = PdfDocument.Load(pdfPath);
for (int page = 0; page < document.PageCount; page++)
{
string temp = Path.Combine(Path.GetTempPath(), $"{Guid.NewGuid()}.png");
try
{
using var rendered = document.Render(page, 200, 200, PdfRenderFlags.CorrectFromDpi);
rendered.Save(temp, ImageFormat.Png);
using var bmp = new Bitmap(temp);
var decoded = reader.DecodeMultiple(bmp);
if (decoded != null)
collected.AddRange(decoded.Select(d => d.Text));
}
finally
{
if (File.Exists(temp))
File.Delete(temp);
}
}
return collected;
}Imports ZXing
Imports ZXing.Windows.Compatibility
Imports PdfiumViewer
Imports System.Drawing
Imports System.Drawing.Imaging
Public Function ExtractBarcodesFromPdf(pdfPath As String) As List(Of String)
Dim collected As New List(Of String)()
Dim reader As New BarcodeReader()
reader.Options.PossibleFormats = New List(Of BarcodeFormat) From {
BarcodeFormat.QR_CODE,
BarcodeFormat.CODE_128,
BarcodeFormat.PDF_417
}
Using document = PdfDocument.Load(pdfPath)
For page As Integer = 0 To document.PageCount - 1
Dim temp As String = Path.Combine(Path.GetTempPath(), $"{Guid.NewGuid()}.png")
Try
Using rendered = document.Render(page, 200, 200, PdfRenderFlags.CorrectFromDpi)
rendered.Save(temp, ImageFormat.Png)
Using bmp As New Bitmap(temp)
Dim decoded = reader.DecodeMultiple(bmp)
If decoded IsNot Nothing Then
collected.AddRange(decoded.Select(Function(d) d.Text))
End If
End Using
End Using
Finally
If File.Exists(temp) Then
File.Delete(temp)
End If
End Try
Next
End Using
Return collected
End FunctionIronBarcode 方法:
using IronBarCode;
public List<string> ExtractBarcodesFromPdf(string pdfPath)
{
return BarcodeReader.Read(pdfPath)
.Select(r => r.Value)
.ToList();
}Imports IronBarCode
Public Function ExtractBarcodesFromPdf(pdfPath As String) As List(Of String)
Return BarcodeReader.Read(pdfPath) _
.Select(Function(r) r.Value) _
.ToList()
End FunctionPdfiumViewer依賴項、頁面渲染迴圈、DPI配置、臨時文件建立和清理塊都被刪除。IronBarcode原生讀取PDF中的條碼,自動處理所有頁面。
生成條碼
ZXing.Net寫入器返回一個System.Drawing.Imaging保存。 IronBarcode返回具有內建輸出方法的GeneratedBarcode。
ZXing.Net方法:
using ZXing;
using ZXing.Common;
using ZXing.Windows.Compatibility;
using System.Drawing;
using System.Drawing.Imaging;
public void WriteCode128(string content, string outputPath)
{
var writer = new BarcodeWriter
{
Format = BarcodeFormat.CODE_128,
Options = new EncodingOptions
{
Width = 400,
Height = 120,
Margin = 10
}
};
using var bitmap = writer.Write(content);
bitmap.Save(outputPath, ImageFormat.Png);
}Imports ZXing
Imports ZXing.Common
Imports ZXing.Windows.Compatibility
Imports System.Drawing
Imports System.Drawing.Imaging
Public Sub WriteCode128(content As String, outputPath As String)
Dim writer = New BarcodeWriter With {
.Format = BarcodeFormat.CODE_128,
.Options = New EncodingOptions With {
.Width = 400,
.Height = 120,
.Margin = 10
}
}
Using bitmap = writer.Write(content)
bitmap.Save(outputPath, ImageFormat.Png)
End Using
End SubIronBarcode 方法:
using IronBarCode;
public void WriteCode128(string content, string outputPath)
{
BarcodeWriter.CreateBarcode(content, BarcodeEncoding.Code128)
.ResizeTo(400, 120)
.SaveAsPng(outputPath);
}Imports IronBarCode
Public Sub WriteCode128(content As String, outputPath As String)
BarcodeWriter.CreateBarcode(content, BarcodeEncoding.Code128) _
.ResizeTo(400, 120) _
.SaveAsPng(outputPath)
End Sub如果需要二進制輸出而不是保存到文件,MemoryStream 管道。
ZXing.Net API到IronBarcode映射參考
| ZXing.Net | IronBarcode | 注意事項 |
|---|---|---|
new BarcodeReader() | 靜態——無需實例 | BarcodeReader.Read(...)是一個靜態調用 |
reader.Options.PossibleFormats = new List<BarcodeFormat> { ... } | 不需要 | 自動檢測會覆蓋所有50多種格式 |
reader.Options.TryHarder = true | Speed = ReadingSpeed.Balanced | 通過BarcodeReaderOptions調整準確性 |
reader.Decode(bitmap) | BarcodeReader.Read(imagePath).FirstOrDefault() | 傳遞文件路徑 — 不需要Bitmap建構 |
reader.DecodeMultiple(bitmap) | BarcodeReader.Read(imagePath) | 始終返回一個集合; never null |
result.Text | result.Value | 屬性已重命名 |
result.BarcodeFormat | result.Format | 屬性已重命名 |
BarcodeFormat.QR_CODE | BarcodeEncoding.QRCode | 枚舉命名規範變更 |
BarcodeFormat.CODE_128 | BarcodeEncoding.Code128 | 枚舉命名規範變更 |
BarcodeFormat.EAN_13 | BarcodeEncoding.EAN13 | 枚舉命名規範變更 |
BarcodeFormat.DATA_MATRIX | BarcodeEncoding.DataMatrix | 枚舉命名規範變更 |
BarcodeFormat.PDF_417 | BarcodeEncoding.PDF417 | 枚舉命名規範變更 |
new BarcodeWriter { Format = ..., Options = new EncodingOptions { ... } } | BarcodeWriter.CreateBarcode(data, encoding) | 靜態工廠,無選項物件 |
Bitmap | .SaveAsPng(path) / .ToPngBinaryData() | 內建輸出於GeneratedBarcode |
EncodingOptions { Width, Height } | .ResizeTo(width, height) | 流暢尺寸調整方法 |
| 無PDF支援 | BarcodeReader.Read("file.pdf") | 原生PDF支持,所有頁面 |
常見遷移問題及解決方案
問題1:BarcodeReader實例化模式
ZXing.Net: 呼叫者建立result.Text。
解決方案: 完全移除實例化。 用靜態調用替換整個模式:
// Before: reader creation + format config + bitmap + decode + result.Text
// After:
var result = BarcodeReader.Read(imagePath).FirstOrDefault();
var value = result?.Value ?? string.Empty;' Before: reader creation + format config + bitmap + decode + result.Text
' After:
Dim result = BarcodeReader.Read(imagePath).FirstOrDefault()
Dim value = If(result?.Value, String.Empty)在程式碼庫中搜索new BarcodeReader()以找到每個實例。 每一個都被刪除,而不是重構。
問題2:PossibleFormats塊移除
ZXing.Net: 每次解碼調用之前都會有reader.Options.PossibleFormats = new List<BarcodeFormat> { ... }指派。 這些列表通常很長且專案特定。
解決方案: 刪除每個PossibleFormats指定塊的全部。 IronBarcode執行自動格式檢測; 不接受或需要格式列表。 如果BarcodeReaderOptions物件。
問題3:綁定包清理
ZXing.Net: 使用System.Drawing.Bitmap為輸入型別。 使用SixLabors.ImageSharp.Image<Rgba32>。 移除綁定包後,這兩種模式均會中斷。
解決方案: 刪除兩個綁定包並替換所有圖像載入程式碼。 IronBarcode的Image<t>建構。 剩下的Bitmap載入而存在的部分也可以移除。
問題4:result.Text到result.Value
ZXing.Net: 解碼條碼值透過result.Text存取。 條碼格式透過result.BarcodeFormat存取。
解決方案: 替換result.Format。 這兩個更改都是簡單的屬性重命名,沒有行為差別。
ZXing.Net 遷移清單
遷移前任務
在進行變更之前,審查程式碼庫以找到所有ZXing.Net引用:
grep -r "using ZXing" --include="*.cs" .
grep -r "new BarcodeReader" --include="*.cs" .
grep -r "PossibleFormats" --include="*.cs" .
grep -r "BarcodeFormat\." --include="*.cs" .
grep -r "reader\.Decode\|reader\.DecodeMultiple" --include="*.cs" .
grep -r "result\.Text\|result\.BarcodeFormat" --include="*.cs" .
grep -r "new BarcodeWriter\|writer\.Write\|EncodingOptions" --include="*.cs" .
grep -r "PdfiumViewer\|PdfDocument\.Load" --include="*.cs" .
grep -r "using System\.Drawing" --include="*.cs" .
文件中引用ZXing綁定包的文件(Windows與ImageSharp)中記錄,並註明System.Drawing.Bitmap僅用於ZXing輸入的地方。 審核Dockerfile(如果存在)以確保libgdiplus安裝。
程式碼更新任務
- 移除
PdfiumViewerNuGet包 - 安裝
IronBarcodeNuGet包 - 向應用程式啟動中新增
IronBarCode.License.LicenseKey = "YOUR-LICENSE-KEY"; - 用
using SixLabors.ImageSharp</em>匯入 - 移除每個
new BarcodeReader()實例 - 刪除每個
reader.Options.PossibleFormats = ...塊 - 用
reader.Decode(bitmap) - 用
reader.DecodeMultiple(bitmap) - 用
result.Text - 用
result.BarcodeFormat - 更新
BarcodeEncoding.X等效 - Replace
new BarcodeWriter { Format = ..., Options = new EncodingOptions { ... } }withBarcodeWriter.CreateBarcode(data, encoding).ResizeTo(w, h) - 用
bitmap.Save(...) - 移除所有僅為ZXing.Net位圖載入而存在的
using System.Drawing;匯入 - 移除任何被實施為PDF替代方法的PdfiumViewer頁面渲染迴圈
- 如果它被新增以支持Linux上的
libgdiplus
遷移後測試
- 驗證應用程式先前配置為檢測的每個條碼格式是否成功找到
- 測試包含先前從
PossibleFormats列表中排除掉的條碼格式的圖像,以確認自動檢測能檢出它們 - 在負載下運行並行處理路徑,並確認沒有競賽條件或空結果
- 如果應用程式通過PdfiumViewer處理PDF,提供相同的PDF輸入並確認條碼值一致
- 確認生成的條碼(Code 128、QR 碼等)是否生成了正確的輸出格式和尺寸
- 在Linux或Docker部署中,確認圖像讀取和PDF讀取是否在沒有
libgdiplus的情況下工作 - 運行完整測試套件並將其輸出與遷移前的基準進行比較
遷移到IronBarcode的主要優勢
消除的執行緒安全負擔: IronBarcode的靜態API完全移除了每執行緒實例模式。 無需實例化讀取器,無需為每個執行緒配置格式列表,無需管理ThreadLocal池。 相同的調用在單執行緒和高併發環境中均正確,併發正確性由庫提供,而不是委派給每個呼叫者。
自動格式檢測: 移除PossibleFormats列表,消除了開發過程中未預見到條碼格式時可能出現的靜默錯失故障。 處理來自外部合作夥伴文件的應用程,或者在不斷演變的條碼標準中運作的應用程式,不再需要進行格式列表維護以保持可靠性。
原生PDF處理: PdfiumViewer渲染迴圈——其頁面枚舉、DPI配置、臨時文件生命周期和清理程式碼——完全被移除。 以前需要兩個函式庫(ZXing.Net 和 PDF 渲染器)才能處理PDF條碼的應用程式現在只需要一個。 已部署依賴項的減少簡化了構建和部署範圍。
單個跨平台包: Windows 和 Linux 部署之間的綁定包區分已被消除。 相同的BarcodeReader.Read(path)調用在所有目標平台上編譯並表現一致,消除了圖像載入程式碼中的平台條件的需求,簡化了跨平台開發和容器化工作流程。
減少了基礎設施程式碼: 遷移最重要的成果是移除了周圍的基礎設施——位圖載入塊、格式列表、PdfiumViewer渲染迴圈、ThreadLocal池——這些都在ZXing.Net 整合中存在,但不涉及到條碼工作,而是繁滿足函式庫的架構要求。 遷移後剩下的就是條碼邏輯本身。 有關檢測率和掃描場景的其他背景,ZXing.Net對比IronBarcode 掃描器比較提供了更廣泛的分析。

Curtis Chau擁有Carleton大學的電腦科學學士學位,專精於前端開發,擁有Node.js、TypeScript、JavaScript和React的專業知識。Curtis熱衷於建立直觀且美觀的使用者介面,喜愛使用現代框架並建立結構良好、視覺吸引力的手冊。