Wie man Barcodes aus PDFs in C# liest
Migrating from BarcodeScanning.Native.Maui to IronBarcode
Dieser Leitfaden bietet einen vollständigen Migrationspfad von BarcodeScanning.Native.Maui zu IronBarcode und behandelt den Austausch des Kameraereignismusters, Namensraumänderungen, Beispiele für die Codemigration sowie die Behandlung von Szenarien, die BarcodeScanning.Native.Maui nicht abdecken kann – Windows MAUI, Datei- und PDF-Eingabe, serverseitige Verarbeitung und Barcode-Generierung.
Warum von BarcodeScanning.MAUI migrieren?
Teams, die von BarcodeScanning.Native.Maui migrieren, melden folgende Auslöser:
Windows MAUI-Ziel erforderlich: BarcodeScanning.Native.Maui kapselt native iOS- und Android-APIs. Es gibt keine Windows-Implementierung und es ist auch keine geplant. Wenn Ihre MAUI-App neben iOS und Android auch Windows als Zielplattform hat, benötigen Sie eine Bibliothek, die auf allen drei Plattformen ohne plattformspezifische Verzweigungen funktioniert.
Datei- oder PDF-Eingabe zu den Anforderungen hinzugefügt: BarcodeScanning.Native.Maui akzeptiert nur Live-Kamerabilder. Wenn Benutzer ein Bild aus ihrer Galerie hochladen müssen oder wenn ein serverseitiger Endpunkt Barcodes aus PDFs extrahieren muss, bietet die Bibliothek keinen entsprechenden Codepfad an. Für jedes Szenario mit Datei- oder PDF-Barcodes wird ein anderes Werkzeug benötigt.
Die iOS UPC-A-Daten waren in der Produktion fehlerhaft: Apples Vision-Framework liefert 13 Ziffern für UPC-A-Barcodes (EAN-13-Kodierung). BarcodeScanning.Native.Maui leitet dies unkorrigiert weiter. Wenn UPC-A-Codes mit einer führenden Null gespeichert wurden, könnten Bestandsdatensätze, Kassenabfragen oder Lieferkettenintegrationen unbemerkt gestört worden sein. IronBarcode liefert ohne manuelle Normalisierung den korrekten 12-stelligen UPC-A-Wert.
PDF417-Scans waren unzuverlässig: Die GitHub -Issues der Bibliothek dokumentieren PDF417 als "sehr problematisch – die meisten Scans werden gar nicht erst durchgeführt". Für Versandetiketten, Führerscheine und Bordkarten ist dies ein direktes Hindernis.
Generierung erforderlich: BarcodeScanning.Native.Maui kann keine Barcodes generieren. IronBarcode generiert Code128, QR, DataMatrix und andere Formate als Bilddateien oder Byte-Arrays.
Serverseitige Verarbeitung eingeführt: BarcodeScanning.Native.Maui ist ein Kamera-UI-Steuerelement – es kann nicht in einem Serverprozess ausgeführt werden. Wenn neben dem Scannen auf dem Mobilgerät auch serverseitiges Barcode-Lesen erforderlich ist, deckt IronBarcode beide Seiten mit demselben Paket und derselben API ab.
Das grundsätzliche Problem
BarcodeScanning.Native.Maui verknüpft das Lesen von Barcodes vollständig mit dem Live-Kamera-Ereignismodell. Sobald eine Anforderung außerhalb dieses Modells liegt, bietet die Bibliothek nichts mehr an:
private void OnBarcodeDetected(object sender, OnDetectionFinishedEventArg e)
{
var barcode = e.BarcodeResults.FirstOrDefault();
if (barcode != null)
ResultLabel.Text = barcode.DisplayValue;
}
private void OnBarcodeDetected(object sender, OnDetectionFinishedEventArg e)
{
var barcode = e.BarcodeResults.FirstOrDefault();
if (barcode != null)
ResultLabel.Text = barcode.DisplayValue;
}
Private Sub OnBarcodeDetected(sender As Object, e As OnDetectionFinishedEventArg)
Dim barcode = e.BarcodeResults.FirstOrDefault()
If barcode IsNot Nothing Then
ResultLabel.Text = barcode.DisplayValue
End If
End Sub
IronBarcode akzeptiert beliebige Dateneingaben – Kameraaufnahmen, Dateien, PDFs, Byte-Arrays – und läuft auf jeder Plattform:
using IronBarCode;
private async void ScanBarcodeButton_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";
}
using IronBarCode;
private async void ScanBarcodeButton_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";
}
Imports IronBarCode
Private Async Sub ScanBarcodeButton_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
IronBarcode vs. BarcodeScanning.MAUI: Funktionsvergleich
| Feature | BarcodeScanning.MAUI | IronBarcode |
|---|---|---|
| Live-Kamerabildlesung | Ja – CameraView-Steuerung | Nein (verwenden Sie MediaPicker zum Aufnehmen und lesen Sie es dann). |
| In-App-Kamerasucher | Ja – kontinuierliche Echtzeit | Nein – verwendet die Systemkamera-Benutzeroberfläche über MediaPicker. |
| Aus Bilddatei lesen | Nein | Ja — BarcodeReader.Read(path) |
| Aus Byte-Array lesen | Nein | Ja — BarcodeReader.Read(bytes) |
| Aus dem Stream lesen | Nein | Ja — BarcodeReader.Read(stream) |
| Aus PDF lesen | Nein | Ja — BarcodeReader.Read(pdf) |
| Barcode-Generierung | Nein | Ja — BarcodeWriter + QRCodeWriter |
| Windows MAUI-Unterstützung | Nein | Ja |
| iOS MAUI-Unterstützung | Ja | Ja |
| Android MAUI-Unterstützung | Ja | Ja |
| macOS MAUI-Unterstützung | Nicht dokumentiert | Ja |
| Serverseitig / ASP.NET | Nein | Ja |
| Docker / Azure / AWS Lambda | Nein | Ja |
| iOS UPC-A Genauigkeit | Gibt 13 Stellen zurück (Fehler), erfordert manuelle Normalisierung | Gibt den korrekten 12-stelligen UPC-A-Code zurück. |
| PDF417 Zuverlässigkeit | "Die meisten Scans finden nie statt" (GitHub Probleme) | Unterstützt |
| Mehrfach-Barcode-Erkennung | Ja (mehrere pro Rahmen über e.BarcodeResults) |
Ja (ExpectMultipleBarcodes Option) |
| Lesegeschwindigkeitssteuerung | None | ReadingSpeed.Faster / Balanced / Detailed / ExtremeDetail |
| Lizenz | MIT (Open Source, kostenlos) | Gewerblich – Lite 749 $, Plus 1.499 $, Professional 2.999 $, Unlimited 5.999 $ |
| .NET Framework -Unterstützung | Nein (nur MAUI) | Ja – .NET Framework 4.6.2+ |
Schnellstart: Migration von BarcodeScanning.MAUI zu IronBarcode
Schritt 1: Ersetzen des NuGet-Pakets
BarcodeScanning.Native.Maui entfernen:
dotnet remove package BarcodeScanning.Native.Maui
dotnet remove package BarcodeScanning.Native.Maui
IronBarcode installieren:
dotnet add package IronBarcode
dotnet add package IronBarcode
Schritt 2: Namespaces aktualisieren
Entfernen Sie den Namespace "BarcodeScanning" aus allen Dateien:
// Remove
using BarcodeScanning;
// Remove
using BarcodeScanning;
Imports BarcodeScanning
Fügen Sie den IronBarcode -Namespace hinzu:
// Add
using IronBarCode;
// Add
using IronBarCode;
Imports IronBarCode
In XAML-Dateien entfernen Sie die scanner: XML-Namespace-Deklaration:
xmlns:scanner="clr-namespace:BarcodeScanning;assembly=BarcodeScanning.Native.Maui"
xmlns:scanner="clr-namespace:BarcodeScanning;assembly=BarcodeScanning.Native.Maui"
Schritt 3: Lizenz initialisieren
Fügen Sie die Lizenzinitialisierung beim Anwendungsstart hinzu — in MauiProgram.cs oder App.xaml.cs:
IronBarCode.License.LicenseKey = "YOUR-LICENSE-KEY";
IronBarCode.License.LicenseKey = "YOUR-LICENSE-KEY";
Imports IronBarCode
IronBarCode.License.LicenseKey = "YOUR-LICENSE-KEY"
Beispiele für die Code-Migration
Kamera-Scan: CameraView zu MediaPicker
Die CameraView Steuerung bot einen Echtzeitsucher mit kontinuierlicher Rahmenerkennung. Der Ersatz durch IronBarcode verwendet MAUI's MediaPicker, um die Systemkamera zu öffnen, ein Foto aufzunehmen und das resultierende Bild zu verarbeiten.
BarcodeScanning.MAUI-Ansatz — XAML:
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:scanner="clr-namespace:BarcodeScanning;assembly=BarcodeScanning.Native.Maui">
<StackLayout>
<scanner:CameraView x:Name="CameraView"
OnDetectionFinished="OnBarcodeDetected"
CameraEnabled="True"
BarcodeFormats="All"
VerticalOptions="FillAndExpand" />
<Label x:Name="ResultLabel" Text="Waiting for scan..." />
</StackLayout>
</ContentPage>
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:scanner="clr-namespace:BarcodeScanning;assembly=BarcodeScanning.Native.Maui">
<StackLayout>
<scanner:CameraView x:Name="CameraView"
OnDetectionFinished="OnBarcodeDetected"
CameraEnabled="True"
BarcodeFormats="All"
VerticalOptions="FillAndExpand" />
<Label x:Name="ResultLabel" Text="Waiting for scan..." />
</StackLayout>
</ContentPage>
BarcodeScanning.MAUI-Ansatz — Code-Behind:
using BarcodeScanning;
private void OnBarcodeDetected(object sender, OnDetectionFinishedEventArg e)
{
var barcode = e.BarcodeResults.FirstOrDefault();
if (barcode != null)
MainThread.BeginInvokeOnMainThread(() =>
ResultLabel.Text = barcode.DisplayValue);
}
using BarcodeScanning;
private void OnBarcodeDetected(object sender, OnDetectionFinishedEventArg e)
{
var barcode = e.BarcodeResults.FirstOrDefault();
if (barcode != null)
MainThread.BeginInvokeOnMainThread(() =>
ResultLabel.Text = barcode.DisplayValue);
}
Imports BarcodeScanning
Private Sub OnBarcodeDetected(sender As Object, e As OnDetectionFinishedEventArg)
Dim barcode = e.BarcodeResults.FirstOrDefault()
If barcode IsNot Nothing Then
MainThread.BeginInvokeOnMainThread(Sub()
ResultLabel.Text = barcode.DisplayValue
End Sub)
End If
End Sub
IronBarcode Ansatz — XAML:
<?xml version="1.0" encoding="utf-8" ?>
<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>
<?xml version="1.0" encoding="utf-8" ?>
<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>
IronBarcode Ansatz – Code-Behind:
using IronBarCode;
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?.Value ?? "No barcode found";
}
using IronBarCode;
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?.Value ?? "No barcode found";
}
Imports IronBarCode
Imports System.IO
Imports System.Linq
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())
Dim first = results.FirstOrDefault()
ResultLabel.Text = If(first?.Value, "No barcode found")
End Using
End Using
End Sub
Dieser Code läuft auf iOS, Android und Windows MAUI ohne plattformspezifische Verzweigungen. Das Benutzererlebnis ändert sich von einem Live-Sucher innerhalb der App zum nativen Kamerabildschirm der Plattform – was für die meisten Geschäftsanwendungen geeignet ist. Die IronBarcode MAUI-Leseanleitung beschreibt weitere Konfigurationsoptionen.
Verarbeitung mehrerer Barcodes pro Scan
BarcodeScanning.MAUI-Ansatz:
private void OnBarcodeDetected(object sender, OnDetectionFinishedEventArg e)
{
foreach (var barcode in e.BarcodeResults)
{
MainThread.BeginInvokeOnMainThread(() =>
Console.WriteLine($"Found: {barcode.DisplayValue}"));
}
}
private void OnBarcodeDetected(object sender, OnDetectionFinishedEventArg e)
{
foreach (var barcode in e.BarcodeResults)
{
MainThread.BeginInvokeOnMainThread(() =>
Console.WriteLine($"Found: {barcode.DisplayValue}"));
}
}
Private Sub OnBarcodeDetected(sender As Object, e As OnDetectionFinishedEventArg)
For Each barcode In e.BarcodeResults
MainThread.BeginInvokeOnMainThread(Sub()
Console.WriteLine($"Found: {barcode.DisplayValue}")
End Sub)
Next
End Sub
IronBarcode -Ansatz:
using IronBarCode;
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 options = new BarcodeReaderOptions
{
Speed = ReadingSpeed.Balanced,
ExpectMultipleBarcodes = true
};
var results = BarcodeReader.Read(ms.ToArray(), options);
foreach (var result in results)
Console.WriteLine($"{result.Format}: {result.Value}");
}
using IronBarCode;
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 options = new BarcodeReaderOptions
{
Speed = ReadingSpeed.Balanced,
ExpectMultipleBarcodes = true
};
var results = BarcodeReader.Read(ms.ToArray(), options);
foreach (var result in results)
Console.WriteLine($"{result.Format}: {result.Value}");
}
Imports IronBarCode
Imports System.IO
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 options As New BarcodeReaderOptions With {
.Speed = ReadingSpeed.Balanced,
.ExpectMultipleBarcodes = True
}
Dim results = BarcodeReader.Read(ms.ToArray(), options)
For Each result In results
Console.WriteLine($"{result.Format}: {result.Value}")
Next
End Using
End Using
End Sub
ExpectMultipleBarcodes = true teilt dem Leser mit, nach dem ersten gefundenen Barcode weiter zu scannen. Ohne diese Option wird beim ersten Treffer eine Antwort zurückgegeben, was bei Szenarien mit nur einem Barcode schneller ist.
iOS UPC-A-Fix: Normalisierungs-Workaround entfernen
Falls Ihre Codebasis die UPC-A-Lösung mit der führenden Null enthält, entfernen Sie diese vollständig. IronBarcode liefert ohne manuelle Eingriffe den korrekten 12-stelligen Wert.
BarcodeScanning.MAUI-Ansatz – Workaround vorhanden:
private void OnBarcodeDetected(object sender, OnDetectionFinishedEventArg e)
{
var barcode = e.BarcodeResults.FirstOrDefault();
if (barcode == null) return;
var value = barcode.DisplayValue;
// Workaround: Apple Vision returns 13 digits for UPC-A
if (barcode.BarcodeFormat == BarcodeFormats.Upca && value.Length == 13)
value = value.Substring(1);
ProcessBarcode(value, barcode.BarcodeFormat.ToString());
}
private void OnBarcodeDetected(object sender, OnDetectionFinishedEventArg e)
{
var barcode = e.BarcodeResults.FirstOrDefault();
if (barcode == null) return;
var value = barcode.DisplayValue;
// Workaround: Apple Vision returns 13 digits for UPC-A
if (barcode.BarcodeFormat == BarcodeFormats.Upca && value.Length == 13)
value = value.Substring(1);
ProcessBarcode(value, barcode.BarcodeFormat.ToString());
}
Private Sub OnBarcodeDetected(sender As Object, e As OnDetectionFinishedEventArg)
Dim barcode = e.BarcodeResults.FirstOrDefault()
If barcode Is Nothing Then Return
Dim value = barcode.DisplayValue
' Workaround: Apple Vision returns 13 digits for UPC-A
If barcode.BarcodeFormat = BarcodeFormats.Upca AndAlso value.Length = 13 Then
value = value.Substring(1)
End If
ProcessBarcode(value, barcode.BarcodeFormat.ToString())
End Sub
IronBarcode Ansatz – kein Workaround erforderlich:
using IronBarCode;
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();
if (first == null) return;
// result.Value is the correct 12-digit UPC-A — no normalization needed
ProcessBarcode(first.Value, first.Format.ToString());
}
using IronBarCode;
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();
if (first == null) return;
// result.Value is the correct 12-digit UPC-A — no normalization needed
ProcessBarcode(first.Value, first.Format.ToString());
}
Imports IronBarCode
Imports System.IO
Imports System.Linq
Imports System.Threading.Tasks
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())
Dim first = results.FirstOrDefault()
If first Is Nothing Then Return
' result.Value is the correct 12-digit UPC-A — no normalization needed
ProcessBarcode(first.Value, first.Format.ToString())
End Using
End Using
End Sub
Löschen Sie alle Übereinstimmungen von BarcodeFormats.Upca, die mit Substring(1) gepaart sind — dieser Code ist nach der Migration überflüssig.
Hinzufügen von Datei- und PDF-Unterstützung
BarcodeScanning.Native.Maui bietet keine Entsprechung für die Eingabe von Dateien oder PDFs. Falls es sich hierbei um eine neue Anforderung handelt, die zum Zeitpunkt der Migration erfüllt werden muss:
BarcodeScanning.MAUI-Ansatz:
//Neinequivalent exists — BarcodeScanning.Native.Maui cannot read from files or PDFs
//Neinequivalent exists — BarcodeScanning.Native.Maui cannot read from files or PDFs
'No equivalent exists — BarcodeScanning.Native.Maui cannot read from files or PDFs
IronBarcode -Ansatz:
using IronBarCode;
// Read from a file the user picked with 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 results = BarcodeReader.Read(file.FullPath);
foreach (var result in results)
ResultLabel.Text += $"\n{result.Format}: {result.Value}";
}
// Read barcodes from a PDF directly — no intermediate image step
private void ReadPdfBarcodes()
{
var results = BarcodeReader.Read("shipment-manifest.pdf");
foreach (var result in results)
Console.WriteLine($"{result.Format}: {result.Value}");
}
using IronBarCode;
// Read from a file the user picked with 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 results = BarcodeReader.Read(file.FullPath);
foreach (var result in results)
ResultLabel.Text += $"\n{result.Format}: {result.Value}";
}
// Read barcodes from a PDF directly — no intermediate image step
private void ReadPdfBarcodes()
{
var results = BarcodeReader.Read("shipment-manifest.pdf");
foreach (var result in results)
Console.WriteLine($"{result.Format}: {result.Value}");
}
Imports IronBarCode
' Read from a file the user picked with 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 results = BarcodeReader.Read(file.FullPath)
For Each result In results
ResultLabel.Text &= vbCrLf & $"{result.Format}: {result.Value}"
Next
End Sub
' Read barcodes from a PDF directly — no intermediate image step
Private Sub ReadPdfBarcodes()
Dim results = BarcodeReader.Read("shipment-manifest.pdf")
For Each result In results
Console.WriteLine($"{result.Format}: {result.Value}")
Next
End Sub
Die IronBarcode Dokumentation zum Lesen von PDFs behandelt die Unterstützung mehrseitiger PDFs und die Auswahl von Seitenbereichen.
Serverseitige Barcode-Verarbeitung
Wenn Ihre Anwendung eine Backend-ASP.NET-API hat, die ebenfalls Barcode-Verarbeitung benötigt, läuft derselbe BarcodeReader.Read() Aufruf dort ohne Modifikation. BarcodeScanning.Native.Maui hat kein serverseitiges Äquivalent.
BarcodeScanning.MAUI-Ansatz:
//Neinequivalent exists — BarcodeScanning.Native.Maui is a camera UI control
// and cannot run in a server process
//Neinequivalent exists — BarcodeScanning.Native.Maui is a camera UI control
// and cannot run in a server process
'No equivalent exists — BarcodeScanning.Native.Maui is a camera UI control
' and cannot run in a server process
IronBarcode -Ansatz:
using IronBarCode;
// ASP.NET endpoint — reads barcodes from an uploaded file
[HttpPost("scan")]
public async Task<IActionResult> ScanBarcode(IFormFile file)
{
using var ms = new MemoryStream();
await file.CopyToAsync(ms);
var results = BarcodeReader.Read(ms.ToArray());
var values = results.Select(r => new { r.Value, Format = r.Format.ToString() });
return Ok(values);
}
using IronBarCode;
// ASP.NET endpoint — reads barcodes from an uploaded file
[HttpPost("scan")]
public async Task<IActionResult> ScanBarcode(IFormFile file)
{
using var ms = new MemoryStream();
await file.CopyToAsync(ms);
var results = BarcodeReader.Read(ms.ToArray());
var values = results.Select(r => new { r.Value, Format = r.Format.ToString() });
return Ok(values);
}
Imports IronBarCode
Imports Microsoft.AspNetCore.Mvc
Imports System.IO
Imports System.Threading.Tasks
' ASP.NET endpoint — reads barcodes from an uploaded file
<HttpPost("scan")>
Public Async Function ScanBarcode(file As IFormFile) As Task(Of IActionResult)
Using ms As New MemoryStream()
Await file.CopyToAsync(ms)
Dim results = BarcodeReader.Read(ms.ToArray())
Dim values = results.Select(Function(r) New With {Key .Value = r.Value, Key .Format = r.Format.ToString()})
Return Ok(values)
End Using
End Function
Das gleiche Paket, die gleiche API, das gleiche Verhalten – auf Mobilgeräten und Servern.
Barcodes generieren
BarcodeScanning.Native.Maui verfügt über keine Generierungs-API. IronBarcode generiert mehrere Formate.
BarcodeScanning.MAUI-Ansatz:
//Neinequivalent exists — BarcodeScanning.Native.Maui cannot generate barcodes
//Neinequivalent exists — BarcodeScanning.Native.Maui cannot generate barcodes
'Neinequivalent exists — BarcodeScanning.Native.Maui cannot generate barcodes
IronBarcode -Ansatz:
using IronBarCode;
// QR code
QRCodeWriter.CreateQrCode("https://example.com/product/12345", 500)
.SaveAsPng("qr.png");
// Code128 barcode sized to specific dimensions
BarcodeWriter.CreateBarcode("ITEM-98765", BarcodeEncoding.Code128)
.ResizeTo(400, 100)
.SaveAsPng("label.png");
// Get bytes for returning from an API or storing in a database
byte[] barcodeBytes = BarcodeWriter.CreateBarcode("ITEM-98765", BarcodeEncoding.Code128)
.ToPngBinaryData();
using IronBarCode;
// QR code
QRCodeWriter.CreateQrCode("https://example.com/product/12345", 500)
.SaveAsPng("qr.png");
// Code128 barcode sized to specific dimensions
BarcodeWriter.CreateBarcode("ITEM-98765", BarcodeEncoding.Code128)
.ResizeTo(400, 100)
.SaveAsPng("label.png");
// Get bytes for returning from an API or storing in a database
byte[] barcodeBytes = BarcodeWriter.CreateBarcode("ITEM-98765", BarcodeEncoding.Code128)
.ToPngBinaryData();
Imports IronBarCode
' QR code
QRCodeWriter.CreateQrCode("https://example.com/product/12345", 500) _
.SaveAsPng("qr.png")
' Code128 barcode sized to specific dimensions
BarcodeWriter.CreateBarcode("ITEM-98765", BarcodeEncoding.Code128) _
.ResizeTo(400, 100) _
.SaveAsPng("label.png")
' Get bytes for returning from an API or storing in a database
Dim barcodeBytes As Byte() = BarcodeWriter.CreateBarcode("ITEM-98765", BarcodeEncoding.Code128) _
.ToPngBinaryData()
Die IronBarcode Generierungsdokumentation umfasst alle unterstützten Formate und Styling-Optionen.
BarcodeScanning.MAUI API zu IronBarcode Mapping-Referenz
| BarcodeScanning.Native.Maui | IronBarcode |
|---|---|
CameraView XAML-Steuerelement |
Entfernen — verwenden Sie Button + MediaPicker.CapturePhotoAsync() |
OnDetectionFinished Ereignis |
BarcodeReader.Read(imageBytes) Rückgabewert |
OnDetectionFinishedEventArg e |
IEnumerable-Ergebnis von BarcodeReader.Read() |
e.BarcodeResults |
Rückgabewert von BarcodeReader.Read() |
e.BarcodeResults.FirstOrDefault() |
results.FirstOrDefault() |
barcode.DisplayValue |
result.Value |
barcode.BarcodeFormat |
result.Format |
BarcodeFormats="All" |
Automatische Erkennung – keine Konfiguration erforderlich |
CameraEnabled="True" |
await MediaPicker.CapturePhotoAsync() |
| Nur iOS + Android | iOS, Android, Windows, macOS MAUI |
| Keine Dateieingabe | BarcodeReader.Read(filePath) |
| Keine PDF-Eingabe | BarcodeReader.Read("document.pdf") |
| Keine Generation | BarcodeWriter.CreateBarcode() / QRCodeWriter.CreateQrCode() |
| iOS UPC-A gibt 13 Ziffern zurück | Gibt die korrekten 12 Ziffern zurück – keine Normalisierung erforderlich |
| PDF417 unzuverlässig | Unterstützt |
Gängige Migrationsprobleme und Lösungen
Problem 1: Verlust der Live-Sucher-Erfahrung
BarcodeScanning.MAUI: Die CameraView Steuerung bettete eine Echtzeit-Kameravorschau direkt in die MAUI-Seite ein. Der Benutzer konnte das Kamerabild sehen und auf einen Barcode zielen – die Erkennung erfolgte automatisch ohne Knopfdruck.
Lösung: MediaPicker.CapturePhotoAsync() zeigt stattdessen den Plattformkamera-Bildschirm an. Für die meisten Geschäftsprozesse ist dies akzeptabel. Für Verbraucher-Apps, die eine kontinuierliche Live-Vorschau erfordern, können Kamerarahmen direkt an BarcodeReader.Read() übergeben werden:
using IronBarCode;
// Continuous scanning: pass camera frame bytes to BarcodeReader.Read()
// (frame capture depends on your MAUI camera frame source)
private void ProcessCameraFrame(byte[] frameBytes)
{
var results = BarcodeReader.Read(frameBytes);
if (results.Any())
{
var first = results.First();
MainThread.BeginInvokeOnMainThread(() =>
ResultLabel.Text = first.Value);
}
}
using IronBarCode;
// Continuous scanning: pass camera frame bytes to BarcodeReader.Read()
// (frame capture depends on your MAUI camera frame source)
private void ProcessCameraFrame(byte[] frameBytes)
{
var results = BarcodeReader.Read(frameBytes);
if (results.Any())
{
var first = results.First();
MainThread.BeginInvokeOnMainThread(() =>
ResultLabel.Text = first.Value);
}
}
Imports IronBarCode
' Continuous scanning: pass camera frame bytes to BarcodeReader.Read()
' (frame capture depends on your MAUI camera frame source)
Private Sub ProcessCameraFrame(frameBytes As Byte())
Dim results = BarcodeReader.Read(frameBytes)
If results.Any() Then
Dim first = results.First()
MainThread.BeginInvokeOnMainThread(Sub()
ResultLabel.Text = first.Value
End Sub)
End If
End Sub
Hierfür muss eine Kamerabildquelle separat von IronBarcode angeschlossen werden. Bevor Sie diesen Weg einschlagen, sollten Sie abwägen, ob eine Live-Vorschau wirklich erforderlich ist oder ob die Systemkamera-Benutzeroberfläche ausreichend ist.
Problem 2: Änderungen am Eigenschaftsnamen und Enum der Klasse e.BarcodeResults
BarcodeScanning.MAUI: barcode.DisplayValue gibt den decodierten String zurück; barcode.BarcodeFormat gibt einen Enum-Wert der BarcodeScanning-Bibliothek zurück.
Lösung: Ersetzen Sie DisplayValue durch result.Value und barcode.BarcodeFormat durch result.Format. Das Iterationsmuster ist dasselbe:
// Before
foreach (var barcode in e.BarcodeResults)
Console.WriteLine(barcode.DisplayValue);
// After
var results = BarcodeReader.Read(imageBytes);
foreach (var result in results)
Console.WriteLine(result.Value);
// Before
foreach (var barcode in e.BarcodeResults)
Console.WriteLine(barcode.DisplayValue);
// After
var results = BarcodeReader.Read(imageBytes);
foreach (var result in results)
Console.WriteLine(result.Value);
' Before
For Each barcode In e.BarcodeResults
Console.WriteLine(barcode.DisplayValue)
Next
' After
Dim results = BarcodeReader.Read(imageBytes)
For Each result In results
Console.WriteLine(result.Value)
Next
Problem 3: Thread-Marshaling für UI-Aktualisierungen
BarcodeScanning.MAUI: OnDetectionFinished wird in einem Hintergrundthread ausgelöst, sodass alle UI-Updates MainThread.BeginInvokeOnMainThread() erfordern.
Lösung: Mit dem MediaPicker + async Muster erfolgt die Fortsetzung nach await im aufrufenden Kontext — typischerweise der Hauptthread. Die MainThread.BeginInvokeOnMainThread() Wrapper um die Ergebnisausgabe können in der Regel entfernt werden, was den Handler-Code vereinfacht.
Ausgabe 4: MAUI-Kameraberechtigungen
BarcodeScanning.MAUI: Das Paket fügt Kamera-Berechtigungen zu AndroidManifest.xml und Info.plist automatisch als Teil seiner Einrichtung hinzu.
Lösung: Da IronBarcode MediaPicker verwendet, müssen die Standard-MAUI-Kamera-Berechtigungen manuell vorhanden sein. Dies sind die gleichen Berechtigungen, die jede MAUI-App für MediaPicker.CapturePhotoAsync() benötigt und sind typischerweise bereits vorhanden. Verifizieren Sie, dass android.permission.CAMERA in AndroidManifest.xml deklariert ist und NSCameraUsageDescription in Info.plist gesetzt ist, bevor das Gerät getestet wird.
BarcodeScanning.MAUI-Migrationscheckliste
Vor der Migration anfallende Aufgaben
Führen Sie diese Suchvorgänge durch, um alle Verwendungen von BarcodeScanning.Native.Maui zu finden, bevor Sie Änderungen vornehmen:
grep -rn "using BarcodeScanning" --include="*.cs" .
grep -rn "using BarcodeScanning" --include="*.xaml" .
grep -rn "CameraView" --include="*.cs" .
grep -rn "CameraView" --include="*.xaml" .
grep -rn "OnDetectionFinished" --include="*.cs" .
grep -rn "OnDetectionFinishedEventArg" --include="*.cs" .
grep -rn "e\.BarcodeResults" --include="*.cs" .
grep -rn "DisplayValue" --include="*.cs" .
grep -rn "BarcodeFormats\.Upca" --include="*.cs" .
grep -rn "scanner:" --include="*.xaml" .
grep -rn "using BarcodeScanning" --include="*.cs" .
grep -rn "using BarcodeScanning" --include="*.xaml" .
grep -rn "CameraView" --include="*.cs" .
grep -rn "CameraView" --include="*.xaml" .
grep -rn "OnDetectionFinished" --include="*.cs" .
grep -rn "OnDetectionFinishedEventArg" --include="*.cs" .
grep -rn "e\.BarcodeResults" --include="*.cs" .
grep -rn "DisplayValue" --include="*.cs" .
grep -rn "BarcodeFormats\.Upca" --include="*.cs" .
grep -rn "scanner:" --include="*.xaml" .
Dokumentieren Sie jeden Treffer. Beachten Sie, welche Dateien CameraView XAML-Verwendung enthalten (erfordern XAML-Änderungen) im Gegensatz zu denen, die nur Code-Behind-Änderungen enthalten. Identifizieren Sie alle UPC-A-Normalisierungs-Workarounds, die nach der Migration gelöscht werden müssen.
Aufgaben der Code-Aktualisierung
- Entfernen Sie das
BarcodeScanning.Native.MauiNuGet-Paket - Installieren Sie das
IronBarcodeNuGet-Paket - Fügen Sie
IronBarCode.License.LicenseKey = "YOUR-LICENSE-KEY";inMauiProgram.csoderApp.xaml.cshinzu - Ersetzen Sie
using BarcodeScanning;durchusing IronBarCode;in allen.csDateien - Entfernen Sie
xmlns:scanner="..."Namespace-Deklarationen aus allen XAML-Dateien - Ersetzen Sie
scanner:CameraViewSteuerelemente in XAML durch einButton, dasMediaPicker.CapturePhotoAsync()auslöst - Entfernen Sie die Verkabelung von
OnDetectionFinished="..."Ereignissen aus XAML - Ersetzen Sie
OnDetectionFinishedEreignishandler durchasyncButton-Klick-Handler unter Verwendung vonBarcodeReader.Read() - Ersetzen Sie
barcode.DisplayValuedurchresult.Valueüberall - Ersetzen Sie
barcode.BarcodeFormatdurchresult.Formatüberall - Löschen Sie alle
BarcodeFormats.Upca+Substring(1)Normalisierungsumgehungen - Fügen Sie
ExpectMultipleBarcodes = truezuBarcodeReaderOptionshinzu, wo zuvor die Mehrfach-Barcode-Erkennung aufe.BarcodeResultsangewiesen war, um mehrere Elemente zurückzugeben - Entfernen Sie
MainThread.BeginInvokeOnMainThread()Wrapper aus dem Code zur Ergebnisausgabe, wo das asynchrone Muster sie unnötig macht - Verifizieren Sie, dass
AndroidManifest.xmlundInfo.plistKamera-Berechtigungen vorhanden sind
Post-Migrationstests
- Überprüfen Sie, ob das Scannen von Barcodes unter iOS funktioniert und ob UPC-A-Werte als 12-stellige Zeichenketten ohne führende Nullen zurückgegeben werden.
- Überprüfen Sie, ob das Scannen von Android-Barcodes für alle in der Anwendung verwendeten Formate korrekte Werte liefert.
- Überprüfen Sie, ob das Scannen von Barcodes unter Windows MAUI funktioniert, wenn Windows ein Build-Ziel ist.
- Testen Sie das Scannen von PDF417 anhand echter Versandetiketten, Führerscheine oder Bordkarten, falls diese verwendet werden.
- Testen Sie Mehrfach-Barcode-Szenarien mit
ExpectMultipleBarcodes = trueund bestätigen Sie, dass alle Barcodes in einem Bild zurückgegeben werden - Verifizieren Sie, dass die Dateiauswahl-Scanfunktion (
BarcodeReader.Read(filePath)) auf allen MAUI-Zielen funktioniert - Überprüfen Sie die PDF-Barcode-Lesefunktion, falls diese Funktion im Zuge der Migration neu hinzugefügt wurde.
- Bestätigen Sie, dass die serverseitige
BarcodeReader.Read()die richtigen Ergebnisse liefert, falls eine Backend-Komponente hinzugefügt wurde - Führen Sie alle vorhandenen automatisierten Tests aus und vergleichen Sie die Barcode-Wertausgaben mit den Baselines vor der Migration.
Wichtigste Vorteile der Migration zu IronBarcode
Vollständige Windows MAUI-Unterstützung: IronBarcode läuft auf allen vier MAUI-Zielplattformen – iOS, Android, Windows und macOS – mit demselben Code und demselben Paket. Keine plattformspezifische Barcode-Implementierung ist für Windows notwendig, und keine #if WINDOWS Blöcke sind im Anwendungscode erforderlich.
Jede Eingabequelle: BarcodeReader.Read() akzeptiert Dateipfade, Byte-Arrays, Streams und PDF-Dokumente. Bei jedem Barcode-Szenario – Kameraaufnahme, Datei-Upload, Galeriebild, serverseitige PDF-Verarbeitung – wird dieselbe statische Methode mit demselben Ergebnistyp verwendet.
Korrekte UPC-A-Werte: IronBarcode liefert unter iOS den korrekten 12-stelligen UPC-A-Wert ohne Normalisierungscode in der Anwendung. Historische UPC-A-Daten, die aufgrund des Verhaltens von BarcodeScanning.Native.Maui mit einer führenden Null gespeichert werden, beeinträchtigen die Genauigkeit der nach der Migration gelesenen Werte nicht.
Zuverlässiges PDF417: PDF417 wird vollständig unterstützt und lässt sich zuverlässig lesen. Versandetiketten, Führerscheine und Bordkarten können ohne die in den GitHub -Issues von BarcodeScanning.Native.Maui dokumentierte Einschränkung "die meisten Scans finden nie statt" gescannt werden.
Barcode-Generierung: BarcodeWriter.CreateBarcode() und QRCodeWriter.CreateQrCode() erzeugen Code128, QR, DataMatrix und andere Formate als PNG-Dateien oder Byte-Arrays. Generierung und Auslesen sind aus demselben Paket ohne zusätzliche Abhängigkeiten möglich.
Serverseitige Bereitstellung: Der gleiche BarcodeReader.Read() Aufruf läuft in ASP.NET, Azure Functions, Docker-Containern und AWS Lambda. Mobile und serverseitige Barcode-Logik können dieselbe API, dieselbe Formatunterstützung und denselben Ergebnistyp nutzen, ohne dass zwei separate Barcode-Implementierungen gepflegt werden müssen.
Häufig gestellte Fragen
Warum sollte ich von BarcodeScanning.MAUI auf IronBarcode umsteigen?
Zu den häufigsten Gründen gehören die Vereinfachung der Lizenzierung (Beseitigung der Komplexität von SDK und Laufzeitschlüsseln), die Beseitigung von Durchsatzbeschränkungen, die Verbesserung der nativen PDF-Unterstützung, die Verbesserung der Docker/CI/CD-Bereitstellung und die Verringerung von API-Boilerplate im Produktionscode.
Wie kann ich BarcodeScanning.MAUI API-Aufrufe durch IronBarcode ersetzen?
Ersetzen Sie Instanzerstellung und Lizenzierung durch IronBarCode.License.LicenseKey = "key". Ersetzen Sie die Leseaufrufe durch BarcodeReader.Read(path) und die Schreibaufrufe durch BarcodeWriter.CreateBarcode(data, encoding). Statische Methoden erfordern keine Instanzverwaltung.
Wie viel Code ändert sich bei der Migration von BarcodeScanning.MAUI zu IronBarcode?
Die meisten Migrationen führen zu weniger Codezeilen. Lizenzierungs-Boilerplate, Instanzkonstruktoren und explizite Formatkonfiguration werden entfernt. Zentrale Lese-/Schreibvorgänge werden auf kürzere IronBarcode-Äquivalente mit saubereren Ergebnisobjekten abgebildet.
Muss ich während der Migration sowohl BarcodeScanning.MAUI als auch IronBarcode installiert lassen?
Nein. Die meisten Migrationen sind direkte Ersetzungen und keine Paralleloperationen. Migrieren Sie eine Serviceklasse nach der anderen, ersetzen Sie die NuGet-Referenz und aktualisieren Sie die Instanzierungs- und API-Aufrufmuster, bevor Sie zur nächsten Klasse übergehen.
Wie lautet der NuGet-Paketname für IronBarcode?
Das Paket ist 'IronBarCode' (mit großem B und C). Installieren Sie es mit 'Install-Package IronBarCode' oder 'dotnet add package IronBarCode'. Die using-Anweisung im Code lautet 'using IronBarCode;'.
Wie vereinfacht IronBarcode die Docker-Bereitstellung im Vergleich zu BarcodeScanning.MAUI?
IronBarcode ist ein NuGet-Paket, für das keine externen SDK-Dateien oder Lizenzkonfigurationen erforderlich sind. In Docker setzen Sie die Umgebungsvariable IRONBARCODE_LICENSE_KEY und das Paket übernimmt die Lizenzvalidierung beim Start.
Erkennt IronBarcode nach der Migration von BarcodeScanning.MAUI automatisch alle Barcodeformate?
Ja, IronBarcode erkennt automatisch die Symbologie aller unterstützten Formate. Eine explizite Aufzählung von BarcodeTypes ist nicht erforderlich. Wenn das Format bereits bekannt ist und die Leistung eine Rolle spielt, ermöglicht BarcodeReaderOptions die Einschränkung des Suchraums als eine Optimierung.
Kann IronBarcode Barcodes aus PDFs ohne eine separate Bibliothek lesen?
Ja, BarcodeReader.Read("document.pdf") verarbeitet PDF-Dateien nativ. Die Ergebnisse enthalten PageNumber, Format, Value und Confidence für jeden gefundenen Barcode. Es ist kein externer PDF-Rendering-Schritt erforderlich.
Wie handhabt IronBarcode die parallele Verarbeitung von Barcodes?
Die statischen Methoden von IronBarcode sind zustandslos und thread-sicher. Verwenden Sie Parallel.ForEach direkt über Dateilisten ohne Instanzmanagement pro Thread. BarcodeReaderOptions.MaxParallelThreads steuert das interne Thread-Budget.
Welche Ergebniseigenschaften ändern sich bei der Migration von BarcodeScanning.MAUI zu IronBarcode?
Übliche Umbenennungen: BarcodeValue wird zu Value, BarcodeType wird zu Format. IronBarcode-Ergebnisse fügen auch Confidence und PageNumber hinzu. Eine lösungsweite Such- und Ersetzungsfunktion übernimmt die Umbenennungen im bestehenden Ergebnisverarbeitungscode.
Wie kann ich die IronBarcode-Lizenzierung in einer CI/CD-Pipeline einrichten?
Speichern Sie IRONBARCODE_LICENSE_KEY als Pipeline-Geheimnis und weisen Sie IronBarCode.License.LicenseKey im Startup-Code der Anwendung zu. Ein Geheimnis deckt alle Umgebungen ab, einschließlich Entwicklung, Test, Staging und Produktion.
Unterstützt IronBarcode die Generierung von QR-Codes mit benutzerdefiniertem Styling?
Ja. QRCodeWriter.CreateQrCode() unterstützt benutzerdefinierte Farben über ChangeBarCodeColor(), das Einbetten von Logos über AddBrandLogo(), konfigurierbare Fehlerkorrekturstufen und mehrere Ausgabeformate einschließlich PNG, JPG, PDF und Stream.

