如何在ZXing中為C#開發人員掃描條碼
Accusoft BarcodeXpress與IronBarcode:授權、吞吐量和API取捨
當您透過試用版評估條碼程式庫時,您希望看到它能否在您的圖像上正常運行,然後再決定是否購買。 Accusoft BarcodeXpress沒有給您這個選擇。 在評估模式下,解碼的條碼值會印上字串" UNLICENSED accusoft.com ",生成的2D條碼也會有相同的標記。您可以驗證程式庫找到條碼,但是無法驗證它是否正確讀取條碼。 這是一種在驗證之前先做出承諾的情況,而且在您查看定價之前,這是一個意義重大的摩擦點。
理解Accusoft BarcodeXpress
Accusoft 已經在企業環境中構建文件成像軟體數十年。 BarcodeXpress是包含PrizmDoc、ImageGear和Accusoft Imaging的更廣泛產品家族的一部分。 已經使用這些產品的團隊將遇到熟悉的API介面,並且可以依靠現有的Accusoft帳戶關係。對於獨立的條碼使用而言,這種背景提供的價值較低。
核心SDK可以作為.NET Core的NuGet包獲得。 API是基於實例的——您建立一個writer物件進行實際操作。 雙鑰授權系統使BarcodeXpress與大多數替代品區分開來。
BarcodeXpress的關鍵架構特徵:
- 基於實例的API: 每個操作都需要一個
BarcodeXpress實例; 靜態便捷方法不是設計的一部分 - 兩層授權: SDK授權(
SetSolutionName+SetOEMLicenseKey)是需要分開購買的系統 - 評估模式標記: 在評估模式下,解碼的值會印上
" UNLICENSED accusoft.com "(生成的2D條碼也會印上相同的字串),使得購買前的準確性測試不可能 - 手動格式規範: 讀取器需要明確的
BarcodeTypes配置以列舉要搜尋哪些符號; 未指明的格式不會檢測到 - 40 PPM標準上限: 標準版將處理速度限制為每分鐘40頁,大多數團隊在部署後而非之前會遇到這個限制
- 無原生PDF支援: 在讀取器可以處理之前,PDF文件必須先使用其他程式庫預渲染為圖像
- 至少五個運行時授權: 即使是單伺服器部署也需要至少購買五個運行時授權
兩鑰系統說明
BarcodeXpress將授權分成兩個概念上分開的層次:
// BarcodeXpress: two separate license keys required
using Accusoft.BarcodeXpressSdk;
// Constructor takes the path to the runtime files (e.g. ".").
var barcodeXpress = new BarcodeXpress(".");
// Step 1: SDK license (for development).
// SetSolutionName and SetSolutionKey are methods, not properties.
// SetSolutionKey takes four 32-bit integers (not a parsed long).
barcodeXpress.Licensing.SetSolutionName("YourCompanyName");
barcodeXpress.Licensing.SetSolutionKey(1, 2, 3, 4);
// Step 2: OEM/runtime license (for production — minimum 5 purchased).
try
{
barcodeXpress.Licensing.SetOEMLicenseKey("YourOEMLicenseString");
}
catch (Exception ex)
{
// Without a valid OEM license, the SDK runs in stamped evaluation mode.
Console.WriteLine($"OEM license activation failed: {ex.Message}");
}
// BarcodeXpress: two separate license keys required
using Accusoft.BarcodeXpressSdk;
// Constructor takes the path to the runtime files (e.g. ".").
var barcodeXpress = new BarcodeXpress(".");
// Step 1: SDK license (for development).
// SetSolutionName and SetSolutionKey are methods, not properties.
// SetSolutionKey takes four 32-bit integers (not a parsed long).
barcodeXpress.Licensing.SetSolutionName("YourCompanyName");
barcodeXpress.Licensing.SetSolutionKey(1, 2, 3, 4);
// Step 2: OEM/runtime license (for production — minimum 5 purchased).
try
{
barcodeXpress.Licensing.SetOEMLicenseKey("YourOEMLicenseString");
}
catch (Exception ex)
{
// Without a valid OEM license, the SDK runs in stamped evaluation mode.
Console.WriteLine($"OEM license activation failed: {ex.Message}");
}
Imports Accusoft.BarcodeXpressSdk
' BarcodeXpress: two separate license keys required
' Constructor takes the path to the runtime files (e.g. ".").
Dim barcodeXpress As New BarcodeXpress(".")
' Step 1: SDK license (for development).
' SetSolutionName and SetSolutionKey are methods, not properties.
' SetSolutionKey takes four 32-bit integers (not a parsed long).
barcodeXpress.Licensing.SetSolutionName("YourCompanyName")
barcodeXpress.Licensing.SetSolutionKey(1, 2, 3, 4)
' Step 2: OEM/runtime license (for production — minimum 5 purchased).
Try
barcodeXpress.Licensing.SetOEMLicenseKey("YourOEMLicenseString")
Catch ex As Exception
' Without a valid OEM license, the SDK runs in stamped evaluation mode.
Console.WriteLine($"OEM license activation failed: {ex.Message}")
End Try
SetSolutionKey組合啟動SDK本身。 SetOEMLicenseKey調用啟動生產部署功能。 兩者都必須存在並有效,生產部署才能返回沒有" UNLICENSED accusoft.com "標記的條碼值。
在程式碼審查中,這種模式會產生一個可預測的問題:"為什麼我們有兩個單獨的授權啟動?"答案是—Accusoft將SDK授權和部署授權視為不同的產品,具有不同的計費—從API本身並不總是明顯可見的。 在初始設置的六個月後,維護此程式碼的團隊通常需要追溯到文件以了解每個鑰匙是哪個。
沒有有效的OEM授權,SetOEMLicenseKey會引發錯誤,SDK會回退到評估模式。 團隊通常在try/catch中包裝啟動,以確保失敗能夠響亮地記錄,而不是靜默地在生產中生成標記的條碼值:
try
{
barcodeXpress.Licensing.SetOEMLicenseKey(oemKey);
}
catch (Exception ex)
{
// In evaluation mode, barcode values are stamped with
// " UNLICENSED accusoft.com " in the output.
throw new InvalidOperationException(
"OEM license activation failed — barcode values will be stamped", ex);
}
try
{
barcodeXpress.Licensing.SetOEMLicenseKey(oemKey);
}
catch (Exception ex)
{
// In evaluation mode, barcode values are stamped with
// " UNLICENSED accusoft.com " in the output.
throw new InvalidOperationException(
"OEM license activation failed — barcode values will be stamped", ex);
}
Try
barcodeXpress.Licensing.SetOEMLicenseKey(oemKey)
Catch ex As Exception
' In evaluation mode, barcode values are stamped with
' " UNLICENSED accusoft.com " in the output.
Throw New InvalidOperationException("OEM license activation failed — barcode values will be stamped", ex)
End Try
當團隊意識到評估模式輸出會靜默地標記結果而不是在解碼時引發錯誤時,這種防範措施是他們新增的模式。
理解IronBarcode
IronBarcode是一個獨立的.NET條碼程式庫,除了其NuGet包外,沒有其他外部依賴。 它通過靜態工廠方法處理生成和讀取,這意味著不需要管理實例生命週期,也沒有分散於應用程式程式碼中的構造函式調用。
單鑰授權模型意味著您在試用模式下測試的內容就是在生產中運行的內容—唯一的差異是在試用期間生成的條碼圖像上的水印。 解碼值總是完整的,這意味著您可以在決定是否購買之前,在您的實際文件上測試讀取準確性。
IronBarcode的關鍵特性:
- 靜態API設計:
BarcodeWriter.CreateBarcode()是無狀態的靜態方法,不需要實例管理 - 單一授權鑰匙:一個鑰匙同時涵蓋開發和生產部署; 沒有單獨的運行時授權層
- 完整試用值:試用模式返回完整的解碼值; 水印僅適用於生成的輸出圖像,而不適用於讀取結果
- 自動格式檢測:IronBarcode自動檢測所有支持格式中的符號型別; 不需要
BarcodeTypes列舉 - 原生PDF支援:
BarcodeReader.Read("document.pdf")直接處理PDF檔案,不需要單獨的渲染步驟 - 無吞吐量上限:處理速度僅受硬體和網路容量的限制,而非軟體施加的上限
- 設計上的執行緒安全:無狀態的靜態方法可以從任何數量的執行緒中同時調用,不需要實例隔離
特性比較
| 特性 | Accusoft BarcodeXpress | IronBarcode |
|---|---|---|
| 授權模型 | SDK授權+單獨的運行時授權 | 單一永久鑰匙 |
| 評估模式行為 | 條碼值印有"未授權accusoft.com" | 返回完整值,水印僅用於生成的輸出 |
| 吞吐量限制(標準版) | 每分鐘40頁 | 無吞吐量限制 |
| PDF支援 | 需要額外的PDF程式庫進行圖像提取 | 原生的—BarcodeReader.Read("doc.pdf") |
| API風格 | 基於實例,冗長的配置 | 靜態工廠方法,流暢的API |
| 執行緒安全 | 需要每個執行緒的實例 | 無狀態的靜態方法—天生執行緒安全 |
| 價格入門點 | $1,960+ SDK + $2,500+ 運行時(至少5個) | $749 永久(Lite,1名開發者) |
詳細特性比較
| 特性 | Accusoft BarcodeXpress | IronBarcode |
|---|---|---|
| 授權 | ||
| 授權模型 | SDK鑰匙+運行時鑰匙 | 單一永久鑰匙 |
| 最少運行時授權 | 5(即使是一台伺服器) | 沒有運行時授權概念 |
| 評估模式 | 值印有"未授權accusoft.com" | 完整值,水印僅在輸出圖像上 |
| 永久授權 | 非標準—聯繫銷售部門 | 是,所有層級 |
| 年度續約 | 需要支援 | 可選 |
| 讀取 | ||
| 格式自動檢測 | 手動—必須指定條碼型別 | 自動涵蓋所有支持格式 |
| PDF讀取 | 需要額外的PDF程式庫 | 原生的 |
| 每個圖像多條碼 | 是,需要BarcodeTypes配置 |
是,具有ExpectMultipleBarcodes選項 |
| 結果屬性 | BarcodeValue, BarcodeType |
Value, Format, Confidence, PageNumber |
| 吞吐量限制 | 40 PPM (標準版) | 任何層級均無限制 |
| 生成 | ||
| 128碼生成 | 是,透過writer.BarcodeType |
是,透過BarcodeWriter.CreateBarcode() |
| QR碼生成 | 是 | 是,透過QRCodeWriter.CreateQrCode() |
| 帶標誌的QR碼 | 需手動進行圖像疊加 | AddBrandLogo("logo.png")內建支持 |
| 輸出格式 | 文件保存 | PNG, JPG, PDF, 二進制資料, 流 |
| 平台和部署 | ||
| .NET Framework | 單獨的傳統SDK | .NET Framework 4.6.2+ |
| .NET Core / .NET 5+ | 是(.NET Core SDK) | .NET Core 3.1+, .NET 5/6/7/8/9 |
| Linux/Docker | 是 | 是—Windows x64/x86,Linux x64,macOS x64/ARM |
| Docker授權配置 | 授權文件或授權伺服器 | 環境變數 |
| CI/CD整合 | 需要SDK和運行時授權 | 一個密鑰 |
| 批量處理 | ||
| 執行緒安全 | 需要每個執行緒的實例 | 無狀態—可以安全地在Parallel.ForEach中使用 |
| 並行批處理 | 需要每個執行緒的實例管理 | 直接支援Parallel.ForEach |
授權架構
BarcodeXpress和IronBarcode在授權複雜性上的差異在於編寫將在生產中運行的初始化程式碼時最為明顯。
BarcodeXpress方法
using Accusoft.BarcodeXpressSdk;
public class BarcodeService
{
private readonly BarcodeXpress _barcodeXpress;
public BarcodeService()
{
_barcodeXpress = new BarcodeXpress(".");
// Layer 1: SDK license
_barcodeXpress.Licensing.SetSolutionName("AcmeCorp");
_barcodeXpress.Licensing.SetSolutionKey(1, 2, 3, 4);
// Layer 2: OEM/runtime license — separate purchase, minimum 5
try
{
_barcodeXpress.Licensing.SetOEMLicenseKey("OEMLicenseString");
}
catch (Exception ex)
{
throw new InvalidOperationException(
"OEM license activation failed — barcode values will be stamped", ex);
}
}
}
using Accusoft.BarcodeXpressSdk;
public class BarcodeService
{
private readonly BarcodeXpress _barcodeXpress;
public BarcodeService()
{
_barcodeXpress = new BarcodeXpress(".");
// Layer 1: SDK license
_barcodeXpress.Licensing.SetSolutionName("AcmeCorp");
_barcodeXpress.Licensing.SetSolutionKey(1, 2, 3, 4);
// Layer 2: OEM/runtime license — separate purchase, minimum 5
try
{
_barcodeXpress.Licensing.SetOEMLicenseKey("OEMLicenseString");
}
catch (Exception ex)
{
throw new InvalidOperationException(
"OEM license activation failed — barcode values will be stamped", ex);
}
}
}
Imports Accusoft.BarcodeXpressSdk
Public Class BarcodeService
Private ReadOnly _barcodeXpress As BarcodeXpress
Public Sub New()
_barcodeXpress = New BarcodeXpress(".")
' Layer 1: SDK license
_barcodeXpress.Licensing.SetSolutionName("AcmeCorp")
_barcodeXpress.Licensing.SetSolutionKey(1, 2, 3, 4)
' Layer 2: OEM/runtime license — separate purchase, minimum 5
Try
_barcodeXpress.Licensing.SetOEMLicenseKey("OEMLicenseString")
Catch ex As Exception
Throw New InvalidOperationException("OEM license activation failed — barcode values will be stamped", ex)
End Try
End Sub
End Class
此構造函式完全用於管理兩個單獨的授權啟動,在任何條碼操作之前。 圍繞SetOEMLicenseKey的try/catch不是可選的—沒有它,服務將在任何OEM密鑰丟失或配置錯誤的環境中靜默返回標記的值。
IronBarcode方法
using IronBarCode;
// In Program.cs or startup configuration
IronBarCode.License.LicenseKey = "YOUR-LICENSE-KEY";
using IronBarCode;
// In Program.cs or startup configuration
IronBarCode.License.LicenseKey = "YOUR-LICENSE-KEY";
Imports IronBarCode
' In Program.vb or startup configuration
IronBarCode.License.LicenseKey = "YOUR-LICENSE-KEY"
這是完整的授權設置。沒有單獨的運行時解鎖,沒有解決方案名稱,沒有兩個參數UnlockRuntime調用。 在Docker中,這成為啟動時讀取的環境變數。在CI/CD流水線中,它是一個密鑰。 在容器編排器中,它是注入到pod中的環境變數。
讀取條碼
條碼讀取揭示了兩個程式庫的配置理念差異—BarcodeXpress需要顯式格式列舉和屬性驅動的設置API,而IronBarcode從單次方法調用中自動檢測所有內容。
BarcodeXpress方法
使用BarcodeXpress讀取需要將圖像載入到Analyze(bitmap)以檢索結果。 SDK無法直接讀取PDF—記錄的輸入格式包括TIFF,JPEG,PNG和BMP:
using Accusoft.BarcodeXpressSdk;
using System.Drawing;
public IEnumerable<string> ReadAllBarcodes(string imagePath)
{
var barcodeXpress = new BarcodeXpress(".");
barcodeXpress.Licensing.SetSolutionName("AcmeCorp");
barcodeXpress.Licensing.SetSolutionKey(1, 2, 3, 4);
barcodeXpress.Licensing.SetOEMLicenseKey("OEMLicenseString");
using var bitmap = new Bitmap(imagePath);
// BarcodeTypes is a System.Array of BarcodeType values (not a [Flags]
// enum). Pass Enum.GetValues to scan for everything, or assign a
// narrower array to restrict the search space.
barcodeXpress.reader.BarcodeTypes = new[]
{
BarcodeType.Code128Barcode,
BarcodeType.DataMatrixBarcode,
BarcodeType.QRCodeBarcode
};
Result[] results = barcodeXpress.reader.Analyze(bitmap);
return results.Select(r => r.BarcodeValue);
}
using Accusoft.BarcodeXpressSdk;
using System.Drawing;
public IEnumerable<string> ReadAllBarcodes(string imagePath)
{
var barcodeXpress = new BarcodeXpress(".");
barcodeXpress.Licensing.SetSolutionName("AcmeCorp");
barcodeXpress.Licensing.SetSolutionKey(1, 2, 3, 4);
barcodeXpress.Licensing.SetOEMLicenseKey("OEMLicenseString");
using var bitmap = new Bitmap(imagePath);
// BarcodeTypes is a System.Array of BarcodeType values (not a [Flags]
// enum). Pass Enum.GetValues to scan for everything, or assign a
// narrower array to restrict the search space.
barcodeXpress.reader.BarcodeTypes = new[]
{
BarcodeType.Code128Barcode,
BarcodeType.DataMatrixBarcode,
BarcodeType.QRCodeBarcode
};
Result[] results = barcodeXpress.reader.Analyze(bitmap);
return results.Select(r => r.BarcodeValue);
}
Imports Accusoft.BarcodeXpressSdk
Imports System.Drawing
Public Function ReadAllBarcodes(imagePath As String) As IEnumerable(Of String)
Dim barcodeXpress = New BarcodeXpress(".")
barcodeXpress.Licensing.SetSolutionName("AcmeCorp")
barcodeXpress.Licensing.SetSolutionKey(1, 2, 3, 4)
barcodeXpress.Licensing.SetOEMLicenseKey("OEMLicenseString")
Using bitmap As New Bitmap(imagePath)
' BarcodeTypes is a System.Array of BarcodeType values (not a [Flags]
' enum). Pass Enum.GetValues to scan for everything, or assign a
' narrower array to restrict the search space.
barcodeXpress.Reader.BarcodeTypes = New BarcodeType() {
BarcodeType.Code128Barcode,
BarcodeType.DataMatrixBarcode,
BarcodeType.QRCodeBarcode
}
Dim results As Result() = barcodeXpress.Reader.Analyze(bitmap)
Return results.Select(Function(r) r.BarcodeValue)
End Using
End Function
Result[]。 如果文件包含BarcodeTypes陣列中不存在的格式,將無法找到。 當文件來源更改時,這會成為維護成本。 PDF需要預先轉換為圖像,然後才能將其送入Analyze。
IronBarcode方法
using IronBarCode;
public IEnumerable<string> ReadAllBarcodes(string imagePath)
{
var results = BarcodeReader.Read(imagePath);
return results.Select(r => r.Value);
}
using IronBarCode;
public IEnumerable<string> ReadAllBarcodes(string imagePath)
{
var results = BarcodeReader.Read(imagePath);
return results.Select(r => r.Value);
}
Imports IronBarCode
Public Function ReadAllBarcodes(imagePath As String) As IEnumerable(Of String)
Dim results = BarcodeReader.Read(imagePath)
Return results.Select(Function(r) r.Value)
End Function
IronBarcode自動檢測所有支持的符號格式。 如果圖像包含Code 128,QR碼和DataMatrix,則在不進行任何配置更改的情況下,這三者將全部回傳到結果集中。 為了更好地控制讀取行為,BarcodeReaderOptions類公開速度、執行緒數和多條碼設置。
原生PDF讀取也可以通過相同的方法使用:
using IronBarCode;
//原生的PDF support — no separate library needed
var results = BarcodeReader.Read("invoice-batch.pdf");
foreach (var result in results)
{
Console.WriteLine($"Page {result.PageNumber}: [{result.Format}] {result.Value}");
}
using IronBarCode;
//原生的PDF support — no separate library needed
var results = BarcodeReader.Read("invoice-batch.pdf");
foreach (var result in results)
{
Console.WriteLine($"Page {result.PageNumber}: [{result.Format}] {result.Value}");
}
Imports IronBarCode
'原生的PDF support — no separate library needed
Dim results = BarcodeReader.Read("invoice-batch.pdf")
For Each result In results
Console.WriteLine($"Page {result.PageNumber}: [{result.Format}] {result.Value}")
Next
BarcodeXpress無法原生讀取PDF。 您需要預先使用其他程式庫將每頁渲染為圖像,然後將這些圖像傳遞給BarcodeXpress讀取器。 這增加了一個依賴,增加了一個轉換步驟,並根據所選的PDF程式庫增加了另外的授權成本。
批量處理和執行緒安全
高容量條碼處理揭示了BarcodeXpress的有狀態實例模型和IronBarcode的無狀態靜態API之間的架構差異。
BarcodeXpress方法
BarcodeXpress是基於實例的,其reader物件是有狀態的。 並行處理需要每個執行緒一個實例,並在每個執行緒上下文中重複完整的兩層許可初始化:
using Accusoft.BarcodeXpressSdk;
using System.Collections.Generic;
using System.Drawing;
public Dictionary<string, string> ProcessBatch(IEnumerable<string> imagePaths)
{
var results = new Dictionary<string, string>();
foreach (var path in imagePaths)
{
using var bitmap = new Bitmap(path);
_barcodeXpress.reader.BarcodeTypes = new[]
{
BarcodeType.Code128Barcode,
BarcodeType.QRCodeBarcode
};
var barcodes = _barcodeXpress.reader.Analyze(bitmap);
if (barcodes.Length > 0)
results[path] = barcodes[0].BarcodeValue;
}
return results;
}
using Accusoft.BarcodeXpressSdk;
using System.Collections.Generic;
using System.Drawing;
public Dictionary<string, string> ProcessBatch(IEnumerable<string> imagePaths)
{
var results = new Dictionary<string, string>();
foreach (var path in imagePaths)
{
using var bitmap = new Bitmap(path);
_barcodeXpress.reader.BarcodeTypes = new[]
{
BarcodeType.Code128Barcode,
BarcodeType.QRCodeBarcode
};
var barcodes = _barcodeXpress.reader.Analyze(bitmap);
if (barcodes.Length > 0)
results[path] = barcodes[0].BarcodeValue;
}
return results;
}
Imports Accusoft.BarcodeXpressSdk
Imports System.Collections.Generic
Imports System.Drawing
Public Function ProcessBatch(imagePaths As IEnumerable(Of String)) As Dictionary(Of String, String)
Dim results As New Dictionary(Of String, String)()
For Each path In imagePaths
Using bitmap As New Bitmap(path)
_barcodeXpress.reader.BarcodeTypes = New BarcodeType() {
BarcodeType.Code128Barcode,
BarcodeType.QRCodeBarcode
}
Dim barcodes = _barcodeXpress.reader.Analyze(bitmap)
If barcodes.Length > 0 Then
results(path) = barcodes(0).BarcodeValue
End If
End Using
Next
Return results
End Function
標準版還強製執行每分鐘40頁的上限。 一批100,000個文件在40 PPM下大約需要41個小時完成。 專業版解除此限制,但每個開發者的費用更高—此外,還需購買已經購買的運行時許可。
IronBarcode方法
using IronBarCode;
using System.Collections.Concurrent;
using System.Threading.Tasks;
//IronBarcode— parallel batch with thread-safe static API
var files = Directory.GetFiles("/incoming/scans", "*.png");
var allResults = new ConcurrentBag<string>();
Parallel.ForEach(files, file =>
{
var r = BarcodeReader.Read(file);
foreach (var barcode in r)
allResults.Add($"{file}: {barcode.Value}");
});
using IronBarCode;
using System.Collections.Concurrent;
using System.Threading.Tasks;
//IronBarcode— parallel batch with thread-safe static API
var files = Directory.GetFiles("/incoming/scans", "*.png");
var allResults = new ConcurrentBag<string>();
Parallel.ForEach(files, file =>
{
var r = BarcodeReader.Read(file);
foreach (var barcode in r)
allResults.Add($"{file}: {barcode.Value}");
});
Imports IronBarCode
Imports System.Collections.Concurrent
Imports System.Threading.Tasks
'IronBarcode— parallel batch with thread-safe static API
Dim files = Directory.GetFiles("/incoming/scans", "*.png")
Dim allResults = New ConcurrentBag(Of String)()
Parallel.ForEach(files, Sub(file)
Dim r = BarcodeReader.Read(file)
For Each barcode In r
allResults.Add($"{file}: {barcode.Value}")
Next
End Sub)
由於IronBarcode的靜態方法是無狀態的,於它們之上的Parallel.ForEach是安全的,不需要實例隔離。 IronBarcode在任何定價層級上都不受吞吐量上限限制。 為了調整讀取性能,BarcodeReaderOptions類提供MaxParallelThreads設置:
using IronBarCode;
var options = new BarcodeReaderOptions
{
Speed = ReadingSpeed.Balanced,
ExpectMultipleBarcodes = true,
MaxParallelThreads = 4
};
var results = BarcodeReader.Read("warehouse-scan.png", options);
using IronBarCode;
var options = new BarcodeReaderOptions
{
Speed = ReadingSpeed.Balanced,
ExpectMultipleBarcodes = true,
MaxParallelThreads = 4
};
var results = BarcodeReader.Read("warehouse-scan.png", options);
Imports IronBarCode
Dim options As New BarcodeReaderOptions With {
.Speed = ReadingSpeed.Balanced,
.ExpectMultipleBarcodes = True,
.MaxParallelThreads = 4
}
Dim results = BarcodeReader.Read("warehouse-scan.png", options)
ReadingSpeed.Balanced是預先設置的。 在條碼清晰的高吞吐量管線中使用ReadingSpeed.Detailed在受損或低對比的圖像中使用。
API對映參考
| Accusoft BarcodeXpress | IronBarcode |
|---|---|
new BarcodeXpress(".") |
靜態方法——不需要實例 |
Licensing.SetSolutionName("...") |
IronBarCode.License.LicenseKey = "YOUR-LICENSE-KEY" |
Licensing.SetSolutionKey(int, int, int, int) |
(removed — not needed) |
Licensing.SetOEMLicenseKey(string) |
(removed — no separate runtime license concept) |
| 圍繞OEM激活的try/catch | (removed — license is always either valid or not) |
reader.Analyze(bitmap) (首先載入System.Drawing.Bitmap) |
BarcodeReader.Read(path) |
reader.BarcodeTypes = new[] { BarcodeType.Code128Barcode, ... } |
(removed — auto-detection handles all formats) |
result.BarcodeValue |
result.Value |
result.BarcodeType |
result.Format |
writer.BarcodeType = BarcodeType.Code128 |
BarcodeWriter.CreateBarcode("data", BarcodeEncoding.Code128) |
writer.BarcodeValue = "data" |
(first argument to CreateBarcode) |
writer.SaveToFile(path) |
.SaveAsPng(path) |
| 40 PPM 標准限制 | 在任何層級都無吞吐量限制 |
| 評估:值印有"未授權accusoft.com" | 試用:完整值,水印僅在輸出圖像上 |
當團隊考慮從Accusoft BarcodeXpress轉向IronBarcode
超越40 PPM 墻的擴展
40頁每分鐘的標準版限制聽起來很慷慨,直到一個業務團隊決定對一年的檔案進行日終批處理。 以這個速率,完成一批100,000個文件大約需要41個小時。 轉向專業版可以解除這個限制,但在每開發者席位費用更高—除了已經購買的運行時授權。 那些在簽署購買訂單後才發現吞吐量上限的團隊通常會發現,移除它的總成本遠遠超過最初預測。
CI/CD 流水管整合授權的複雜性
典型的CI/CD 設置在短暫容器中運行構建。 使用BarcodeXpress時,每個構建環境都需要同時可用的SDK密碼組和運行時解鎖密碼,管理為獨立的秘密。 如果運行時密碼丟失或配置錯誤,構建可能會成功,但整合測試將返回模糊值—這是一種容易在測試管道中錯過的靜默故障模式,如果測試斷言沒有仔細地針對實際條碼內容進行編寫。
空氣隔離和安全部署要求
某些環境—處理患者記錄的醫療系統,政府文件工作流,金融機構的後台處理——不允許授權驗證進行出網路調用。 BarcodeXpress的運行時授權系統涉及Accusoft的授權基礎設施,可能在對出網路有嚴格限制的環境中引起合規問題。 在這些環境中運行的團隊通常會選擇完全在本地進行授權驗證的程式庫。
Docker和容器部署
在Docker中使用BarcodeXpress通常需要將授權文件裝入到容器中的已知路徑,或配置授權伺服器並將容器指向它。 這兩種方法都增加部署複雜性——授權文件需要分發並保持同步,而授權伺服器是需要維護的額外基礎設施。 轉向微服務架構或無伺服器部署模式的團隊發現,配置文件方法無法有效轉換為不可變的容器圖像。
評估準確性要求
需要在購買之前驗證自身文件讀取準確性的團隊會發現BarcodeXpress的評估模式存在根本性的限制。 針對真實世界的文件掃描進行測試——檢查程式庫能否處理低對比條碼,傾斜圖像或多條碼頁面——需要完整的解碼值。 部分遮擋的輸出僅顯示程式庫找到了條碼,而不是它是否正確讀取。
常見的遷移考慮因素
從實例管理到靜態調用
BarcodeXpress要求建立並授權BarcodeXpress實例才能進行任何操作。 IronBarcode的靜態方法不需要實例。 遷移的團隊通常有一個構造函式主要是授權樣板的BarcodeService類——遷移後,該構造函式可以完全移除或簡化為單一授權金鑰分配。
刪除BarcodeTypes枚舉
每一次BarcodeXpress讀取操作都需要BarcodeTypes陣列分配以列舉要搜尋的符號。 IronBarcode預設自動檢測所有支持的格式。 在遷移過程中,所有reader.BarcodeTypes = ...賦值可以刪除而無需替代。 如果出於效能原因需要限制搜尋範圍,BarcodeReaderOptions支持作為顯式選項而不是必需的預設格式過濾。
結果屬性名稱更改
兩個屬性的重命名影響所有結果處理程式碼:result.Format。 整個解決方案中的查找與替換可以處理這兩者。 IronBarcode的結果還公開result.PageNumber,這些在BarcodeXpress中沒有對等物,可以在不更改現有結果處理程式碼的情況下用於其他過濾。
Docker授權配置
BarcodeXpress Docker 部署通常使用掛載的授權配置文件。IronBarcode 使用環境變數。 遷移涉及刪除配置文件的COPY指令並新增單一環境變數分配。 在Kubernetes中,授權金鑰會變成Pod規範中的一個祕密參考,而不是掛載卷。
額外的IronBarcode能力
除了在此比較中涵蓋的核心功能外,IronBarcode還提供BarcodeXpress產品中不包含的功能:
- 帶標誌的QR碼:
QRCodeWriter.CreateQrCode().AddBrandLogo("logo.png")原生嵌入品牌圖像到QR碼中,可配置錯誤更正級別以保持掃描可靠性 - PDF上的條碼蓋章:將條碼直接寫入現有的PDF文件中,而不需要其他PDF程式庫
- 批量導出:在一次調用中處理整個PDF文件並接收每頁結果和頁碼、格式、值和信任分數
.NET相容性和未來準備
IronBarcode支持.NET Framework 4.6.2及更高版本,.NET Core 3.1和.NET 5、6、7、8及9。平台目標包括Windows x64和x86、Linux x64和macOS x64和ARM。 BarcodeXpress for .NET Core與傳統的.NET Framework版本是單獨的SDK—升級其應用程式的目標框架的團隊需要考慮這一點。 IronBarcode的單個包覆蓋所有支持的運行時。 隨著.NET新版本發布會定期更新。
結論
BarcodeXpress和IronBarcode代表了兩個不同的設計理念,用於商業.NET條碼程式庫。 BarcodeXpress將SDK存取和生產部署視為單獨授權的產品,具有單獨的計費、單獨的密鑰系統和單獨的最低購買要求。 IronBarcode將程式庫視為一個產品,提供一個單鑰涵蓋從開發到生產的每個環境。
BarcodeXpress是已經深入Accusoft產品生態系統的團隊的合理選擇—使用PrizmDoc或ImageGear的組織會發現BarcodeXpress的API熟悉,以及其Accusoft帳戶關係對於綜合支援有用。 對這些團隊來說,雙鑰授權系統是一種成熟的運營模式,而不是新的摩擦。 該SDK還適合於文件來源受到良好控制、格式需求穩定的環境,手動BarcodeTypes規範是一種可接受的一次性配置而不是持續的維護。
IronBarcode更適合於部署到容器、CI/CD流水線和雲端環境的團隊,這些環境的授權管理複雜性直接影響運營開銷。 自動檢測模型、靜態API和原生PDF 支援減少了整合程式碼的表面面積,單一鑰匙授權模型簡化了跨開發、測試及生產環境的秘密管理。 對於需要在購買前驗證讀取準確性的團隊而言,完整的試用輸出—水印在生成的圖像上,而不是在讀取結果上—允許真實的購買前基準測試。
在每個層級上的價格差距很顯著。 在單開發者層級上,BarcodeXpress SDK加上最低運行時授權和IronBarcode的Lite級別之間的差距很大。 對於那些將成本差異視為次於Accusoft生態系統整合的團隊而言,BarcodeXpress仍然是一個連貫的選擇。對於那些基於自身優勢評估條碼程式庫的團隊而言,評估模式的限制、雙鑰授權及吞吐量上限的組合使IronBarcode成為更簡單的方案。
常見問題
什麼是Accusoft BarcodeXpress?
Accusoft BarcodeXpress是一個用於在C#應用程式中生成和讀取條碼的.NET條碼程式庫。它是開發者在為.NET專案選擇條碼解決方案時考量的多種替代方案之一。
Accusoft BarcodeXpress和IronBarcode之間的主要區別是什麼?
IronBarcode使用靜態、無狀態API,無需管理實例,而Accusoft BarcodeXpress通常需要在使用前建立和配置實例。IronBarcode還提供原生PDF支持、自動格式檢測,以及在所有環境中的單一授權金鑰。
IronBarcode比Accusoft BarcodeXpress更容易授權嗎?
IronBarcode使用一個覆蓋開發和生產部署的單一授權金鑰。相比於將SDK金鑰與運行時金鑰分開的授權系統,這簡化了CI/CD管道和Docker配置。
IronBarcode 支持Accusoft BarcodeXpress支持的所有條碼格式嗎?
IronBarcode支持超過30種條碼符號,包括QR Code、Code 128、Code 39、DataMatrix、PDF417、Aztec、EAN-13、UPC-A、GS1等。格式自動檢測意味著不需要顯式的格式枚舉。
IronBarcode支持原生PDF條碼讀取嗎?
是的。IronBarcode可以直接從PDF文件中讀取條碼,使用BarcodeReader.Read("document.pdf"),無需單獨的PDF渲染程式庫。每頁結果包括頁碼、條碼格式、值和置信分數。
IronBarcode如何處理批量處理,相較於Accusoft BarcodeXpress?
IronBarcode的靜態方法無狀態且天然執行緒安全,可以直接使用Parallel.ForEach而無需每個執行緒的實例管理。任何價格級別下都沒有吞吐量上限。
IronBarcode支持哪些.NET版本?
IronBarcode支持.NET Framework 4.6.2+、.NET Core 3.1,以及.NET 5、6、7、8和9,單一NuGet包。平台目標包括Windows x64/x86、Linux x64和macOS x64/ARM。
如何在.NET專案中安裝IronBarcode?
通過NuGet安裝IronBarcode:在Package Manager Console中運行 'Install-Package IronBarCode',或在CLI中運行 'dotnet add package IronBarCode'。不需要額外的SDK安裝程式或運行時文件。
我可以在購買前評估IronBarcode嗎?不像Accusoft BarcodeXpress?
可以。IronBarcode的試用模式返回完整解碼的條碼值——只有生成的輸出圖像上有水印。您可以在自己的文件上評估讀取準確性,然後再決定購買。
Accusoft BarcodeXpress和IronBarcode的價格差異是多少?
IronBarcode起價為$749,為單開發者所適用的永久授權,覆蓋開發和生產。價格詳情和批量選項可在IronBarcode授權頁面獲得。無需單獨的運行時授權。
從Accusoft BarcodeXpress遷移到IronBarcode容易嗎?
從Accusoft BarcodeXpress遷移到IronBarcode主要涉及用IronBarcode的靜態方法替換基於實例的API調用,去除授權樣板,並更新結果屬性名稱。大多數遷移涉及減少程式碼而不是增加。
IronBarcode可以生成帶有Logo的QR碼嗎?
可以。QRCodeWriter.CreateQrCode().AddBrandLogo("logo.png") 可以原生嵌入品牌圖像進QR碼,並可配置錯誤更正。也支持通過ChangeBarCodeColor() 生成彩色QR碼。

