Jak skanować kody kreskowe w ZXing dla deweloperów C#
Accusoft BarcodeXpressvs IronBarcode: Licencjonowanie, przepustowość i kompromisy API
Oceniając bibliotekę kodów kreskowych na podstawie wersji próbnej, oczekujesz, że przed podjęciem decyzji o zakupie sprawdzisz, czy faktycznie działa ona na Twoich obrazach.Accusoft BarcodeXpressnie oferuje takiej opcji. W trybie oceny, zdekodowane wartosci kodu kreskowego sa oznaczone lancuchem " UNLICENSED accusoft.com ", a wygenerowane 2D kody kreskowe posiadaja ten sam stempel. Mozna zweryfikowac, ze biblioteka odnajduje kod kreskowy, ale nie mozna sprawdzic, czy odczytuje go poprawnie. Jest to sytuacja typu "najpierw zatwierdź, potem sprawdź" i stanowi to istotny punkt tarcia, zanim jeszcze przyjrzysz się cenom.
Zrozumienie Accusoft BarcodeXpress
Accusoft od dziesięcioleci tworzy oprogramowanie do przetwarzania obrazów dokumentów dla środowisk Enterprise. BarcodeXpress jest częścią szerszej rodziny produktów, która obejmuje PrizmDoc, ImageGear i Accusoft Imaging. Zespoły już korzystające z tych produktów mają do czynienia ze znanym interfejsem API i mogą polegać na istniejących relacjach z Accusoft. W przypadku samodzielnego wykorzystania kodów kreskowych kontekst ten ma mniejszą wartość.
Podstawowy zestaw SDK jest dostępny jako pakiet NuGet dla .NET Core. API jest oparte na instancji — tworzysz obiekt BarcodeXpress, konfigurujesz wlasciwosc Licensing, a nastepnie uzywasz dzieci reader i writer do faktycznych operacji. System licencji z podwójnym kluczem odróżnia BarcodeXpress od większości alternatywnych rozwiązań.
Kluczowe cechy architektury BarcodeXpress:
- API oparte na instancji: Kazda operacja wymaga instancji
BarcodeXpress; statyczne metody wygodne nie są częścią projektu - Licencjonowanie dwuwarstwowe: licencjonowanie SDK (
SetSolutionName+SetSolutionKey) i licencjonowanie OEM/uruchomienie (SetOEMLicenseKey) to oddzielne systemy wymagajace oddzielnych zakupow - Stemplowanie trybu oceny: w trybie oceny zdekodowane wartosci sa oznaczane
" UNLICENSED accusoft.com "(i wygenerowane 2D kody kreskowe sa oznaczane tym samym lancuchem), co uniemozliwia testowanie dokladnosci przed zakupem - Reczna specyfikacja formatu: czytnik wymaga wyraznej konfiguracji
BarcodeTypes, aby wyznaczyc, jakich systemow szukac; nieokreślone formaty nie są wykrywane - Standardowy limit 40 stron na minutę: Wersja Standard ogranicza przetwarzanie do 40 stron na minutę, co jest limitem, z którym większość zespołów spotyka się raczej po wdrożeniu niż przed nim
- Brak natywnej obsługi plików PDF: pliki PDF muszą zostać wstępnie przekształcone na obrazy przy użyciu oddzielnej biblioteki, zanim czytnik będzie mógł je przetworzyć
- Co najmniej pięć licencji uruchomieniowych: Nawet wdrożenie na jednym serwerze wymaga zakupu co najmniej pięciu licencji uruchomieniowych
Wyjaśnienie systemu dwóch kluczy
BarcodeXpress dzieli licencjonowanie na dwie koncepcyjnie odrębne warstwy:
// 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
Para SetSolutionKey aktywuje samo SDK. Wywolanie SetOEMLicenseKey aktywuje mozliwosci wdrozenia produkcyjnego. Oba musza byc obecne i wazne, aby wdrozenie produkcyjne zwracalo wartosci kodu kreskowego bez stempla " UNLICENSED accusoft.com ".
Podczas przeglądu kodu ten wzorzec wywołuje przewidywalne pytanie: "Dlaczego mamy dwie oddzielne aktywacje licencji?" Odpowiedź — że Accusoft traktuje licencjonowanie SDK i licencjonowanie wdrożeniowe jako oddzielne produkty z odrębnymi rozliczeniami — nie zawsze jest oczywista z samego API. Zespoły utrzymujące ten kod sześć miesięcy po początkowej konfiguracji często muszą sięgać do dokumentacji, aby zrozumieć, który klucz jest który.
Bez waznej licencji OEM, SetOEMLicenseKey wywoluje w trybie oceny SDK. Zespoły zazwyczaj opakowują aktywację w try/catch, aby niepowodzenie było głośno logowane zamiast cicho produkować oznakowane wartości kodu kreskowego w produkcji:
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
Ta ochrona jest wzorcem, jaki zespoły dodają, gdy zdają sobie sprawę, że wyjście w trybie oceny cicho oznacza wyniki zamiast rzucać wyjątkiem podczas dekodowania.
Zrozumienie IronBarcode
IronBarcode to samodzielna biblioteka IronBarCode.NET, która nie ma żadnych zewnętrznych zależności poza pakietem NuGet. Obsługuje zarówno generowanie, jak i odczyt za pomocą statycznych metod fabrycznych, co oznacza, że nie ma cyklu życia instancji do zarządzania ani wywołań konstruktorów rozrzuconych po kodzie aplikacji.
Model licencji typu "single-key" oznacza, że to, co testujesz w trybie próbnym, działa również w środowisku produkcyjnym — jedyną różnicą jest znak wodny na generowanych obrazach BARCODE podczas okresu próbnego. Wartości zdekodowane są zawsze kompletne, co oznacza, że przed podjęciem decyzji o zakupie można sprawdzić dokładność odczytu na rzeczywistych dokumentach.
Kluczowe cechy IronBarcode:
- Projekt API statycznego:
BarcodeReader.Read()iBarcodeWriter.CreateBarcode()sa bezstanowymi metodami statycznymi — nie wymaga zarzadzania instancjami - Pojedynczy klucz licencyjny: jeden klucz obejmuje zarówno fazę rozwoju, jak i wdrożenie produkcyjne; nie ma osobnej warstwy licencji runtime
- Pełne wartości próbne: Tryb próbny zwraca kompletne, zdekodowane wartości; Znacznik wodny dotyczy wyłącznie wygenerowanych obrazów wyjściowych, a nie wyników odczytu.
- Automatyczne wykrywanie formatu:IronBarcode automatycznie wykrywa symbole we wszystkich obsługiwanych formatach; nie jest potrzebna enumeracja
BarcodeTypes - Natywna obsługa PDF:
BarcodeReader.Read("document.pdf")przetwarza pliki PDF bezposrednio, bez oddzielnego etapu renderowania - Brak ograniczeń przepustowości: Szybkość przetwarzania jest ograniczona jedynie możliwościami sprzętu i sieci, a nie ograniczeniami narzuconymi przez oprogramowanie
- Bezpieczne dla wątków z założenia: bezstanowe metody statyczne mogą być wywoływane jednocześnie z dowolnej liczby wątków bez izolacji instancji
Porównanie funkcji
| Funkcja | Accusoft BarcodeXpress | IronBarcode |
|---|---|---|
| Model licencji | Licencja SDK + oddzielna licencja na środowisko uruchomieniowe | Pojedynczy klucz wieczny |
| Zachowanie trybu oceny | Wartości kodów oznaczone "UNLICENSED accusoft.com " | Zwracane są pełne wartości, znak wodny pojawia się tylko na wygenerowanym wyniku |
| Limit przepustowości (Standard) | 40 stron na minutę | Brak ograniczeń przepustowości |
| Obsługa plików PDF | Wymaga zewnętrznej biblioteki PDF do wyodrębniania obrazów | Nattywny — BarcodeReader.Read("doc.pdf") |
| Styl API | Konfiguracja oparta na instancjach, rozbudowana | Statyczne metody fabryczne, płynny interfejs API |
| Bezpieczeństwo wątków | Wymagana liczba instancji na wątek | Metody statyczne bezstanowe — naturalnie bezpieczne dla wątków |
| Cena początkowa | 1960 USD + SDK + 2500 USD + środowisko uruchomieniowe (min. 5) | 749 USD na zawsze (wersja Lite, 1 programista) |
Szczegółowe porównanie funkcji
| Funkcja | Accusoft BarcodeXpress | IronBarcode |
|---|---|---|
| Licencjonowanie | ||
| Model licencji | Klucz SDK + klucz środowiska uruchomieniowego | Pojedynczy klucz wieczny |
| Minimalne licencje na środowisko uruchomieniowe | 5 (nawet dla 1 serwera) | Brak koncepcji licencji na czas działania |
| Tryb oceny | Wartości oznaczone "UNLICENSED accusoft.com " | Pełne wartości, znak wodny tylko na obrazach wyjściowych |
| Licencja wieczysta | Niestandardowe — skontaktuj się z działem sprzedaży | Tak, wszystkie poziomy |
| Roczne odnowienie | Wymagane do wsparcia | Opcjonalnie |
| Czytanie | ||
| Automatyczne wykrywanie formatu | Podręcznik — należy określić typy BARCODE | Automatyczne dla wszystkich obsługiwanych formatów |
| Odczytywanie plików PDF | Wymagana zewnętrzna biblioteka PDF | Język ojczysty |
| Wiele BarCode na jednym obrazie | Tak, z konfiguracja BarcodeTypes |
Tak, z opcja ExpectMultipleBarcodes |
| Właściwości wyniku | BarcodeValue, BarcodeType |
Value, Format, Confidence, PageNumber |
| Limit przepustowości | 40 PPM (wersja standardowa) | Brak limitów na żadnym poziomie |
| Generacja | ||
| Generowanie kodu 128 | Tak, przez writer.BarcodeType |
Tak, przez BarcodeWriter.CreateBarcode() |
| Generowanie kodów QR | Tak | Tak, przez QRCodeWriter.CreateQrCode() |
| Kod QR z logo | Wymagane ręczne nakładanie obrazów | AddBrandLogo("logo.png") wbudowane |
| Formaty wyjściowe | Zapis pliku | PNG, JPG, PDF, dane binarne, strumień |
| Platforma i wdrożenie | ||
| .NET Framework | Oddzielny starszy zestaw SDK | .NET Framework 4.6.2+ |
| .NET Core / .NET 5+ | Tak (.NET Core SDK) | .NET Core 3.1+, .NET 5/6/7/8/9 |
| Linux/Docker | Tak | Tak — Windows x64/x86, Linux x64, macOS x64/ARM |
| Konfiguracja licencji Docker | Plik licencji lub serwer licencji | Zmienna środowiskowa |
| Integracja CI/CD | Wymagane są zarówno klucze SDK, jak i klucze środowiska uruchomieniowego | Jeden sekret |
| Przetwarzanie wsadowe | ||
| Bezpieczeństwo wątków | Wymagana liczba instancji na wątek | Bezstanowe — bezpieczne dla Parallel.ForEach |
| Partia równoległa | Wymaga zarządzania instancjami na poziomie wątku | Bezpośrednia obsługa Parallel.ForEach |
Architektura licencji
Różnica w złożoności licencji między BarcodeXpress a IronBarcode jest najbardziej widoczna podczas pisania kodu inicjalizacyjnego, który będzie działał w środowisku produkcyjnym.
Podejście 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
Ten konstruktor istnieje w całości, aby zarządzać dwoma oddzielnymi aktywacjami licencji przed wykonaniem jakiejkolwiek operacji na kodzie kreskowym. Try/catch wokol SetOEMLicenseKey nie jest opcjonalne — bez niego usluga bedzie cicho zwracac wartosci oznaczone w kazdym srodowisku, gdzie klucz OEM jest brakujacy lub zle skonfigurowany.
Podejście 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"
To jest pelna konfiguracja licencyjna. Brak oddzielnej odblokowywania w czasie dzialania, brak nazwy rozwiazania, brak wywolania UnlockRuntime z dwoma argumentami. W Dockerze staje się to zmienną środowiskową odczytywaną podczas uruchamiania. W potoku CI/CD jest to jeden sekret. W w orkiestratorze kontenerów jest to jedna zmienna środowiskowa wstrzyknięta do podu.
Odczytywanie BarCodes
Odczyt kodu kreskowego ujawnia różnicę między filozofiami konfiguracji obu bibliotek — BarcodeXpress wymaga jawnego wyliczenia formatów i API konfiguracji opartego na właściwościach, podczas gdy IronBarcode automatycznie wykrywa wszystko na podstawie jednego wywołania metody.
Podejście BarcodeXpress
Odczyt z BarcodeXpress wymaga zaladowania obrazu do System.Drawing.Bitmap, przypisania zestawu symbologii do reader.BarcodeTypes jako System.Array wartosci BarcodeType i wywolania Analyze(bitmap) w celu uzyskania wynikow. SDK nie czyta bezpośrednio plików PDF — dokumentowane formaty wejściowe to TIFF, JPEG, PNG i 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
Analyze przyjmuje Bitmap i zwraca Result[]. Jesli dokument zawiera format nieobecny w tablicy BarcodeTypes, nie zostanie znaleziony. W przypadku zmiany dokumentów źródłowych powoduje to dodatkowe obciążenie związane z utrzymaniem. PDFy wymagaja wstepnego renderowania do obrazow przy uzyciu oddzielnej biblioteki, zanim beda mogly byc przekazane do Analyze.
Podejście 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 automatycznie wykrywa format we wszystkich obsługiwanych symbolikach. Jeśli obraz zawiera kod 128, kod QR i DataMatrix, wszystkie trzy pojawiają się w zbiorze wyników bez żadnych zmian w konfiguracji. Aby zapewnić większą kontrolę nad sposobem odczytu, klasa BarcodeReaderOptions udostępnia ustawienia prędkości, liczby wątków oraz obsługi wielu kodów kreskowych.
Natywne odczytywanie plików PDF jest również dostępne za pomocą tej samej metody:
using IronBarCode;
// Język ojczysty 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;
// Język ojczysty 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
' Język ojczysty 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 nie odczytuje plików PDF w sposób natywny. Najpierw należy renderować każdą stronę do obrazu, używając oddzielnej biblioteki, a następnie przekazać te obrazy do czytnika BarcodeXpress. Powoduje to dodanie zależności, etapu konwersji oraz dodatkowych kosztów licencji w zależności od wybranej biblioteki PDF.
Przetwarzanie wsadowe i bezpieczeństwo wątków
Przetwarzanie dużych ilości kodów kreskowych ujawnia różnicę architektoniczną między modelem instancji z zachowaniem stanu w BarcodeXpress a statycznym API bez zachowania stanu w IronBarcode.
Podejście BarcodeXpress
BarcodeXpress jest oparty na instancji, a jego obiekt reader jest stanowy. Przetwarzanie równoległe wymaga jednej instancji na wątek, przy czym pełna dwuwarstwowa inicjalizacja licencji jest powtarzana w kontekście każdego wątku:
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
Wersja Standard Edition nakłada również ograniczenie do 40 stron na minutę. Przetworzenie partii 100 000 dokumentów przy prędkości 40 stron na minutę zajmuje około 41 godzin. Wersja Professional Edition znosi ten limit, ale wiąże się to z wyższym kosztem na programistę — oprócz już zakupionych licencji na środowisko uruchomieniowe.
Podejście 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)
Poniewaz metody statyczne IronBarcode sa bezstanowe, Parallel.ForEach nad nimi jest bezpieczny, nie wymaga izolacji instancji.IronBarcode nie nakłada żadnych ograniczeń przepustowości w żadnym przedziale cenowym. Do dostrajania wydajnosci odczytu klasa BarcodeReaderOptions oferuje ustawienia ReadingSpeed i 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 jest domyslnym. Uzyj ReadingSpeed.Faster dla wysokowydajnych przeplywow, gdzie kody kreskowe sa czyste, lub ReadingSpeed.Detailed dla uszkodzonych lub niewyraznych obrazow.
Przewodnik po mapowaniu API
| Accusoft BarcodeXpress | IronBarcode |
|---|---|
new BarcodeXpress(".") |
Metody statyczne — nie wymagają instancji |
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) |
| Try/catch wokół aktywacji OEM | (removed — license is always either valid or not) |
reader.Analyze(bitmap) (laduje najpierw 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) |
| Standardowy limit 40 stron na minutę | Brak ograniczeń przepustowości na żadnym poziomie |
| Ocena: wartości oznaczone "UNLICENSED accusoft.com " | Wersja próbna: pełne wartości, znak wodny tylko na obrazach wyjściowych |
Kiedy zespoły rozważają przejście zAccusoft BarcodeXpressna IronBarcode
Przekraczanie bariery 40 stron na minutę
Limit 40 stron na minutę w wersji Standard Edition wydaje się hojny, dopóki zespół biznesowy nie zdecyduje się na przetwarzanie wsadowe na koniec dnia archiwalnych faktur z całego roku. Przetworzenie partii 100 000 dokumentów przy tej szybkości zajmuje około 41 godzin. Przejście na wersję Professional Edition znosi limit, ale wiąże się z wyższym kosztem licencji na stanowisko programisty — oprócz już zakupionych licencji na środowisko uruchomieniowe. Zespoły, które po podpisaniu zamówienia odkrywają ograniczenia przepustowości, często stwierdzają, że całkowity koszt ich usunięcia znacznie przekracza początkowe szacunki.
Złożoność licencji w procesie CI/CD
Typowa konfiguracja CI/CD uruchamia kompilacje w kontenerach efemerycznych. W przypadku BarcodeXpress każde środowisko kompilacji wymaga zarówno pary kluczy SDK, jak i kluczy odblokowujących środowisko uruchomieniowe, zarządzanych jako oddzielne sekrety. Jeśli klucz środowiska uruchomieniowego jest nieobecny lub nieprawidłowo skonfigurowany, kompilacja może zakończyć się powodzeniem, ale testy integracyjne zwrócą niejasne wartości — jest to cichy tryb awarii, który łatwo przeoczyć w potoku testowym, jeśli asercje testowe nie są starannie napisane w odniesieniu do rzeczywistej zawartości kodu kreskowego.
Wymagania dotyczące wdrożenia w środowisku izolowanym i bezpiecznym
Niektóre środowiska — systemy opieki zdrowotnej przetwarzające dokumentację pacjentów, przepływy dokumentów rządowych, przetwarzanie back-office w instytucjach finansowych — nie mogą zezwalać na sprawdzanie licencji poprzez wychodzące połączenia sieciowe. System licencji uruchomieniowych BarcodeXpress wykorzystuje infrastrukturę licencyjną Accusoft, co może stanowić problem zgodności w środowiskach o ścisłych ograniczeniach ruchu wychodzącego z sieci. Zespoły działające w tych środowiskach często wybierają biblioteki, których weryfikacja licencji odbywa się całkowicie lokalnie.
Docker i wdrażanie kontenerów
BarcodeXpress w Dockerze zazwyczaj wymaga zamontowania pliku licencji w kontenerze w znanej ścieżce lub skonfigurowania serwera licencji i skierowania kontenera na niego. Oba podejścia zwiększają złożoność wdrożenia — pliki licencji muszą być dystrybuowane i synchronizowane, a serwer licencji stanowi dodatkowy element infrastruktury, który należy utrzymywać. Zespoły przechodzące na architekturę mikrousług lub wzorce wdrażania bezserwerowego zauważają, że podejście oparte na plikach konfiguracyjnych nie przekłada się w sposób przejrzysty na niezmienne obrazy kontenerów.
Wymagania dotyczące dokładności oceny
Zespoły, które przed podjęciem decyzji o zakupie muszą sprawdzić dokładność odczytu na własnych dokumentach, uważają tryb ewaluacyjny BarcodeXpress za zasadniczo ograniczony. Testowanie na rzeczywistych skanach dokumentów — sprawdzanie, czy biblioteka radzi sobie z kodami kreskowymi o niskim kontraście, przekrzywionymi obrazami lub stronami zawierającymi wiele kodów kreskowych — wymaga kompletnych, zdekodowanych wartości. Częściowo zasłonięty wynik pokazuje jedynie, że biblioteka znalazła BARCODE, a nie to, czy odczytała go poprawnie.
Typowe kwestie związane z migracją
Zarządzanie instancjami do wywołań statycznych
BarcodeXpress wymaga utworzenia i licencjonowania instancji BarcodeXpress przed jakakolwiek operacja. Metody statyczne IronBarcode nie wymagają instancji. Zespoly migrujace maja zazwyczaj klase BarcodeService, ktorej konstruktor jest glownie szablonem licencjonowania — po migracji konstruktor ten mozna zupelnie usunac lub sprowadzic do przypisania pojedynczego klucza licencyjnego.
Usunięcie wyliczenia BarcodeTypes
Kazda operacja odczytu BarcodeXpress wymaga przypisania tablicy BarcodeTypes do wyliczenia, jakich symbologii szukac.IronBarcode domyślnie automatycznie wykrywa wszystkie obsługiwane formaty. Podczas migracji wszystkie przypisania reader.BarcodeTypes = ... mozna usunac bez zastepowania. Jesli istnieje powod wydajnosciowy do ograniczenia przestrzeni wyszukiwania, BarcodeReaderOptions wspiera filtrowanie formatow jako wyrazna opcja, a nie wymagalny domyslny.
Zmiany nazw właściwości wynikowych
Dwie zmiany nazw wlasciwosci wplywaja na caly kod przetwarzajacy wyniki: result.BarcodeValue staje sie result.Value, a result.BarcodeType staje sie result.Format. Funkcja wyszukiwania i zamiany w całym rozwiązaniu pozwala zająć się obiema kwestiami. Wyniki IronBarcode rowniez ujawniaja result.Confidence i result.PageNumber, ktore nie maja odpowiednika w BarcodeXpress i moga byc uzywane do dodatkowego filtrowania bez zmian kodu w istniejacej obsludze wynikow.
Konfiguracja licencji Docker
Wdrożenia BarcodeXpress w Dockerze zazwyczaj wykorzystują zamontowany plik konfiguracyjny licencji.IronBarcode używa zmiennej środowiskowej. Migracja obejmuje usuniecie instrukcji COPY dla pliku konfiguracyjnego i dodanie przypisania pojedynczej zmiennej srodowiskowej. W Kubernetes klucz licencyjny staje się sekretnym odniesieniem w specyfikacji podu, a nie zamontowanym woluminem.
Dodatkowe możliwości IronBarcode
Oprócz podstawowych funkcji omówionych w tym porównaniu,IronBarcode oferuje możliwości, których nie ma w ofercie BarcodeXpress:
- Kod QR z logo:
QRCodeWriter.CreateQrCode().AddBrandLogo("logo.png")osadza obraz marki w kodzie QR w sposob natywny, z konfigurowalnym poziomem korekcji bledow, aby utrzymac niezawodnosc skanowania - Dodawanie kodów kreskowych do plików PDF: Umieszczaj kody kreskowe bezpośrednio w istniejących dokumentach PDF bez konieczności korzystania z oddzielnej biblioteki PDF
- Eksport wsadowy: przetwarzaj całe dokumenty PDF w jednym wywołaniu i otrzymuj wyniki dla poszczególnych stron wraz z numerem strony, formatem, wartością i wskaźnikiem pewności
Zgodność z platformą .NET i gotowość na przyszłość
IronBarcode obsługuje.NET Framework4.6.2 i nowsze wersje, .NET Core 3.1 oraz .NET 5, 6, 7, 8 i 9. Obsługiwane platformy to Windows x64 i x86, Linux x64 oraz macOS x64 i ARM. BarcodeXpress dla .NET Core to oddzielny zestaw SDK od starszej wersji.NET Framework— zespoły aktualizujące framework docelowy swojej aplikacji muszą to uwzględnić. Pojedynczy pakiet IronBarcode obejmuje wszystkie obsługiwane środowiska uruchomieniowe. Regularne aktualizacje śledzą nowe wydania .NET, gdy są publikowane.
Wnioski
BarcodeXpress i IronBarcode reprezentują dwie różne filozofie projektowania komercyjnych bibliotek kodów kreskowych dla platformy .NET. BarcodeXpress traktuje dostęp do SDK i wdrożenie produkcyjne jako odrębne produkty licencyjne z oddzielnym rozliczeniem, oddzielnymi systemami kluczy i oddzielnymi minimalnymi wymaganiami zakupowymi.IronBarcode traktuje bibliotekę jako pojedynczy produkt z jednym kluczem, który obejmuje każde środowisko, od rozwoju po produkcję.
BarcodeXpress to rozsądny wybór dla zespołów już działających w ekosystemie produktów Accusoft — organizacje korzystające z PrizmDoc lub ImageGear uznają API BarcodeXpress za znajome, a swoje konto Accusoft za przydatne do uzyskania skonsolidowanego wsparcia. Dla tych zespołów system licencji oparty na dwóch kluczach jest raczej ugruntowanym wzorcem operacyjnym niż nowym utrudnieniem. SDK pasuje rowniez do srodowisk, gdzie zrodla dokumentow sa dobrze kontrolowane, a wymagania formatu sa stabilne, co czyni reczna specyfikacje BarcodeTypes akceptowalna jednorazowa konfiguracja, a nie ciaglym utrzymaniem.
IronBarcode lepiej nadaje się dla zespołów wdrażających rozwiązania w kontenerach, potokach CI/CD oraz środowiskach chmurowych, gdzie złożoność zarządzania licencjami bezpośrednio wpływa na koszty operacyjne. Model automatycznego wykrywania, statyczny interfejs API oraz natywna obsługa plików PDF zmniejszają powierzchnię kodu integracyjnego, a model licencjonowania oparty na jednym kluczu upraszcza zarządzanie danymi poufnymi w środowiskach programistycznych, testowych i produkcyjnych. Dla zespołów, które przed zakupem muszą ocenić dokładność odczytu, pełna wersja próbna — z znakiem wodnym na wygenerowanych obrazach, a nie na wynikach odczytu — umożliwia prawdziwe porównanie przed zakupem.
Różnica w cenach jest znaczna na każdym poziomie. Na poziomie pojedynczego programisty różnica między pakietem BarcodeXpress SDK Plus wraz z minimalnymi licencjami uruchomieniowymi a poziomem Lite firmy IronBarcode jest znaczna. Dla zespołów, dla których różnica w kosztach ma drugorzędne znaczenie w porównaniu z integracją z ekosystemem Accusoft, BarcodeXpress pozostaje spójnym wyborem. Dla zespołów oceniających biblioteki kodów kreskowych na podstawie ich własnych zalet, połączenie ograniczeń trybu oceny, licencji dwukluczyowej i limitów przepustowości sprawia, że IronBarcode jest bardziej bezpośrednią opcją.
Często Zadawane Pytania
Czym jest Accusoft BarcodeXpress?
Accusoft BarcodeXpress to biblioteka kodów kreskowych .NET służąca do generowania i odczytu kodów kreskowych w aplikacjach C#. Jest to jedna z kilku alternatyw rozważanych przez programistów przy wyborze rozwiązania do obsługi kodów kreskowych w projektach .NET.
Jakie są główne różnice między Accusoft BarcodeXpress a IronBarcode?
IronBarcode wykorzystuje statyczne, bezstanowe API, które nie wymaga zarządzania instancjami, podczas gdy Accusoft BarcodeXpress zazwyczaj wymaga utworzenia i konfiguracji instancji przed użyciem. IronBarcode zapewnia również natywną obsługę plików PDF, automatyczne wykrywanie formatów oraz licencjonowanie za pomocą jednego klucza we wszystkich środowiskach.
Czy licencja na IronBarcode jest łatwiejsza do uzyskania niż na Accusoft BarcodeXpress?
IronBarcode wykorzystuje pojedynczy klucz licencyjny obejmujący zarówno wdrożenia deweloperskie, jak i produkcyjne. Upraszcza to procesy CI/CD oraz konfiguracje Docker w porównaniu z systemami licencyjnymi, które oddzielają klucze SDK od kluczy środowiska uruchomieniowego.
Czy IronBarcode obsługuje wszystkie formaty kodów kreskowych obsługiwane przez Accusoft BarcodeXpress?
IronBarcode obsługuje ponad 30 symboli kodów kreskowych, w tym QR Code, Code 128, Code 39, DataMatrix, PDF417, Aztec, EAN-13, UPC-A, GS1 i wiele innych. Automatyczne wykrywanie formatu oznacza, że nie jest wymagane jawne wyliczanie formatów.
Czy IronBarcode obsługuje natywne odczytywanie kodów kreskowych z plików PDF?
Tak. IronBarcode odczytuje kody kreskowe bezpośrednio z plików PDF za pomocą BarcodeReader.Read("document.pdf") bez konieczności korzystania z oddzielnej biblioteki do renderowania plików PDF. Wyniki dla każdej strony obejmują numer strony, format kodu kreskowego, wartość oraz wskaźnik pewności.
W jaki sposób IronBarcode radzi sobie z przetwarzaniem wsadowym w porównaniu z Accusoft BarcodeXpress?
Metody statyczne IronBarcode są bezstanowe i z natury bezpieczne dla wątków, co umożliwia bezpośrednie użycie Parallel.ForEach bez zarządzania instancjami dla poszczególnych wątków. Nie ma ograniczeń przepustowości w żadnym przedziale cenowym.
Jakie wersje .NET obsługuje IronBarcode?
IronBarcode obsługuje .NET Framework 4.6.2+, .NET Core 3.1 oraz .NET 5, 6, 7, 8 i 9 w jednym pakiecie NuGet. Obsługiwane platformy to Windows x64/x86, Linux x64 oraz macOS x64/ARM.
Jak zainstalować IronBarcode w projekcie .NET?
Zainstaluj IronBarcode za pomocą NuGet: uruchom polecenie „Install-Package IronBarCode” w konsoli menedżera pakietów lub „dotnet add package IronBarCode” w interfejsie CLI. Nie są wymagane żadne dodatkowe instalatory SDK ani pliki uruchomieniowe.
Czy mogę przetestować IronBarcode przed zakupem, w przeciwieństwie do Accusoft BarcodeXpress?
Tak. Tryb próbny IronBarcode zwraca pełne, zdekodowane wartości BarCode — tylko wygenerowane obrazy wyjściowe są opatrzone znakiem wodnym. Przed podjęciem decyzji o zakupie można sprawdzić dokładność odczytu na własnych dokumentach.
Jaka jest różnica w cenie między Accusoft BarcodeXpress a IronBarcode?
Cena IronBarcode zaczyna się od 749 USD za Licencję wieczystą dla jednego programisty, obejmującą etapy rozwoju i produkcji. Szczegóły dotyczące cen i opcji zakupu hurtowego są dostępne na stronie licencyjnej IronBarcode. Nie ma wymogu posiadania oddzielnej licencji na środowisko uruchomieniowe.
Czy migracja z Accusoft BarcodeXpress do IronBarcode jest prosta?
Migracja z Accusoft BarcodeXpress do IronBarcode polega przede wszystkim na zastąpieniu wywołań API opartych na instancjach statycznymi metodami IronBarcode, usunięciu standardowych fragmentów kodu dotyczących licencji oraz aktualizacji nazw właściwości wyników. Większość migracji wiąże się raczej z redukcją kodu niż z jego dodawaniem.
Czy IronBarcode generuje kody QR z logo?
Tak. Funkcja QRCodeWriter.CreateQrCode().AddBrandLogo("logo.png") osadza obraz marki w kodzie QR w sposób natywny z konfigurowalną korekcją błędów. Kolorowe kody QR są również obsługiwane za pomocą funkcji ChangeBarCodeColor().

