Jak ustawić korekcję błędów w C# | IronQR
Migrating from ZXing.Net.MAUI to IronBarcode
Niniejszy przewodnik zawiera kompletną ścieżkę migracji z ZXing.Net.MAUI do IronBarcode for .NET dla programistów .NET MAUI. Obejmuje on powody, dla których zespoły podejmują tę migrację, porównanie funkcji ułatwiające podjęcie decyzji, mechaniczne kroki wymiany pakietu i aktualizacji plików projektu, przykłady kodu przed i po zmianie dla każdego głównego wzorca użytkowania, Dokumentację API, sekcję rozwiązywania problemów pojawiających się podczas przejścia, listę kontrolną migracji do śledzenia postępów oraz podsumowanie wyników, jakie przynosi migracja.
Dlaczego warto przejść z ZXing.Net.MAUI
Decyzja o odejściu od ZXing.Net.MAUI jest zazwyczaj spowodowana jednym lub kilkoma konkretnymi warunkami projektowymi. Nie są to preferencje stylistyczne — są to przypadki, w których architektura biblioteki lub stan jej utrzymania uniemożliwiają spełnienie danego wymagania.
Brak obsługi Windows MAUI: ZXing.Net.MAUI nie posiada implementacji kamery dla systemu Windows i nie ma publicznych planów jej stworzenia. Biblioteka została zbudowana w oparciu o interfejsy API aparatów fotograficznych platform iOS i Android. Jeśli projekt MAUI doda cel Windows po początkowej kompilacji — co jest powszechnym schematem w zespołach, które zaczynają od mobilnych aplikacji — ZXing.Net.MAUI nie będzie w stanie obsłużyć tego celu. Nie ma szkicu, rozwiązania awaryjnego ani obejścia.
Problem z automatycznym fokusowaniem w iPhone 15 Pro: Tracker problemów GitHub dla Redth/ZXing.Net.Maui dokumentuje, że urządzenia iPhone 15 Pro i Pro Max (iPhone16,1 i iPhone16,2) nie osiągają niezawodnego fokusowania dla wykrywania kodów kreskowych przy użyciu CameraBarcodeReaderView. BARCODE jest widoczny w kadrze aparatu, ale system autofokusa nie ustawia ostrości wystarczająco precyzyjnie, aby dekoder mógł wyodrębnić wynik. Jedynym udokumentowanym rozwiązaniem jest poinstruowanie użytkownika, aby ręcznie dostosował odległość między urządzeniem a BARCODE — instrukcja ta wymaga widocznej podpowiedzi w interfejsie użytkownika oraz cierpliwości użytkownika, co nie jest akceptowalnym wynikiem produkcyjnym dla podstawowego przepływu pracy.
Wyciek zasobów kamery: CameraBarcodeReaderView nie implementuje IDisposable. Gdy użytkownik opuszcza stronę skanowania, zasoby kamery nie są zwalniane za pomocą standardowego wzorca usuwania. Dokumentowany obejście polega na ustawieniu IsDetecting = false w OnDisappearing(), co zmniejsza wpływ, ale nie uwalnia formalnie kamery. Aplikacje, które często przechodzą do stron skanowania i z nich wychodzą, zużywają coraz więcej zasobów, co może objawiać się wzrostem zużycia pamięci, wyczerpywaniem się baterii oraz sporadycznymi błędami inicjalizacji aparatu po powrocie na stronę skanowania.
Cicha awaria specyfikacji formatu: ZXing.Net.MAUI dziedziczy po ZXing.Net wymóg deklarowania każdego formatu BARCODE do skanowania przed rozpoczęciem skanowania. Formaty pominięte z BarcodeReaderOptions.Formats są cicho ignorowane, nawet jeśli są wyraźnie widoczne w kadrze kamery. Użytkownik, który skieruje urządzenie na format BARCODE, którego programista nie przewidział, nie zobaczy żadnego błędu — aplikacja po prostu niczego nie wykryje. W środowiskach, w których formaty kodów kreskowych są kontrolowane przez zewnętrznych dostawców, klientów lub systemy stron trzecich, to niezauważalne niedopatrzenie staje się stałym problemem dla działu wsparcia.
Stabilność pre-1.0: ZXing.Net.MAUI jest opublikowany w wersji v0.7.4 — stabilne wydanie w NuGet, ale wciąż pre-1.0 pod względem wersjonowania semantycznego. Zmiany API w wersji mniejszej są nadal możliwe przed wersją 1.0, tempo poprawek błędów zależy od dostępności konserwatorów społecznościowych, i nie ma wsparcia SLA komercyjnego. Dla aplikacji enterprise podlegających audytom zależności lub analizie kompozycji oprogramowania, biblioteka społecznościowa pre-1.0 bez wsparcia komercyjnego może nie przejść procesu zatwierdzania.
Podstawowy problem
Problem strukturalny polega na tym, że CameraBarcodeReaderView blokuje programistę w pętli zdarzeń zorientowanej na kamerę z ręcznym zarządzaniem cyklem życia i stałą listą formatów. Dla wszystkiego poza podstawowym skanowaniem kamerą na iOS i Androidzie z znanymi formatami kodów kreskowych architektura osiąga swoją granicę:
// ZXing.Net.MAUI: event loop, format list, lifecycle boilerplate on every scan page
public partial class ScannerPage : ContentPage
{
public BarcodeReaderOptions ReaderOptions { get; }
public ScannerPage()
{
InitializeComponent();
ReaderOptions = new BarcodeReaderOptions
{
Formats = BarcodeFormats.QRCode |
BarcodeFormats.Code128 |
BarcodeFormats.Ean13 |
BarcodeFormats.UpcA,
TryHarder = true,
AutoRotate = true
};
BindingContext = this;
}
private void OnBarcodesDetected(object sender, BarcodeDetectionEventArgs e)
{
MainThread.BeginInvokeOnMainThread(() =>
{
foreach (var barcode in e.Results)
ResultLabel.Text = $"{barcode.Format}: {barcode.Value}";
});
CameraView.IsDetecting = false;
}
protected override void OnDisappearing()
{
base.OnDisappearing();
CameraView.IsDetecting = false; // Required — no Dispose() available
}
protected override void OnAppearing()
{
base.OnAppearing();
CameraView.IsDetecting = true;
}
}
// ZXing.Net.MAUI: event loop, format list, lifecycle boilerplate on every scan page
public partial class ScannerPage : ContentPage
{
public BarcodeReaderOptions ReaderOptions { get; }
public ScannerPage()
{
InitializeComponent();
ReaderOptions = new BarcodeReaderOptions
{
Formats = BarcodeFormats.QRCode |
BarcodeFormats.Code128 |
BarcodeFormats.Ean13 |
BarcodeFormats.UpcA,
TryHarder = true,
AutoRotate = true
};
BindingContext = this;
}
private void OnBarcodesDetected(object sender, BarcodeDetectionEventArgs e)
{
MainThread.BeginInvokeOnMainThread(() =>
{
foreach (var barcode in e.Results)
ResultLabel.Text = $"{barcode.Format}: {barcode.Value}";
});
CameraView.IsDetecting = false;
}
protected override void OnDisappearing()
{
base.OnDisappearing();
CameraView.IsDetecting = false; // Required — no Dispose() available
}
protected override void OnAppearing()
{
base.OnAppearing();
CameraView.IsDetecting = true;
}
}
Imports ZXing.Net.MAUI
Public Partial Class ScannerPage
Inherits ContentPage
Public ReadOnly Property ReaderOptions As BarcodeReaderOptions
Public Sub New()
InitializeComponent()
ReaderOptions = New BarcodeReaderOptions With {
.Formats = BarcodeFormats.QRCode Or
BarcodeFormats.Code128 Or
BarcodeFormats.Ean13 Or
BarcodeFormats.UpcA,
.TryHarder = True,
.AutoRotate = True
}
BindingContext = Me
End Sub
Private Sub OnBarcodesDetected(sender As Object, e As BarcodeDetectionEventArgs)
MainThread.BeginInvokeOnMainThread(Sub()
For Each barcode In e.Results
ResultLabel.Text = $"{barcode.Format}: {barcode.Value}"
Next
End Sub)
CameraView.IsDetecting = False
End Sub
Protected Overrides Sub OnDisappearing()
MyBase.OnDisappearing()
CameraView.IsDetecting = False ' Required — no Dispose() available
End Sub
Protected Overrides Sub OnAppearing()
MyBase.OnAppearing()
CameraView.IsDetecting = True
End Sub
End Class
IronBarcode zastępuje pętlę zdarzeń pojedynczym wywołaniem asynchronicznym po naciśnięciu przycisku, całkowicie usuwa konfigurację formatu i eliminuje zarządzanie cyklem życia ze strony:
// NuGet: dotnet add package IronBarcode
// IronBarcode: stateless, all platforms, auto-detection, no lifecycle boilerplate
using IronBarCode;
public partial class ScannerPage : ContentPage
{
public ScannerPage() => InitializeComponent();
private async void ScanButton_Clicked(object sender, EventArgs e)
{
var photo = await MediaPicker.CapturePhotoAsync();
if (photo == null) return;
using var stream = await photo.OpenReadAsync();
using var ms = new MemoryStream();
await stream.CopyToAsync(ms);
var results = BarcodeReader.Read(ms.ToArray());
ResultLabel.Text = results.FirstOrDefault()?.Value ?? "No barcode found";
}
// Nie OnAppearing / OnDisappearing needed
}
// NuGet: dotnet add package IronBarcode
// IronBarcode: stateless, all platforms, auto-detection, no lifecycle boilerplate
using IronBarCode;
public partial class ScannerPage : ContentPage
{
public ScannerPage() => InitializeComponent();
private async void ScanButton_Clicked(object sender, EventArgs e)
{
var photo = await MediaPicker.CapturePhotoAsync();
if (photo == null) return;
using var stream = await photo.OpenReadAsync();
using var ms = new MemoryStream();
await stream.CopyToAsync(ms);
var results = BarcodeReader.Read(ms.ToArray());
ResultLabel.Text = results.FirstOrDefault()?.Value ?? "No barcode found";
}
// Nie OnAppearing / OnDisappearing needed
}
Imports IronBarCode
Public Partial Class ScannerPage
Inherits ContentPage
Public Sub New()
InitializeComponent()
End Sub
Private Async Sub ScanButton_Clicked(sender As Object, e As EventArgs)
Dim photo = Await MediaPicker.CapturePhotoAsync()
If photo Is Nothing Then Return
Using stream = Await photo.OpenReadAsync()
Using ms = New MemoryStream()
Await stream.CopyToAsync(ms)
Dim results = BarcodeReader.Read(ms.ToArray())
ResultLabel.Text = If(results.FirstOrDefault()?.Value, "No barcode found")
End Using
End Using
End Sub
' Nie OnAppearing / OnDisappearing needed
End Class
IronBarcode vs ZXing.Net.MAUI: Porównanie funkcji
| Funkcja | ZXing.Net.MAUI | IronBarcode |
|---|---|---|
| Status wydania | Stabilny, pre-1.0 (v0.7.4) | Stabilna, komercyjna wersja |
| iOS MAUI | Tak (iPhone 15 Pro – uszkodzony autofokus) | Tak |
| Android MAUI | Tak (problemy z kompilacją Camera 1.5.0) | Tak |
| Windows MAUI | Nieobsługiwane | Tak |
| macOS MAUI | Nieobsługiwane | Tak |
| Po stronie serwera / ASP.NET Core | Nie | Tak |
| Podgląd na żywo z kamery | Tak | Nie (interfejs użytkownika systemu MediaPicker) |
| Wymagana specyfikacja formatu | Tak | Nie (automatyczne wykrywanie, ponad 50 formatów) |
| Zarządzanie cyklem życia kamery | Podręcznik (IsDetecting) | Nie dotyczy |
| Implementacja metody Dispose() | Nie | Nie dotyczy — bezstanowe |
| Autofokus w iPhone 15 Pro | Uszkodzone (udokumentowane) | Nie dotyczy |
| Pobieranie kodów kreskowych z plików PDF | Nie | Tak |
| Wprowadzenie ścieżki do pliku | Nie (tylko aparat) | Tak |
| Odzyskiwanie uszkodzonych kodów kreskowych | TryHarder tylko | Tak (oparte na ML) |
| Generowanie BarCode'ów | Tak (za pośrednictwem ZXing.Net) | Tak |
| Wsparcie komercyjne | None | Tak |
| Licencja | MIT (bezpłatne) | Komercjalne |
Szybki start
Krok 1: Usuń ZXing.Net.Maui.Controls i wyczyść plik MauiProgram.cs
Usuń pakiet NuGet ZXing.Net.MAUI:
dotnet remove package ZXing.Net.Maui.Controls
dotnet remove package ZXing.Net.Maui.Controls
ZXing.Net.MAUI wymaga jednorazowego wywołania rejestracyjnego w MauiProgram.cs. Usuń tę linię, jeśli się znajduje:
// Usuń this line from MauiProgram.cs
builder.UseBarcodeReader();
// Usuń this line from MauiProgram.cs
builder.UseBarcodeReader();
Import using ZXing.Net.Maui; wspierający to wywołanie może również zostać usunięty z MauiProgram.cs.
Krok 2: Zainstaluj IronBarcode
dotnet add package IronBarcode
dotnet add package IronBarcode
Samouczek skanera kodów kreskowych .NET MAUI obejmuje pełną konfigurację projektu, w tym wpisy uprawnień kamery Info.plist dla iOS i deklaracje uprawnień AndroidManifest.xml dla Androida.
Krok 3: Zaktualizuj przestrzenie nazw i zainicjuj licencję
Usuń importy przestrzeni nazw ZXing.Net.MAUI ze wszystkich plików:
// Usuń these from every .cs file that imported them
using ZXing.Net.Maui;
using ZXing.Net.Maui.Controls;
// Usuń these from every .cs file that imported them
using ZXing.Net.Maui;
using ZXing.Net.Maui.Controls;
Dodaj przestrzeń nazw IronBarcode i zainicjuj klucz licencyjny przy starcie aplikacji. Odpowiednia lokalizacja to MauiProgram.cs lub App.xaml.cs, przed wykonaniem jakichkolwiek operacji na kodach kreskowych:
using IronBarCode;
// In MauiProgram.cs CreateMauiApp() or App.xaml.cs constructor
IronBarCode.License.LicenseKey = "YOUR-LICENSE-KEY";
using IronBarCode;
// In MauiProgram.cs CreateMauiApp() or App.xaml.cs constructor
IronBarCode.License.LicenseKey = "YOUR-LICENSE-KEY";
Imports IronBarCode
' In MauiProgram.vb CreateMauiApp() or App.xaml.vb constructor
IronBarCode.License.LicenseKey = "YOUR-LICENSE-KEY"
Przykłady migracji kodu
Zastąpienie kontrolki kamery XAML i kodu zaplecza
Podstawowym celem migracji są kontrolka XAML CameraBarcodeReaderView i jej wspierający kod-behind. Zmiana usuwa widok kamery z układu strony i zastępuje wzorzec skanowania sterowany zdarzeniami asynchronicznym przechwytywaniem uruchamianym przyciskiem.
Podejście ZXing.Net.MAUI:
XAML:
<ContentPage xmlns:zxing="clr-namespace:ZXing.Net.Maui.Controls;assembly=ZXing.Net.MAUI.Controls">
<StackLayout>
<zxing:CameraBarcodeReaderView
x:Name="CameraView"
Options="{Binding ReaderOptions}"
BarcodesDetected="OnBarcodesDetected"
VerticalOptions="FillAndExpand" />
<Label x:Name="ResultLabel" Text="Scanning..." />
</StackLayout>
</ContentPage>
<ContentPage xmlns:zxing="clr-namespace:ZXing.Net.Maui.Controls;assembly=ZXing.Net.MAUI.Controls">
<StackLayout>
<zxing:CameraBarcodeReaderView
x:Name="CameraView"
Options="{Binding ReaderOptions}"
BarcodesDetected="OnBarcodesDetected"
VerticalOptions="FillAndExpand" />
<Label x:Name="ResultLabel" Text="Scanning..." />
</StackLayout>
</ContentPage>
Kod źródłowy:
using ZXing.Net.Maui;
using ZXing.Net.Maui.Controls;
public partial class ScannerPage : ContentPage
{
public BarcodeReaderOptions ReaderOptions { get; }
public ScannerPage()
{
InitializeComponent();
ReaderOptions = new BarcodeReaderOptions
{
Formats = BarcodeFormats.QRCode | BarcodeFormats.Code128 | BarcodeFormats.Ean13,
TryHarder = true,
AutoRotate = true
};
BindingContext = this;
}
private void OnBarcodesDetected(object sender, BarcodeDetectionEventArgs e)
{
MainThread.BeginInvokeOnMainThread(() =>
{
foreach (var barcode in e.Results)
ResultLabel.Text = $"{barcode.Format}: {barcode.Value}";
});
CameraView.IsDetecting = false;
}
protected override void OnDisappearing()
{
base.OnDisappearing();
CameraView.IsDetecting = false;
}
protected override void OnAppearing()
{
base.OnAppearing();
CameraView.IsDetecting = true;
}
}
using ZXing.Net.Maui;
using ZXing.Net.Maui.Controls;
public partial class ScannerPage : ContentPage
{
public BarcodeReaderOptions ReaderOptions { get; }
public ScannerPage()
{
InitializeComponent();
ReaderOptions = new BarcodeReaderOptions
{
Formats = BarcodeFormats.QRCode | BarcodeFormats.Code128 | BarcodeFormats.Ean13,
TryHarder = true,
AutoRotate = true
};
BindingContext = this;
}
private void OnBarcodesDetected(object sender, BarcodeDetectionEventArgs e)
{
MainThread.BeginInvokeOnMainThread(() =>
{
foreach (var barcode in e.Results)
ResultLabel.Text = $"{barcode.Format}: {barcode.Value}";
});
CameraView.IsDetecting = false;
}
protected override void OnDisappearing()
{
base.OnDisappearing();
CameraView.IsDetecting = false;
}
protected override void OnAppearing()
{
base.OnAppearing();
CameraView.IsDetecting = true;
}
}
Imports ZXing.Net.Maui
Imports ZXing.Net.Maui.Controls
Public Partial Class ScannerPage
Inherits ContentPage
Public ReadOnly Property ReaderOptions As BarcodeReaderOptions
Public Sub New()
InitializeComponent()
ReaderOptions = New BarcodeReaderOptions With {
.Formats = BarcodeFormats.QRCode Or BarcodeFormats.Code128 Or BarcodeFormats.Ean13,
.TryHarder = True,
.AutoRotate = True
}
BindingContext = Me
End Sub
Private Sub OnBarcodesDetected(sender As Object, e As BarcodeDetectionEventArgs)
MainThread.BeginInvokeOnMainThread(Sub()
For Each barcode In e.Results
ResultLabel.Text = $"{barcode.Format}: {barcode.Value}"
Next
End Sub)
CameraView.IsDetecting = False
End Sub
Protected Overrides Sub OnDisappearing()
MyBase.OnDisappearing()
CameraView.IsDetecting = False
End Sub
Protected Overrides Sub OnAppearing()
MyBase.OnAppearing()
CameraView.IsDetecting = True
End Sub
End Class
Podejście IronBarcode:
XAML:
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui">
<StackLayout>
<Button Text="Scan Barcode" Clicked="ScanButton_Clicked" />
<Label x:Name="ResultLabel" Text="Tap to scan..." />
</StackLayout>
</ContentPage>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui">
<StackLayout>
<Button Text="Scan Barcode" Clicked="ScanButton_Clicked" />
<Label x:Name="ResultLabel" Text="Tap to scan..." />
</StackLayout>
</ContentPage>
Kod źródłowy:
// NuGet: dotnet add package IronBarcode
using IronBarCode;
public partial class ScannerPage : ContentPage
{
public ScannerPage() => InitializeComponent();
private async void ScanButton_Clicked(object sender, EventArgs e)
{
var photo = await MediaPicker.CapturePhotoAsync();
if (photo == null) return;
using var stream = await photo.OpenReadAsync();
using var ms = new MemoryStream();
await stream.CopyToAsync(ms);
var results = BarcodeReader.Read(ms.ToArray());
var first = results.FirstOrDefault();
ResultLabel.Text = first != null
? $"{first.Format}: {first.Value}"
: "No barcode found";
}
// Nie OnAppearing or OnDisappearing required — no camera state exists between scans
}
// NuGet: dotnet add package IronBarcode
using IronBarCode;
public partial class ScannerPage : ContentPage
{
public ScannerPage() => InitializeComponent();
private async void ScanButton_Clicked(object sender, EventArgs e)
{
var photo = await MediaPicker.CapturePhotoAsync();
if (photo == null) return;
using var stream = await photo.OpenReadAsync();
using var ms = new MemoryStream();
await stream.CopyToAsync(ms);
var results = BarcodeReader.Read(ms.ToArray());
var first = results.FirstOrDefault();
ResultLabel.Text = first != null
? $"{first.Format}: {first.Value}"
: "No barcode found";
}
// Nie OnAppearing or OnDisappearing required — no camera state exists between scans
}
Imports IronBarCode
Public Partial Class ScannerPage
Inherits ContentPage
Public Sub New()
InitializeComponent()
End Sub
Private Async Sub ScanButton_Clicked(sender As Object, e As EventArgs)
Dim photo = Await MediaPicker.CapturePhotoAsync()
If photo Is Nothing Then Return
Using stream = Await photo.OpenReadAsync()
Using ms = New MemoryStream()
Await stream.CopyToAsync(ms)
Dim results = BarcodeReader.Read(ms.ToArray())
Dim first = results.FirstOrDefault()
ResultLabel.Text = If(first IsNot Nothing, $"{first.Format}: {first.Value}", "No barcode found")
End Using
End Using
End Sub
' Nie OnAppearing or OnDisappearing required — no camera state exists between scans
End Class
Całkowicie usunięto przestrzeń nazw XAML zxing:, listę formatów BarcodeReaderOptions, osłonę MainThread.BeginInvokeOnMainThread() oraz oba nadpisania cyklu życia. Kontynuacja metody async działa w kontekście wywołującym — który jest głównym wątkiem dla obsługi zdarzeń UI — więc nie potrzeba explicite przekładania wątków.
Usunięcie specyfikacji formatu
Usunięto wszelkie bloki konfiguracyjne BarcodeReaderOptions rozproszone między wieloma stronami lub scenariuszami skanowania w kodzie bazowym.IronBarcode automatycznie wykrywa format spośród ponad 50 obsługiwanych formatów bez konieczności wcześniejszej konfiguracji.
Podejście ZXing.Net.MAUI:
// ZXing.Net.MAUI: every anticipated format must be listed explicitly
// Formats not listed here will silently fail to detect
var readerOptions = new BarcodeReaderOptions
{
Formats = BarcodeFormats.QRCode |
BarcodeFormats.DataMatrix |
BarcodeFormats.Aztec |
BarcodeFormats.Pdf417 |
BarcodeFormats.Code128 |
BarcodeFormats.Code39 |
BarcodeFormats.Ean13 |
BarcodeFormats.UpcA |
BarcodeFormats.Codabar,
TryHarder = true
};
// ZXing.Net.MAUI: every anticipated format must be listed explicitly
// Formats not listed here will silently fail to detect
var readerOptions = new BarcodeReaderOptions
{
Formats = BarcodeFormats.QRCode |
BarcodeFormats.DataMatrix |
BarcodeFormats.Aztec |
BarcodeFormats.Pdf417 |
BarcodeFormats.Code128 |
BarcodeFormats.Code39 |
BarcodeFormats.Ean13 |
BarcodeFormats.UpcA |
BarcodeFormats.Codabar,
TryHarder = true
};
' ZXing.Net.MAUI: every anticipated format must be listed explicitly
' Formats not listed here will silently fail to detect
Dim readerOptions As New BarcodeReaderOptions With {
.Formats = BarcodeFormats.QRCode Or
BarcodeFormats.DataMatrix Or
BarcodeFormats.Aztec Or
BarcodeFormats.Pdf417 Or
BarcodeFormats.Code128 Or
BarcodeFormats.Code39 Or
BarcodeFormats.Ean13 Or
BarcodeFormats.UpcA Or
BarcodeFormats.Codabar,
.TryHarder = True
}
Podejście IronBarcode:
// IronBarcode: no format configuration needed
// All formats are detected automatically on every read call
var results = BarcodeReader.Read(imageBytes);
// Optional: restrict to specific formats for performance tuning (not required for correctness)
var options = new BarcodeReaderOptions
{
ExpectBarcodeTypes = BarcodeEncoding.QRCode | BarcodeEncoding.Code128
};
var tunedResults = BarcodeReader.Read(imageBytes, options);
// IronBarcode: no format configuration needed
// All formats are detected automatically on every read call
var results = BarcodeReader.Read(imageBytes);
// Optional: restrict to specific formats for performance tuning (not required for correctness)
var options = new BarcodeReaderOptions
{
ExpectBarcodeTypes = BarcodeEncoding.QRCode | BarcodeEncoding.Code128
};
var tunedResults = BarcodeReader.Read(imageBytes, options);
Imports IronBarcode
' IronBarcode: no format configuration needed
' All formats are detected automatically on every read call
Dim results = BarcodeReader.Read(imageBytes)
' Optional: restrict to specific formats for performance tuning (not required for correctness)
Dim options As New BarcodeReaderOptions With {
.ExpectBarcodeTypes = BarcodeEncoding.QRCode Or BarcodeEncoding.Code128
}
Dim tunedResults = BarcodeReader.Read(imageBytes, options)
W IronBarcode dostępne są wskazówki dotyczące formatowania dla scenariuszy, w których liczy się wydajność, ale są one opcjonalne. BARCODE w formacie niewymienionym w obiekcie opcji nadal zostanie wykryty i zwrócony.
Usunięcie zarządzania cyklem życia IsDetecting
Każde nadpisanie OnAppearing i OnDisappearing, które istnieje w celu przełączenia CameraView.IsDetecting, zostało usunięte. Jeśli te nadpisania metody zawierają inną logikę cyklu życia strony, zachowaj tę logikę i usuń tylko linie IsDetecting.
Podejście ZXing.Net.MAUI:
// Required boilerplate on every page — omitting this causes camera resource leaks
protected override void OnDisappearing()
{
base.OnDisappearing();
if (CameraView != null)
CameraView.IsDetecting = false;
}
protected override void OnAppearing()
{
base.OnAppearing();
if (CameraView != null)
CameraView.IsDetecting = true;
}
// Required boilerplate on every page — omitting this causes camera resource leaks
protected override void OnDisappearing()
{
base.OnDisappearing();
if (CameraView != null)
CameraView.IsDetecting = false;
}
protected override void OnAppearing()
{
base.OnAppearing();
if (CameraView != null)
CameraView.IsDetecting = true;
}
' Required boilerplate on every page — omitting this causes camera resource leaks
Protected Overrides Sub OnDisappearing()
MyBase.OnDisappearing()
If CameraView IsNot Nothing Then
CameraView.IsDetecting = False
End If
End Sub
Protected Overrides Sub OnAppearing()
MyBase.OnAppearing()
If CameraView IsNot Nothing Then
CameraView.IsDetecting = True
End If
End Sub
Podejście IronBarcode:
// Delete both methods if they contain only IsDetecting management.
// If they contain other logic, remove only the IsDetecting lines and keep the rest.
//IronBarcode is stateless — there is no camera view running between button taps.
// Delete both methods if they contain only IsDetecting management.
// If they contain other logic, remove only the IsDetecting lines and keep the rest.
//IronBarcode is stateless — there is no camera view running between button taps.
' Delete both methods if they contain only IsDetecting management.
' If they contain other logic, remove only the IsDetecting lines and keep the rest.
' IronBarcode is stateless — there is no camera view running between button taps.
Windows MAUI: ten sam kod, bez kompilacji warunkowej
W przypadku ZXing.Net.MAUI dodanie docelowej platformy Windows do projektu kończyło się niepowodzeniem kompilacji lub wymagało stosowania stubów specyficznych dla platformy, ponieważ implementacja dla Windows nigdy nie została napisana. Dzięki IronBarcode ten sam kod, który działa na iOS i Androidzie, kompiluje się i działa na Windowsie bez żadnych modyfikacji.
Podejście ZXing.Net.MAUI:
// Windows MAUI: either fails to compile or requires a platform-specific stub
// There is no documented path to Windows support
#if ANDROID || IOS
// ZXing.Net.MAUI scanning — Windows has no implementation
#endif
// Windows MAUI: either fails to compile or requires a platform-specific stub
// There is no documented path to Windows support
#if ANDROID || IOS
// ZXing.Net.MAUI scanning — Windows has no implementation
#endif
Podejście IronBarcode:
// NuGet: dotnet add package IronBarcode
// Nie platform conditionals — same code runs on iOS, Android, Windows, and macOS
private async void ScanButton_Clicked(object sender, EventArgs e)
{
var photo = await MediaPicker.CapturePhotoAsync();
if (photo == null) return;
using var stream = await photo.OpenReadAsync();
using var ms = new MemoryStream();
await stream.CopyToAsync(ms);
var results = BarcodeReader.Read(ms.ToArray());
ResultLabel.Text = results.FirstOrDefault()?.Value ?? "No barcode found";
}
// NuGet: dotnet add package IronBarcode
// Nie platform conditionals — same code runs on iOS, Android, Windows, and macOS
private async void ScanButton_Clicked(object sender, EventArgs e)
{
var photo = await MediaPicker.CapturePhotoAsync();
if (photo == null) return;
using var stream = await photo.OpenReadAsync();
using var ms = new MemoryStream();
await stream.CopyToAsync(ms);
var results = BarcodeReader.Read(ms.ToArray());
ResultLabel.Text = results.FirstOrDefault()?.Value ?? "No barcode found";
}
' NuGet: dotnet add package IronBarcode
' Nie platform conditionals — same code runs on iOS, Android, Windows, and macOS
Private Async Sub ScanButton_Clicked(sender As Object, e As EventArgs)
Dim photo = Await MediaPicker.CapturePhotoAsync()
If photo Is Nothing Then Return
Using stream = Await photo.OpenReadAsync()
Using ms As New MemoryStream()
Await stream.CopyToAsync(ms)
Dim results = BarcodeReader.Read(ms.ToArray())
ResultLabel.Text = If(results.FirstOrDefault()?.Value, "No barcode found")
End Using
End Using
End Sub
Na Windowsie MediaPicker.CapturePhotoAsync() mapuje się na selektor plików Windows, pozwalając użytkownikowi wybrać plik graficzny — odpowiednie zachowanie dla środowiska desktop. Przewodnik po kodach kreskowych MAUI dla komputerów stacjonarnych szczegółowo omawia konfigurację MAUI w systemach Windows i macOS.
Odczytywanie BarCodes z plików PDF (nowa funkcja)
ZXing.Net.MAUI nie posiada API do odczytu BARCODE-ów z dokumentów PDF. Jeśli jest to nowa funkcja, którą umożliwia migracja, obowiązuje następujący wzorzec:
Podejście ZXing.Net.MAUI:
// ZXing.Net.MAUI: no API for PDF or file-based barcode reading
// Cannot fulfill this requirement — a separate library is required
// ZXing.Net.MAUI: no API for PDF or file-based barcode reading
// Cannot fulfill this requirement — a separate library is required
' ZXing.Net.MAUI: no API for PDF or file-based barcode reading
' Cannot fulfill this requirement — a separate library is required
Podejście IronBarcode:
// NuGet: dotnet add package IronBarcode
using IronBarCode;
// Read all barcodes from all pages of a PDF
var pdfResults = BarcodeReader.Read("invoice.pdf");
foreach (var barcode in pdfResults)
Console.WriteLine($"Page {barcode.PageNumber}: {barcode.Format} — {barcode.Value}");
// Read from a user-selected file using MAUI FilePicker
private async void ReadFileButton_Clicked(object sender, EventArgs e)
{
var file = await FilePicker.PickAsync(new PickOptions
{
PickerTitle = "Select image or PDF"
});
if (file == null) return;
var fileResults = BarcodeReader.Read(file.FullPath);
foreach (var result in fileResults)
ResultLabel.Text += $"\n{result.Format}: {result.Value}";
}
// NuGet: dotnet add package IronBarcode
using IronBarCode;
// Read all barcodes from all pages of a PDF
var pdfResults = BarcodeReader.Read("invoice.pdf");
foreach (var barcode in pdfResults)
Console.WriteLine($"Page {barcode.PageNumber}: {barcode.Format} — {barcode.Value}");
// Read from a user-selected file using MAUI FilePicker
private async void ReadFileButton_Clicked(object sender, EventArgs e)
{
var file = await FilePicker.PickAsync(new PickOptions
{
PickerTitle = "Select image or PDF"
});
if (file == null) return;
var fileResults = BarcodeReader.Read(file.FullPath);
foreach (var result in fileResults)
ResultLabel.Text += $"\n{result.Format}: {result.Value}";
}
Imports IronBarCode
' Read all barcodes from all pages of a PDF
Dim pdfResults = BarcodeReader.Read("invoice.pdf")
For Each barcode In pdfResults
Console.WriteLine($"Page {barcode.PageNumber}: {barcode.Format} — {barcode.Value}")
Next
' Read from a user-selected file using MAUI FilePicker
Private Async Sub ReadFileButton_Clicked(sender As Object, e As EventArgs)
Dim file = Await FilePicker.PickAsync(New PickOptions With {
.PickerTitle = "Select image or PDF"
})
If file Is Nothing Then Return
Dim fileResults = BarcodeReader.Read(file.FullPath)
For Each result In fileResults
ResultLabel.Text &= $"\n{result.Format}: {result.Value}"
Next
End Sub
Kompletny proces odczytu BARCODE-ów z plików PDF — obejmujący dokumenty wielostronicowe, metadane dotyczące numerów stron oraz dokumenty o mieszanych formatach — został opisany w przewodniku "Odczyt BARCODE-ów z plików PDF".
ZXing.Net.MAUI API do IronBarcode Mapping Dokumentacja API
| ZXing.Net.MAUI | IronBarcode | Uwagi |
|---|---|---|
builder.UseBarcodeReader() |
Nie jest wymagane | Usunąć z MauiProgram.cs |
using ZXing.Net.Maui; |
using IronBarCode; |
Zastąpienie przestrzeni nazw |
using ZXing.Net.Maui.Controls; |
Nie jest wymagane | Usuń |
xmlns:zxing="clr-namespace:ZXing.Net.Maui.Controls;..." |
Nie jest wymagane | Usuń z XAML |
<zxing:CameraBarcodeReaderView> |
<Button> + MediaPicker.CapturePhotoAsync() |
Zmiana architektury |
Options="{Binding ReaderOptions}" |
Nie jest wymagane | Usuń oprawę |
BarcodesDetected="OnBarcodesDetected" |
wartość zwracana BarcodeReader.Read() |
Wydarzenie → zwrot asynchroniczny |
new BarcodeReaderOptions { Formats = BarcodeFormats.X \| ... } |
Nie jest wymagane | Automatyczne wykrywanie zastępuje listy formatów |
BarcodeDetectionEventArgs e |
IEnumerable<BarcodeResult> |
Różne sposoby dostarczania wyników |
e.Results |
Wartość zwracana z BarcodeReader.Read() |
|
barcode.Value |
result.Value |
Ta sama nazwa właściwości |
barcode.Format |
result.Format |
Ta sama nazwa właściwości |
BarcodeFormats.QRCode |
BarcodeEncoding.QRCode |
Zmiana nazwy enum |
BarcodeFormats.Code128 |
BarcodeEncoding.Code128 |
Zmiana nazwy enum |
BarcodeFormats.Ean13 |
BarcodeEncoding.EAN13 |
Zmiana nazwy enum |
BarcodeFormats.UpcA |
BarcodeEncoding.UPCA |
Zmiana nazwy enum |
CameraView.IsDetecting = false |
Nie jest wymagane | Usunąć z OnDisappearing |
CameraView.IsDetecting = true |
Nie jest wymagane | Usunąć z OnAppearing |
| Brak API do wprowadzania plików | BarcodeReader.Read("path/to/image.png") |
Nowa funkcja |
| Brak API do obsługi plików PDF | BarcodeReader.Read("document.pdf") |
Nowa funkcja |
| Tylko iOS i Android | iOS, Android, Windows, macOS, serwer | Rozwój platformy |
Typowe problemy związane z migracją i ich rozwiązania
Problem 1: Brak odpowiednika podglądu na żywo
ZXing.Net.MAUI: CameraBarcodeReaderView wyświetla ciągły strumień kamery w układzie strony, pokazując użytkownikowi podgląd na żywo z nałożoną informacją zwrotną o skanowaniu.
Rozwiązanie:IronBarcode nie udostępnia kontrolki podglądu na żywo. Wzorzec zastępczy używa MediaPicker.CapturePhotoAsync(), co otwiera UI systemowej kamery platformy. Aparat systemowy zapewnia własny podgląd na żywo i wskaźnik ostrości. Po przechwyceniu obrazu przez użytkownika i zatwierdzeniu, wynik jest przekazywany do BarcodeReader.Read(). Jeżeli trwały wizjer w aplikacji jest wymaganym elementem UX, którego nie można zastąpić systemowym interfejsem kamery, warstwa integracji kamery musi być zbudowana osobno za pomocą Microsoft.Maui.Media lub interfejsów API kamery platformy, przy czym IronBarcode obsługuje etap dekodowania.
Problem 2: Deklaracje uprawnień kamery
ZXing.Net.MAUI: Uprawnienia do korzystania z aparatu mogły zostać zadeklarowane w projekcie w ramach instrukcji konfiguracji ZXing.Net.MAUI.
Rozwiązanie: Uprawnienia kamery nadal są konieczne dla wywołania MediaPicker.CapturePhotoAsync(), które używa wzorzec MAUI IronBarcode. Zweryfikuj, że NSCameraUsageDescription jest obecne w Info.plist dla iOS oraz że <uses-permission android:name="android.permission.CAMERA" /> jest obecne w AndroidManifest.xml dla Androida.IronBarcode sam nie uzyskuje bezpośrednio dostępu do kamery — przetwarza obrazy — ale wywołanie MediaPicker, które dostarcza mu obrazy, wymaga uprawnień do kamery. Konfiguracja uprawnień została omówiona w samouczku dotyczącym skanera BarCode .NET MAUI.
Problem 3: Kompilacja w systemie Windows przebiega teraz pomyślnie, podczas gdy wcześniej kończyła się niepowodzeniem
ZXing.Net.MAUI: Projekty, w których próbowano uwzględnić środowisko docelowe Windows przy użyciu ZXing.Net.MAUI, zazwyczaj napotykały błędy kompilacji lub wymagały wykluczenia biblioteki z kompilacji dla Windows za pomocą warunkowej logiki MSBuild.
Rozwiązanie: Po usunięciu ZXing.Net.MAUI i zainstalowaniu IronBarcode kompilacjaWindows MAUIprzebiega pomyślnie bez żadnych warunków platformowych. Usuń wszystkie #if ANDROID || Zabezpieczenia IOS, które zostały umieszczone wokół wywołań ZXing.Net.MAUI, aby wykluczyć je z kompilacji dla systemu Windows. WywołanieBarcodeReader.Read()IronBarcode kompiluje się i działa na wszystkich docelowych platformach. JeśliMediaPicker.CapturePhotoAsync()` było wykluczone z budów na Windows, to wykluczenie można także usunąć — metoda jest obsługiwana naWindows MAUIi mapuje się na selektor plików. Sprawdź, czy po usunięciu warunków pełne rozwiązanie kompiluje się poprawnie dla wszystkich docelowych frameworków.
Problem 4: Odwołania do wyliczenia BarcodeFormats
ZXing.Net.MAUI: Enuma BarcodeFormats z ZXing.Net.Maui jest intensywnie używana w konfiguracjach BarcodeReaderOptions. Po usunięciu pakietu wszelkie pozostałe odwołania powodują błędy kompilacji.
Rozwiązanie: Usuń wszystkie bloki inicjalizacyjne BarcodeReaderOptions używane do konfigurowania list formatów.IronBarcode nie wymaga określenia formatu do prawidłowego działania. Jeśli jakiekolwiek pozostałe fragmenty kodu odwołują się do wartości BarcodeFormats dla celów logowania, wyświetlania lub porównywania, zastąp je wartościami BarcodeEncoding z przestrzeni nazw IronBarCode. Uruchom grep -rn "BarcodeFormats\." --include="*.cs" ., aby znaleźć wszystkie pozostałe odwołania po usunięciu pakietu.
Lista kontrolna migracji ZXing.Net.MAUI
Zadania przed migracją
Przed wprowadzeniem zmian należy sprawdzić wszystkie użycia ZXing.Net.MAUI w kodzie źródłowym:
grep -rn "ZXing.Net.Maui" --include="*.cs" --include="*.xaml" .
grep -rn "CameraBarcodeReaderView" --include="*.cs" --include="*.xaml" .
grep -rn "BarcodeDetectionEventArgs" --include="*.cs" .
grep -rn "BarcodeReaderOptions" --include="*.cs" .
grep -rn "BarcodeFormats\." --include="*.cs" .
grep -rn "IsDetecting" --include="*.cs" .
grep -rn "UseBarcodeReader" --include="*.cs" .
grep -rn "zxing:" --include="*.xaml" .
grep -rn "e\.Results" --include="*.cs" .
grep -rn "ZXing.Net.Maui" --include="*.cs" --include="*.xaml" .
grep -rn "CameraBarcodeReaderView" --include="*.cs" --include="*.xaml" .
grep -rn "BarcodeDetectionEventArgs" --include="*.cs" .
grep -rn "BarcodeReaderOptions" --include="*.cs" .
grep -rn "BarcodeFormats\." --include="*.cs" .
grep -rn "IsDetecting" --include="*.cs" .
grep -rn "UseBarcodeReader" --include="*.cs" .
grep -rn "zxing:" --include="*.xaml" .
grep -rn "e\.Results" --include="*.cs" .
Zdokumentuj wszystkie strony skanów zidentyfikowane podczas audytu. Zanotuj, które nadpisania OnAppearing i OnDisappearing zawierają tylko zarządzanie IsDetecting (do usunięcia) w porównaniu do tych, które zawierają inną logikę (do częściowej modyfikacji). Zanotuj wszelkie instancje BarcodeReaderOptions, które mogą zawierać listy formatów używane w sposób wykraczający poza konfigurację detekcyjną.
Zadania związane z aktualizacją kodu
- Usuń pakiet NuGet
ZXing.Net.Maui.Controlsz pliku projektu - Usuń
builder.UseBarcodeReader()zMauiProgram.cs - Usuń importy przestrzeni nazw
using ZXing.Net.Maui;iusing ZXing.Net.Maui.Controls;ze wszystkich plików - Zainstaluj pakiet NuGet
IronBarcode - Dodaj
using IronBarCode;do wszystkich plików, które będą używać czytania kodu kreskowego - Dodaj
IronBarCode.License.LicenseKey = "YOUR-LICENSE-KEY";do uruchomienia aplikacji - Usuń deklarację przestrzeni nazw
xmlns:zxingze wszystkich plików XAML - Usuń wszystkie elementy
<zxing:CameraBarcodeReaderView>z plików XAML - Zastąp widok kamery kontrolką
<Button>w każdym pliku XAML - Dodaj
Clicked="ScanButton_Clicked"do każdego przycisku skanowania - Usuń metody obsługi zdarzeń
OnBarcodesDetectedze wszystkich plików kodu-behind - Dodaj metody
async void ScanButton_ClickedimplementująceMediaPicker.CapturePhotoAsync()+BarcodeReader.Read()do każdej strony - Usuń wszystkie bloki inicjalizacyjne
BarcodeReaderOptions - Usuń wszystkie nadpisania
OnDisappearingiOnAppearing, które istnieją wyłącznie do zarządzaniaIsDetecting - Usunąć linie
IsDetectingz jakichkolwiek nadpisańOnDisappearingiOnAppearing, które zawierają inną logikę - Usuń wszystkie `#if ANDROID || Warunkowe zabezpieczenia kompilacji w systemie iOS, które izolowały ZXing.Net.MAUI od kompilacji dla systemu Windows
- Zastąpić wszelkie pozostałe odwołania do enuma
BarcodeFormats.XodpowiednikamiBarcodeEncoding.X
Testy po migracji
Po pomyślnym skompilowaniu migracji sprawdź, czy:
- Android MAUI: przycisk skanowania otwiera aparat systemowy, robi zdjęcie i zwraca poprawny wynik skanowania BARCODE — potwierdź to w przewodniku po skanowaniu na Androidzie
- iOS MAUI: ten sam proces działa na iOS, w tym na sprzęcie iPhone 15 Pro, na którym wcześniej występował problem z autofokusem
- Windows MAUI: kompilacja dla systemu Windows przebiega bez błędów, a przycisk skanowania otwiera okno wyboru plików i zwraca prawidłowy wynik na podstawie wybranego obrazu
- Format: testuj skanowanie kodów kreskowych w formatach, które nie były uwzględnione na starej liście
BarcodeFormats, aby potwierdzić autodetekcję - Nawigacja po stronach: wielokrotnie przechodź do strony skanowania i z niej oraz sprawdź, czy nie występuje wzrost zużycia pamięci ani błędy inicjalizacji kamery
- Odczytywanie plików PDF: jeśli migracja dodaje odczytywanie BarCODE w plikach PDF jako nową funkcję, należy sprawdzić, czy wielostronicowe pliki PDF zwracają wyniki z poprawnymi metadanymi dotyczącymi numerów stron
Kluczowe korzyści wynikające z migracji do IronBarcode
Rozszerzony zakres obsługiwanych platform: Po migracji aplikacja obsługuje systemy Windows imacOS MAUIoprócz iOS i Android — wszystko z tego samego pakietu i przy użyciu tego samego wzorca skanowania. Projekty, które wcześniej wymagały stubów specyficznych dla platformy lub wykluczały system Windows z funkcjonalności BarCode, zyskują pełną obsługę bez dodatkowego kodu.
Niezawodność sprzętu najnowszej generacji: Podejście do przechwytywania obrazu za pomocą MediaPicker i BarcodeReader.Read() nie jest dotknięte modelem automatycznego fokusowania CameraBarcodeReaderView, który zawodzi na sprzęcie iPhone 15 Pro i Pro Max. Aparat systemowy samodzielnie ustawia ostrość, a IronBarcode przetwarza zarejestrowany obraz po potwierdzeniu przez użytkownika wykonania zdjęcia.
Eliminacja zarządzania zasobami kamery: Usunięcie CameraBarcodeReaderView eliminuje całą kategorię błędów wycieków zasobów kamery. Nie ma stanu IsDetecting do śledzenia, nie ma boilerplate OnAppearing i OnDisappearing do utrzymywania na każdej stronie skanowania, i nie ma gromadzenia zasobów kamery w ramach cykli nawigacyjnych. Bezstanowe API sprawia, że strony skanowane są nie do odróżnienia od innych stron pod względem cyklu życia zasobów.
Obsługa formatów bez konfiguracji: Każdy format BARCODE-a napotkany w terenie jest wykrywany automatycznie. Eliminowane są awarie skanowania spowodowane brakującymi wpisami na liście BarcodeFormats. Nie ma już zgłoszeń od użytkowników, których BarCodes były ignorowane, bo dostawca zmienił format etykiet.
Przetwarzanie plików i dokumentów: Migracja umożliwia odczytywanie BarCodes z dokumentów PDF, plików graficznych i strumieni bajtów bez konieczności korzystania z dodatkowej biblioteki. Przepływy zadań, które były wcześniej poza zakresem ZXing.Net.MAUI — odczytywanie kodów kreskowych z załadowanych faktur, przetwarzanie biletów cyfrowych, skanowanie katalogów obrazów w partiach — stają się dostępne przez to samo wywołanie BarcodeReader.Read() używane do przechwytywania kamery.
Stabilność na poziomie produkcyjnym:IronBarcode jest dostarczany jako stabilna wersja komercyjna z aktywnym cyklem rozwoju, wsparciem technicznym oraz regularnymi aktualizacjami dostosowanymi do nowych wersji .NET. Audyty zależności, analiza składu oprogramowania i procesy zatwierdzania w Enterprise wymagają biblioteki obsługiwanej z udokumentowanym zobowiązaniem do utrzymania, a nie pakietu przedpremierowego społeczności.
Często Zadawane Pytania
Dlaczego warto przejść z ZXing.Net.MAUI na IronBarcode?
Typowe powody to uproszczenie licencjonowania (eliminacja złożoności związanej z SDK i kluczem uruchomieniowym), zniesienie limitów przepustowości, uzyskanie natywnej obsługi plików PDF, usprawnienie wdrażania w środowisku Docker/CI/CD oraz ograniczenie powtarzalnego kodu API w kodzie produkcyjnym.
Jak zastąpić wywołania API ZXing.Net.MAUI za pomocą IronBarcode?
Zastąp standardowe fragmenty kodu dotyczące tworzenia instancji i licencjonowania wyrażeniem IronBarCode.License.LicenseKey = "key". Zastąp wywołania czytnika wyrażeniem BarcodeReader.Read(path), a wywołania zapisu wyrażeniem BarcodeWriter.CreateBarcode(data, encoding). Metody statyczne nie wymagają zarządzania instancjami.
Jak bardzo zmienia się kod podczas migracji z ZXing.Net.MAUI do IronBarcode?
Większość migracji skutkuje zmniejszeniem liczby linii kodu. Usuwane są standardowe fragmenty dotyczące licencji, konstruktory instancji oraz jawna konfiguracja formatów. Podstawowe operacje odczytu/zapisu są mapowane na krótsze odpowiedniki w IronBarcode z bardziej przejrzystymi obiektami wynikowymi.
Czy podczas migracji muszę mieć zainstalowane zarówno ZXing.Net.MAUI, jak i IronBarcode?
Nie. Większość migracji polega na bezpośredniej wymianie, a nie na równoległym działaniu. Należy migrować po jednej klasie usługowej na raz, zastąpić odwołanie do NuGet oraz zaktualizować wzorce instancjonowania i wywoływania API przed przejściem do kolejnej klasy.
Jaka jest nazwa pakietu NuGet dla IronBarcode?
Pakiet nosi nazwę „IronBarcode” (z wielkimi literami B i C). Zainstaluj go za pomocą polecenia „Install-Package IronBarcode” lub „dotnet add package IronBarcode”. Dyrektywa using w kodzie to „using IronBarcode;”.
W jaki sposób IronBarcode upraszcza wdrażanie Docker w porównaniu z ZXing.Net.MAUI?
IronBarcode to pakiet NuGet bez zewnętrznych plików SDK ani konfiguracji licencji. W Dockerze należy ustawić zmienną środowiskową IRONBARCODE_LICENSE_KEY, a pakiet zajmie się weryfikacją licencji podczas uruchamiania.
Czy IronBarcode automatycznie wykrywa wszystkie formaty kodów kreskowych po migracji z ZXing.Net.MAUI?
Tak. IronBarcode automatycznie wykrywa symbole we wszystkich obsługiwanych formatach. Wyraźne wyliczenie typów kodów kreskowych nie jest wymagane. Jeśli format jest już znany, a wydajność ma znaczenie, BarcodeReaderOptions pozwala ograniczyć obszar wyszukiwania w celu optymalizacji.
Czy IronBarcode może odczytywać BarCodes z plików PDF bez oddzielnej biblioteki?
Tak. BarCodeReader.Read("document.pdf") przetwarza pliki PDF natywnie. Wyniki obejmują PageNumber, Format, Value i Confidence dla każdego znalezionego kodu kreskowego. Nie jest wymagany żaden zewnętrzny etap renderowania pliku PDF.
W jaki sposób IronBarcode obsługuje równoległe przetwarzanie kodów kreskowych?
Metody statyczne IronBarcode są bezstanowe i bezpieczne dla wątków. Użyj Parallel.ForEach bezpośrednio na listach plików bez zarządzania instancjami dla poszczególnych wątków. BarcodeReaderOptions.MaxParallelThreads kontroluje wewnętrzny limit wątków.
Jakie właściwości wyników ulegają zmianie podczas migracji z ZXing.Net.MAUI do IronBarcode?
Typowe zmiany nazw: BarcodeValue staje się Value, BarcodeType staje się Format. Wyniki IronBarcode zawierają również Confidence i PageNumber. Funkcja wyszukiwania i zamiany w całym rozwiązaniu obsługuje zmiany nazw w istniejącym kodzie przetwarzania wyników.
Jak skonfigurować licencjonowanie IronBarcode w potoku CI/CD?
Zapisz IronBarcode_LICENSE_KEY jako sekret potoku i przypisz IronBarCode.License.LicenseKey w kodzie uruchamiającym aplikację. Jeden sekret obejmuje wszystkie środowiska, w tym środowisko programistyczne, testowe, przejściowe i produkcyjne.
Czy IronBarcode obsługuje generowanie kodów QR z niestandardowym stylem?
Tak. Funkcja QRCodeWriter.CreateQrCode() obsługuje niestandardowe kolory za pomocą ChangeBarCodeColor(), osadzanie logo za pomocą AddBrandLogo(), konfigurowalne poziomy korekcji błędów oraz wiele formatów wyjściowych, w tym PNG, JPG, PDF i strumień.

