Przejdź do treści stopki
PORóWNAJ Z INNYMI KOMPONENTAMI

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
$vbLabelText   $csharpLabel

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
$vbLabelText   $csharpLabel

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() i BarcodeWriter.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
$vbLabelText   $csharpLabel

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"
$vbLabelText   $csharpLabel

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
$vbLabelText   $csharpLabel

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
$vbLabelText   $csharpLabel

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
$vbLabelText   $csharpLabel

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
$vbLabelText   $csharpLabel

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)
$vbLabelText   $csharpLabel

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)
$vbLabelText   $csharpLabel

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ą.

Zwróć uwagęAccusoft jest zarejestrowanym znakiem towarowym swojego odpowiedniego właściciela. "Ta strona nie jest spokrewniona z, zatwierdzona przez, ani sponsorowana przez Accusoft." Wszystkie nazwy produktów, logo i marki są własnością ich odpowiednich właścicieli. Porównania mają charakter wyłącznie informacyjny i odzwierciedlają informacje dostępne publicznie w momencie pisania.

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().

Curtis Chau
Autor tekstów technicznych

Curtis Chau posiada tytuł licencjata z informatyki (Uniwersytet Carleton) i specjalizuje się w front-endowym rozwoju, z ekspertką w Node.js, TypeScript, JavaScript i React. Pasjonuje się tworzeniem intuicyjnych i estetycznie przyjemnych interfejsów użytkownika, Curtis cieszy się pracą z nowoczesnymi frameworkami i tworzeniem dobrze zorganizowanych, atrakcyjnych wizualnie podrę...

Czytaj więcej

Zespół wsparcia Iron

Jesteśmy online 24 godziny, 5 dni w tygodniu.
Czat
E-mail
Zadzwoń do mnie