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

Dynamsoft Barcode Reader vs IronBarcode: Porównanie bibliotek kodów kreskowych C#

Infragistics BarCode vs IronBarcode: Czytnik tylkoWPFvs API niepowiązane z platformą

Odczyt BarCode'ów Infragistics działa w WPF. Do dotarcia tam wymagane są: instancja BarcodeReader, obsługa zdarzeń DecodeComplete, TaskCompletionSource<string> do przekształcenia wywołania zwrotnego w kod asynchroniczny, załadowanie BitmapImage z URI oraz bitowe OR każdej rodziny Symbology, którą chcesz obsługiwać — przekazane jako drugi argument do Decode(). Pominąć rodzinę — powiedzmy, pozostawić Symbology.QRCode poza flagami — a każdy kod kreskowy QR w twoich obrazach zwróci nic. Bez wyjątków. Brak ostrzeżenia. Tylko pusty wynik.

To jest część WPF. Po stronie WinForms, pakiet Infragistics.Win.UltraWinBarcode zawiera kontrolki do generowania, ale nie ma klasy odczytu. Jeśli chcesz odczytać kody kreskowe w projekcie WinForms, w pakiecie kodów kreskowych Infragistics nie ma nic, co można by wywołać. To samo dotyczy każdego kontrolera .NET Core, narzędzia konsolowego, funkcji Azure, komponentuBlazor Serverlub kontenera Docker. Obsługa kodów kreskowych Infragistics istnieje w ramach interfejsu użytkownika:WPFobsługuje generowanie i odczyt oparty na zdarzeniach;WinFormsobejmuje wyłącznie generowanie; wszystko inne zostaje pominięte.

W niniejszym porównaniu przeanalizowano, co ten podział oznacza w praktyce, a następnie przyjrzano się, w jaki sposób IronBarcode radzi sobie z tym samym zadaniem za pomocą jednego statycznego interfejsu API, który działa identycznie w każdym typie projektu.

Zrozumienie obsługi BarCode przez Infragistics

Infragistics jest jednym z najbardziej uznanych dostawców komponentów interfejsu użytkownika .NET. Pakiet Infragistics Ultimate — subskrypcja obejmująca funkcje kodów kreskowych — zawiera setki kontrolek dla WinForms, WPF, ASP.NET, Blazor i urządzeń mobilnych. Dla zespołów już korzystających z tabel, wykresów lub harmonogramów Infragistics kontrolki kodów kreskowych są logicznym dodatkiem: przecież już płacą za subskrypcję.

Obsługa BarCode nie jest jednak ujednoliconą biblioteką. Są to dwa oddzielne zestawy o odrębnych możliwościach, które tylko częściowo się pokrywają.

WinForms: UltraWinBarcode

Pakiet Infragistics.Win.UltraWinBarcode zapewnia generowanie kodów kreskowych w aplikacjachWinFormsza pomocą klasy UltraWinBarcode. Interfejs API jest prosty:

// InfragisticsWinFormsgeneration
using Infragistics.Win.UltraWinBarcode;

var barcode = new UltraWinBarcode();
barcode.Symbology = Symbology.Code128;
barcode.Data = "ITEM-12345";
barcode.SaveTo(outputPath);
// InfragisticsWinFormsgeneration
using Infragistics.Win.UltraWinBarcode;

var barcode = new UltraWinBarcode();
barcode.Symbology = Symbology.Code128;
barcode.Data = "ITEM-12345";
barcode.SaveTo(outputPath);
Imports Infragistics.Win.UltraWinBarcode

Dim barcode As New UltraWinBarcode()
barcode.Symbology = Symbology.Code128
barcode.Data = "ITEM-12345"
barcode.SaveTo(outputPath)
$vbLabelText   $csharpLabel

Ustawiasz symbolikę, przypisujesz dane, wywołujesz SaveTo(). W scenariuszach wyłącznie generacyjnych wWinFormsto działa. Enum Symbology obejmuje popularne formaty: Code128, Code39, QR, EAN13 i inne.

W tym zestawie nie ma czytnika. Nie ma klasy UltraBarcodeReader. Nie ma metody Scan(). Jeśli próbujesz odczytać obraz kodu kreskowego w aplikacjiWinFormsużywając tylko pakietu Infragistics.Win.UltraWinBarcode, nie ma nic do wywołania.

WPF: XamBarcode i BarcodeReader

StronaWPFzawiera zarówno kontrolkę generacji (XamBarcode), jak i oddzielną klasę odczytu (BarcodeReader w Infragistics.Controls.Barcodes, z zestawu Infragistics.WPF.BarcodeReader). Odczyt jest sterowany zdarzeniami i zaprojektowany w oparciu o model wątków i obrazówania WPF.

Odczytanie kodu kreskowego wWPFwymaga podłączenia zdarzenia DecodeComplete, ładowania obrazów jako obiektów BitmapSource zamiast ścieżek plików oraz przekształcenia wzorca wywołań zwrotnych w coś możliwego do wyczekiwania, jeśli twój kod jest asynchroniczny.

ASP.NET Core, Console, Docker: Nic

Nie ma pakietu kodów kreskowych Infragistics, który celuje w net8.0 bez zestawów UIWPFlub WinForms. Projekty ASP.NET Core, narzędzia konsolowe, Azure Functions,Blazor Serveri kontenery Docker w systemie Linux nie mają opcji BarCode Infragistics. Biblioteka jest powiązana z frameworkiem interfejsu użytkownika.

Wzorzec czytania WPF

Oto jak w rzeczywistości wygląda odczyt BarCodes wWPFprzy użyciu Infragistics:

// InfragisticsWPFreading: event-driven, requiresWPFassemblies
using Infragistics.Controls.Barcodes;
using System.Windows.Media.Imaging;

private BarcodeReader _reader;
private TaskCompletionSource<string> _result;

public InfragisticsBarcodeService()
{
    _reader = new BarcodeReader();
    _reader.DecodeComplete += OnDecodeComplete;
}

public async Task<string> ReadBarcodeAsync(string imagePath)
{
    _result = new TaskCompletionSource<string>();

    // Load asWPFBitmapSource — not a file path
    var bitmap = new BitmapImage(new Uri(imagePath, UriKind.Absolute));

    // Build the Symbology flags. The enum is [Flags];
    // EAN-8/EAN-13/UPC-A/UPC-E share a single EanUpc flag,
    // and Code 39 is exposed as Code39Ext. Use Symbology.All
    // to search every supported family.
    var symbologies = Symbology.Code128 |
                      Symbology.Code39Ext |
                      Symbology.QRCode |
                      Symbology.EanUpc |
                      Symbology.Interleaved2Of5;

    // Symbology is the second argument to Decode/DecodeAsync,
    // not a property on the reader. Result comes via callback.
    _reader.DecodeAsync(bitmap, symbologies);

    return await _result.Task;
}

private void OnDecodeComplete(object sender, ReaderDecodeArgs e)
{
    _result?.TrySetResult(e.SymbolFound ? e.Value : "No barcode found");
}

public void Dispose()
{
    if (_reader != null)
    {
        _reader.DecodeComplete -= OnDecodeComplete;
        _reader = null;
    }
}
// InfragisticsWPFreading: event-driven, requiresWPFassemblies
using Infragistics.Controls.Barcodes;
using System.Windows.Media.Imaging;

private BarcodeReader _reader;
private TaskCompletionSource<string> _result;

public InfragisticsBarcodeService()
{
    _reader = new BarcodeReader();
    _reader.DecodeComplete += OnDecodeComplete;
}

public async Task<string> ReadBarcodeAsync(string imagePath)
{
    _result = new TaskCompletionSource<string>();

    // Load asWPFBitmapSource — not a file path
    var bitmap = new BitmapImage(new Uri(imagePath, UriKind.Absolute));

    // Build the Symbology flags. The enum is [Flags];
    // EAN-8/EAN-13/UPC-A/UPC-E share a single EanUpc flag,
    // and Code 39 is exposed as Code39Ext. Use Symbology.All
    // to search every supported family.
    var symbologies = Symbology.Code128 |
                      Symbology.Code39Ext |
                      Symbology.QRCode |
                      Symbology.EanUpc |
                      Symbology.Interleaved2Of5;

    // Symbology is the second argument to Decode/DecodeAsync,
    // not a property on the reader. Result comes via callback.
    _reader.DecodeAsync(bitmap, symbologies);

    return await _result.Task;
}

private void OnDecodeComplete(object sender, ReaderDecodeArgs e)
{
    _result?.TrySetResult(e.SymbolFound ? e.Value : "No barcode found");
}

public void Dispose()
{
    if (_reader != null)
    {
        _reader.DecodeComplete -= OnDecodeComplete;
        _reader = null;
    }
}
Imports Infragistics.Controls.Barcodes
Imports System.Windows.Media.Imaging
Imports System.Threading.Tasks

Private _reader As BarcodeReader
Private _result As TaskCompletionSource(Of String)

Public Sub New()
    _reader = New BarcodeReader()
    AddHandler _reader.DecodeComplete, AddressOf OnDecodeComplete
End Sub

Public Async Function ReadBarcodeAsync(imagePath As String) As Task(Of String)
    _result = New TaskCompletionSource(Of String)()

    ' Load as WPF BitmapSource — not a file path
    Dim bitmap As New BitmapImage(New Uri(imagePath, UriKind.Absolute))

    ' Build the Symbology flags. The enum is [Flags];
    ' EAN-8/EAN-13/UPC-A/UPC-E share a single EanUpc flag,
    ' and Code 39 is exposed as Code39Ext. Use Symbology.All
    ' to search every supported family.
    Dim symbologies = Symbology.Code128 Or
                      Symbology.Code39Ext Or
                      Symbology.QRCode Or
                      Symbology.EanUpc Or
                      Symbology.Interleaved2Of5

    ' Symbology is the second argument to Decode/DecodeAsync,
    ' not a property on the reader. Result comes via callback.
    _reader.DecodeAsync(bitmap, symbologies)

    Return Await _result.Task
End Function

Private Sub OnDecodeComplete(sender As Object, e As ReaderDecodeArgs)
    _result?.TrySetResult(If(e.SymbolFound, e.Value, "No barcode found"))
End Sub

Public Sub Dispose()
    If _reader IsNot Nothing Then
        RemoveHandler _reader.DecodeComplete, AddressOf OnDecodeComplete
        _reader = Nothing
    End If
End Sub
$vbLabelText   $csharpLabel

To około 35 wierszy kodu potrzebnego do odczytania jednego BARCODE'a. Opisz, co faktycznie się dzieje:

  1. Tworzona jest instancja BarcodeReader i przechowywana jako pole.
  2. Obsługa zdarzeń jest podłączona w konstruktorze.
  3. Każde wywołanie ReadBarcodeAsync tworzy nowe TaskCompletionSource<string> przypisane do wspólnego pola — co oznacza, że ten serwis nie jest w swojej obecnej formie bezpieczny dla wielowątkowości. Jednoczesne wywołania nadpisywałyby _result.
  4. Obraz musi być załadowany jako BitmapImage z Uri — nie jako ciąg ścieżki pliku, nie jako tablica bajtów, nie jako strumień.
  5. DecodeAsync() wywołuje zdarzenie asynchronicznie. TaskCompletionSource jest mostem między światem wywołań zwrotnych a światem async/await.
  6. Wywołanie zwrotne wyodrębnia e.Value, gdy e.SymbolFound jest prawdziwe.
  7. Metoda Dispose() musi odłączyć obsługę zdarzeń, aby zapobiec wyciekom pamięci.

Żadna z tych logik nie dotyczy BarCodes. Jest to infrastruktura niezbędna do pracy w oparciu o projektowanie sterowane zdarzeniami. W kodzie w produkcji trzeba także zająć się przypadkiem, gdy _result.Task nigdy się nie zakończy — timeoutem, tokenem anulowania lub jakimś zabezpieczeniem przed nigdy niewystrzelonym zdarzeniem.

Luka w WinForms

Luka wWinFormsjest bardziej wyraźna, niż mogłoby się początkowo wydawać. Zespoły tworzące aplikacjeWinFormsczęsto trafiają na stronę Infragistics poświęconą kodom kreskowym BARCODE, oczekując symetrycznego doświadczenia — generowania i odczytu w obu frameworkach UI. Odkrywają, że Infragistics.Win.UltraWinBarcode nie zapewnia żadnej zdolności odczytu.

Nie jest to przeoczenie w dokumentacji. Zestaw BarCodeWinFormszostał zaprojektowany jako kontrolka generująca. Jeśli chcesz skanować kody kreskowe w aplikacjiWinForms— na przykład odczytywać kod kreskowy z pliku obrazu przesłanego przez użytkownika lub dekodować kod kreskowy z obrazu z kamery — nie możesz tego zrobić za pomocą narzędzi do kodów kreskowych firmy Infragistics. Konieczne byłoby wprowadzenie zupełnie oddzielnej biblioteki, co osłabiłoby uzasadnienie dla wykorzystania Infragistics do generowania.

Asymetria tworzy lukę w pokryciu dla zespołów prowadzących mieszane projekty frameworków. Zespół posiadający zarówno klienta desktopowego WPF, jak i klienta desktopowegoWinFormsnie może używać Infragistics do odczytu kodów BarCode w projekcie WinForms, nawet jeśli używa Infragistics wszędzie indziej.

Specyfikacja symboliki: tryb cichej awarii

Argument flag Symbology do Decode() w czytnikuWPFzasługuje na własną sekcję, ponieważ jego tryb awaryjny jest cichy: brakująca flaga zwraca pusty wynik bez błędu.

Kiedy wywołujesz do czytnika, łączysz operacją OR każdą rodzinę kodów kreskowych, które chcesz przeszukać. Obsługiwane rodziny to QR, EAN/UPC (EanUpc), Code 39 (Code39Ext), Code 128, MaxiCode i Interleaved 2 z 5 — DataMatrix nie znajduje się w enum, więc czytnikWPFnie może go dekodować. Symbology.All obejmuje wszystko w enum:

// Build flags explicitly, or use Symbology.All to search every family
var symbologies = Symbology.Code128 |
                  Symbology.Code39Ext |
                  Symbology.QRCode |
                  Symbology.EanUpc |
                  Symbology.Interleaved2Of5;

_reader.DecodeAsync(bitmap, symbologies);
// Build flags explicitly, or use Symbology.All to search every family
var symbologies = Symbology.Code128 |
                  Symbology.Code39Ext |
                  Symbology.QRCode |
                  Symbology.EanUpc |
                  Symbology.Interleaved2Of5;

_reader.DecodeAsync(bitmap, symbologies);
' Build flags explicitly, or use Symbology.All to search every family
Dim symbologies = Symbology.Code128 Or
                  Symbology.Code39Ext Or
                  Symbology.QRCode Or
                  Symbology.EanUpc Or
                  Symbology.Interleaved2Of5

_reader.DecodeAsync(bitmap, symbologies)
$vbLabelText   $csharpLabel

Jeśli obraz kodu kreskowego zawiera kod QR i Symbology.QRCode nie znajduje się w flagach, e.SymbolFound daje false, a e.Value jest pusty. Zdarzenie decode nadal jest wywoływane. Nie jest zgłaszany żaden wyjątek. Osoba dzwoniąca otrzymuje komunikat "Nie znaleziono kodu BARCODE" i nie ma żadnej wskazówki, czy obraz był nieczytelny, czy po prostu nie został skonfigurowany.

W praktyce oznacza to:

  • Wstępna konfiguracja działa poprawnie w przypadku formatów przetestowanych przez programistę.
  • Do systemu wprowadzany jest nowy format BARCODE (dostawca zmienia rodzaj etykiety, nowa linia produktów wykorzystuje inną symbolikę).
  • Czytnik cicho niepowoduje dla wszystkich obrazów z tą rodziną.
  • Błąd wygląda identycznie jak "obraz nie zawiera BarCODE-a", a nie "format nie został skonfigurowany".

Zespoły debugujące to spędzają czas badając jakość obrazu, zanim zrozumieją, że rodzina nigdy nie była na liście flag. DataMatrix jest ostrzejszym przypadkiem: nie ma flagi do dodania, ponieważ czytnikWPFw ogóle jej nie obsługuje.

IronBarcode nie wymaga argumentu formatu. Automatycznie wykrywa każdy obsługiwany format przy każdym odczycie. Nie ma żadnej flagi, o której można by zapomnieć.

Matryca platform

Różnice w możliwościach poszczególnych platform to najprostszy sposób na zrozumienie ograniczeń architektonicznych:

Platforma Infragistics Generation Infragistics Reading Generowanie kodów kreskowych IronBarcode Odczytywanie kodów kreskowych IronBarcode
WPF Kontrolka XamBarcode BarcodeReader (sterowany zdarzeniami) Tak Tak
WinForms UltraWinBarcode NIE DOSTĘPNE Tak Tak
ASP.NET Core NIE DOSTĘPNE NIE DOSTĘPNE Tak Tak
Konsola NIE DOSTĘPNE NIE DOSTĘPNE Tak Tak
Blazor Server NIE DOSTĘPNE NIE DOSTĘPNE Tak Tak
Docker / Linux NIE DOSTĘPNE NIE DOSTĘPNE Tak Tak
Azure Functions NIE DOSTĘPNE NIE DOSTĘPNE Tak Tak

Ta tabela ilustruje, dlaczego zespoły korzystające z rozwiązań wykraczających poza czyste aplikacje desktopoweWPFuważają obsługę BarCode przez Infragistics za niewystarczającą. W momencie, gdy projekt obejmuje zarówno WinForms, jak iASP.NET Core— lubWPFi usługę działającą w tle — biblioteka kodów kreskowych Infragistics obejmuje tylko część kodu źródłowego.

Zrozumienie IronBarcode

IronBarcode to dedykowana biblioteka kodów kreskowych dla platformy .NET, niezależna od WinForms,WPFi innych frameworków interfejsu użytkownika. Ten sam pakiet NuGet, ta sama przestrzeń nazw i to samo API działają w każdym projekcie .NET: WinForms, WPF, ASP.NET Core, konsola, Blazor Server, Docker, Azure Functions, AWS Lambda.

// IronBarcode: identical code in WinForms, WPF, ASP.NET Core, console, Docker
// NuGet: dotnet add package BarCode
using IronBarCode;

// Read — 2 lines, any platform
var results = BarcodeReader.Read(imagePath);
return results.FirstOrDefault()?.Value ?? "No barcode found";
// IronBarcode: identical code in WinForms, WPF, ASP.NET Core, console, Docker
// NuGet: dotnet add package BarCode
using IronBarCode;

// Read — 2 lines, any platform
var results = BarcodeReader.Read(imagePath);
return results.FirstOrDefault()?.Value ?? "No barcode found";
Imports IronBarCode

' Read — 2 lines, any platform
Dim results = BarcodeReader.Read(imagePath)
Return If(results.FirstOrDefault()?.Value, "No barcode found")
$vbLabelText   $csharpLabel

BarcodeReader.Read() jest metodą statyczną. Nie ma instancji do zarządzania, nie ma zdarzenia do podpięcia, nie ma TaskCompletionSource do połączenia wzorców wywołań zwrotnych. Akceptuje ciąg ścieżki pliku, tablicę bajtów, Stream lub tablicę dowolnych z nich do przetwarzania wsadowego.

Dla generowania BarcodeWriter.CreateBarcode() zwraca obiekt kodu kreskowego, który można zapisać do PNG, JPEG, SVG lub pobrać jako dane binarne:

using IronBarCode;

// Generate Code 128
BarcodeWriter.CreateBarcode("ITEM-12345", BarcodeEncoding.Code128)
             .ResizeTo(400, 100)
             .SaveAsPng("barcode.png");

// Generate QR code
QRCodeWriter.CreateQrCode("https://example.com", 500,
    QRCodeWriter.QrErrorCorrectionLevel.Highest)
    .SaveAsPng("qr.png");
using IronBarCode;

// Generate Code 128
BarcodeWriter.CreateBarcode("ITEM-12345", BarcodeEncoding.Code128)
             .ResizeTo(400, 100)
             .SaveAsPng("barcode.png");

// Generate QR code
QRCodeWriter.CreateQrCode("https://example.com", 500,
    QRCodeWriter.QrErrorCorrectionLevel.Highest)
    .SaveAsPng("qr.png");
Imports IronBarCode

' Generate Code 128
BarcodeWriter.CreateBarcode("ITEM-12345", BarcodeEncoding.Code128) _
             .ResizeTo(400, 100) _
             .SaveAsPng("barcode.png")

' Generate QR code
QRCodeWriter.CreateQrCode("https://example.com", 500, QRCodeWriter.QrErrorCorrectionLevel.Highest) _
    .SaveAsPng("qr.png")
$vbLabelText   $csharpLabel

Inicjalizacja licencji odbywa się przy uruchomieniu aplikacji, jednorazowo:

IronBarCode.License.LicenseKey = "YOUR-LICENSE-KEY";
IronBarCode.License.LicenseKey = "YOUR-LICENSE-KEY";
Imports IronBarCode

IronBarCode.License.LicenseKey = "YOUR-LICENSE-KEY"
$vbLabelText   $csharpLabel

Obok siebie: Przetwarzanie wsadowe

Przetwarzanie wsadowe ujawnia kolejne ograniczenie strukturalne czytnika Infragistics WPF. Ponieważ czytnik używa wspólnej obsługi zdarzeń, a pole _result jest nadpisywane przy każdym wywołaniu, pokazana powyżej klasa serwisowa nie może bezpiecznie przetwarzać wielu obrazów jednocześnie. Należy uporządkować wywołania:

// Infragistics: must process sequentially — shared event handler and TaskCompletionSource
// field mean concurrent calls would overwrite _result before the previous decode completes
var service = new InfragisticsBarcodeService();
var results = new List<string>();

foreach (var file in imageFiles)
{
    // Each call must await before starting the next
    var value = await service.ReadBarcodeAsync(file);
    results.Add(value);
}
// Infragistics: must process sequentially — shared event handler and TaskCompletionSource
// field mean concurrent calls would overwrite _result before the previous decode completes
var service = new InfragisticsBarcodeService();
var results = new List<string>();

foreach (var file in imageFiles)
{
    // Each call must await before starting the next
    var value = await service.ReadBarcodeAsync(file);
    results.Add(value);
}
Imports System.Collections.Generic
Imports System.Threading.Tasks

' Infragistics: must process sequentially — shared event handler and TaskCompletionSource
' field mean concurrent calls would overwrite _result before the previous decode completes
Dim service As New InfragisticsBarcodeService()
Dim results As New List(Of String)()

For Each file In imageFiles
    ' Each call must await before starting the next
    Dim value As String = Await service.ReadBarcodeAsync(file)
    results.Add(value)
Next
$vbLabelText   $csharpLabel

Umożliwienie jednoczesnego działania tego wymaga znaczącej dodatkowej infrastruktury: blokady, kolejki lub semafora, aby zapewnić, że _result nie zostanie nadpisany, gdy poprzednia dekodacja jest jeszcze w toku. Jest to niebanalny problem współbieżności w przypadku operacji wejścia/wyjścia, która powinna być prosta.

Statyczny BarcodeReader.Read()IronBarcode jest bezpieczny dla wątków. Można go wywoływać jednocześnie z wielu wątków bez dodatkowej synchronizacji. Dla obciążeń wsadowych można użyć bezpośrednio Parallel.ForEach:

using IronBarCode;

// IronBarcode: parallel batch with thread-safe static API
var results = new System.Collections.Concurrent.ConcurrentBag<string>();

Parallel.ForEach(imageFiles, file =>
{
    var barcodeResults = BarcodeReader.Read(file);
    foreach (var result in barcodeResults)
    {
        results.Add(result.Value);
    }
});
using IronBarCode;

// IronBarcode: parallel batch with thread-safe static API
var results = new System.Collections.Concurrent.ConcurrentBag<string>();

Parallel.ForEach(imageFiles, file =>
{
    var barcodeResults = BarcodeReader.Read(file);
    foreach (var result in barcodeResults)
    {
        results.Add(result.Value);
    }
});
Imports IronBarCode
Imports System.Collections.Concurrent
Imports System.Threading.Tasks

' IronBarcode: parallel batch with thread-safe static API
Dim results As New ConcurrentBag(Of String)()

Parallel.ForEach(imageFiles, Sub(file)
    Dim barcodeResults = BarcodeReader.Read(file)
    For Each result In barcodeResults
        results.Add(result.Value)
    Next
End Sub)
$vbLabelText   $csharpLabel

Możesz także przekazać wiele plików w pojedynczym wywołaniu i skonfigurować równoległość za pomocą BarcodeReaderOptions:

using IronBarCode;

var options = new BarcodeReaderOptions
{
    Speed = ReadingSpeed.Balanced,
    ExpectMultipleBarcodes = true,
    MaxParallelThreads = 4
};

var results = BarcodeReader.Read(imageFiles, options);
foreach (var result in results)
{
    Console.WriteLine($"{result.Value} ({result.Format})");
}
using IronBarCode;

var options = new BarcodeReaderOptions
{
    Speed = ReadingSpeed.Balanced,
    ExpectMultipleBarcodes = true,
    MaxParallelThreads = 4
};

var results = BarcodeReader.Read(imageFiles, options);
foreach (var result in results)
{
    Console.WriteLine($"{result.Value} ({result.Format})");
}
Imports IronBarCode

Dim options As New BarcodeReaderOptions With {
    .Speed = ReadingSpeed.Balanced,
    .ExpectMultipleBarcodes = True,
    .MaxParallelThreads = 4
}

Dim results = BarcodeReader.Read(imageFiles, options)
For Each result In results
    Console.WriteLine($"{result.Value} ({result.Format})")
Next
$vbLabelText   $csharpLabel

Porównanie funkcji

Funkcja Infragistics BarCode IronBarcode
Odczytywanie BarCodes wWinForms Niedostępne Tak
Odczytywanie BarCode wWPF Tak (sterowane zdarzeniami) Tak (synchroniczne)
ObsługaASP.NET Core Niedostępne Tak
Konsola / Usługa robocza Niedostępne Tak
Docker / Linux Niedostępne Tak
Azure Functions Niedostępne Tak
Blazor Server Niedostępne Tak
Automatyczne wykrywanie formatowania Nie — musisz przekazać flagi Symbology do Decode() Tak — formaty wykrywane automatycznie
Odczytywanie BarCodes z plików PDF Niedostępne Tak — natywne, bez dodatkowego pakietu
Odczyt bezpieczny dla wątków Nie (wspólny moduł obsługi zdarzeń) Tak (statyczne API)
Wymagane API sterowane zdarzeniami Tak (WPF) Nie
Wyraźne ładowanie obrazu (BitmapSource) Tak Nie — akceptuje ścieżkę do pliku, bajty, strumień
Czytanie synchroniczne Nie (należy połączyć za pomocą TaskCompletionSource) Tak
Przetwarzanie wsadowe Tylko sekwencyjnie (niezgodne z wielowątkowością) Wbudowana równoległość
Ciche błędy formatowania Tak (pominięta rodzina Symbology) Nie
Wymagana zależność od Suite Tak — subskrypcja Infragistics Ultimate Nie — pakiet samodzielny
Opcja licencji wieczystej Nie — roczna subskrypcja Tak
Przybliżony koszt licencji Roczna subskrypcja (Infragistics Ultimate) Od 749 USD – licencja wieczysta (Lite)

Przewodnik po mapowaniu API

WinForms(UltraWinBarcode) do IronBarcode

InfragisticsWinForms—UltraWinBarcode IronBarcode
new UltraWinBarcode() BarcodeWriter.CreateBarcode(data, encoding)
barcode.Symbology = Symbology.Code128 BarcodeEncoding.Code128 (parameter to CreateBarcode)
barcode.Data = "ITEM-12345" First argument of CreateBarcode()
barcode.SaveTo(outputPath) .SaveAsPng(outputPath)
Nie istnieje API do odczytu BarcodeReader.Read(imagePath)

WPF(BarcodeReader) do IronBarcode

InfragisticsWPF— BarcodeReader IronBarcode
new BarcodeReader() Klasa statyczna — nie wymaga instancji
_reader.DecodeComplete += OnDecodeComplete Nie jest potrzebne
_reader.DecodeAsync(bitmap, Symbology.X |Symbology.Y) Automatyczne wykrywanie — bez konfiguracji
new BitmapImage(new Uri(path)) + _reader.Decode(bitmap, ...) BarcodeReader.Read(path)
e.Value (in ReaderDecodeArgs) result.Value
e.Symbology (in ReaderDecodeArgs) result.Format
TaskCompletionSource<string> async wrapper Synchroniczne — nie wymaga opakowania
Dispose() — detach event handler Niepotrzebne — brak instancji lub zdarzenia
Tylko projektWPF Dowolny typ projektu .NET

Kiedy zespoły się zmieniają

Kilka konkretnych sytuacji konsekwentnie zniechęca zespoły do korzystania z obsługi BarCode firmy Infragistics.

Odczyt wymagany w WinForms. Jest to najczęstszy scenariusz. AplikacjaWinFormsgeneruje kody kreskowe dobrze z UltraWinBarcode, ale potem pojawia się nowe wymaganie: skanowanie kodu kreskowego z przesłanego obrazu lub weryfikacja etykiety przed drukowaniem. Nie ma interfejsu API do odczytu Infragistics dla WinForms. Zespół albo korzysta z drugiej biblioteki, albo zastępuje kod generujący czymś, co spełnia obie te funkcje.

Nowy punkt końcowy .NET Core. Aplikacja desktopowa z funkcją generowania kodów kreskowych Infragistics zyskuje towarzyszące jej webowe API. Punkt końcowy musi akceptować przesyłanie obrazów i zwracać wartości BARCODE lub generować obrazy BARCODE na żądanie. Żadne z tych zadań nie jest możliwe przy użyciu pakietów BarCode Infragistics w projekcie ASP.NET Core.IronBarcode instaluje się za pomocą dotnet add package BarCode i działa w akcji kontrolera tak samo, jak działa w metodzie konsolowej.

Wdrożenie w Dockerze. AplikacjaWPFjest konteneryzowana lub jej logika BarCode jest wyodrębniana do mikrousługi. ZestawyWPFnie działają w kontenerach Docker na systemie Linux. InfragisticsWPFBarcodeReader idzie z nimi.IronBarcode jest natywnie przeznaczony dla systemu Linux x64.

Wydajność przetwarzania wsadowego. Przepływ pracy przetwarza setki lub tysiące obrazów BarCode. Czytnik Infragistics, sterowany zdarzeniami, przetwarza je sekwencyjnie. Statyczny czytnik IronBarcode jest bezpieczny dla wątków i obsługuje Parallel.ForEach lub jego wbudowaną opcję MaxParallelThreads bez żadnej infrastruktury do pracy równoczesnej.

Ciche awarie formatu w produkcji. Zespół odkrywa, że kody kreskowe pewnej rodziny były cicho zawodzące przez tygodnie, ponieważ flagi Symbology przekazane do Decode() nie zawierały tej rodziny. Przejście na automatyczne wykrywanie całkowicie eliminuje ten rodzaj awarii.

Ograniczenie zakresu subskrypcji Infragistics. Niektóre zespoły płacą cenę subskrypcji Infragistics Ultimate właśnie dlatego, że obejmuje ona kontrolki BARCODE. Jeśli jedynym powodem subskrypcji jest potrzeba korzystania z kodów kreskowych, warto rozważyć dedykowaną bibliotekę kodów kreskowych, która kosztuje ułamek ceny.

Wnioski

Główny problem związany z obsługą BARCODE przez Infragistics ma charakter architektoniczny, a nie dotyczy możliwości.WPFBarcodeReader odczytuje kody kreskowe.WinFormsUltraWinBarcode je generuje. W wąskim kontekście, dla którego każdy komponent został zaprojektowany, działają one prawidłowo. Problem polega na tym, że te dwa konteksty nie obejmują tego, czego faktycznie potrzebuje większość zespołów .NET.

Funkcja BARCODE w nowoczesnej aplikacji .NET rzadko mieści się w jednym frameworku interfejsu użytkownika. Pojawia się w kliencieWinFormsi web API. Działa w kontenerze Docker i na komputerze stacjonarnym. Musi skanować obrazy przesłane do punktu końcowego ASP.NET i drukować etykiety z poziomu narzędzia konsolowego. Żadne z tych rozwiązań nie działa z pakietami kodów kreskowych Infragistics, a wzorzec sterowany zdarzeniami czytnikaWPFz wymaganymi flagami symboliki znacznie zwiększa złożoność nawet w tym jednym kontekście, w którym działa.

IronBarcode rozwiązuje ten sam problem — odczytywanie i generowanie kodów kreskowych — za pomocą statycznego interfejsu API, który kompiluje się i działa identycznie w każdym typie projektu .NET. Wywołanie BarcodeReader.Read(), które piszesz w klasie serwisowej WPF, jest tym samym wywołaniem, które piszesz w kontrolerzeASP.NET Corei tym samym wywołaniem, które piszesz w kontenerze Docker w Linux. Brak zdarzeń, brak flag, brak TaskCompletionSource. Logika kodu BarCode składa się z dwóch wierszy, a nie trzydziestu pięciu, i te dwa wiersze działają wszędzie.

Często Zadawane Pytania

Co to jest Infragistics Barcode?

Infragistics Barcode to biblioteka .NET do generowania i odczytywania kodów kreskowych w aplikacjach C#. Jest jedną z kilku alternatyw ocenianych przez programistów przy wyborze rozwiązania do kodów kreskowych dla projektów .NET.

Jakie są główne różnice między Infragistics Barcode a IronBarcode?

IronBarcode używa statycznego, bezstanowego API, które nie wymaga zarządzania instancjami, podczas gdy Infragistics Barcode zazwyczaj wymaga utworzenia i skonfigurowania instancji przed użyciem. IronBarcode również zapewnia natywne wsparcie dla PDF, automatyczne wykrywanie formatu oraz licencjonowanie za pomocą jednego klucza we wszystkich środowiskach.

Czy IronBarcode jest łatwiejszy do licencjonowania niż Infragistics Barcode?

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, które obsługuje Infragistics Barcode?

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.

Jak IronBarcode radzi sobie z przetwarzaniem wsadowym w porównaniu do Infragistics Barcode?

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ę ocenić IronBarcode przed zakupem, w przeciwieństwie do Infragistics?

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 cenowa między Infragistics Barcode 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 Infragistics Barcode do IronBarcode jest prosta?

Migracja z Infragistics Barcode do IronBarcode polega głównie na zastąpieniu wywołań API opartych na instancjach metodami statycznymi IronBarcode, usunięciu szablonów licencyjnych oraz aktualizacji nazw właściwości wynikowych. Większość migracji polega na redukcji kodu, a nie na jego dodawaniu.

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