Comment lire des codes-barres à partir de PDF en C#
Passer de BarcodeScanning.Native.Maui à IronBarcode
Ce guide fournit un chemin de migration complet de BarcodeScanning.Native.Maui vers IronBarcode, couvrant le remplacement du modèle d'événement de la caméra, les changements d'espace de noms, des exemples de migration de code et la gestion des scénarios que BarcodeScanning.Native.Maui ne peut pas aborder : Windows MAUI, l'entrée de fichiers et de PDF, le traitement côté serveur et la génération de codes-barres.
Pourquoi migrer depuis BarcodeScanning.MAUI ?
Les équipes migrant depuis BarcodeScanning.Native.Maui signalent les déclencheurs suivants :
Cible MAUI requise pour Windows : BarcodeScanning.Native.Maui encapsule les API natives iOS et Android. Aucune implémentation Windows n'est disponible et aucune n'est prévue. Si votre application MAUI cible Windows en plus d'iOS et d'Android, vous avez besoin d'une bibliothèque qui fonctionne sur les trois plateformes sans branchement spécifique à chaque plateforme.
Ajout de la saisie de fichiers ou de PDF aux exigences : BarcodeScanning.Native.Maui n'accepte que les images de la caméra en direct. Lorsque les utilisateurs doivent télécharger une image depuis leur galerie, ou lorsqu'un point de terminaison côté serveur doit extraire des codes-barres à partir de fichiers PDF, la bibliothèque ne propose aucun chemin de code. Chaque scénario de code-barres, qu'il s'agisse de fichiers ou de PDF, nécessite un outil différent.
Les données UPC-A d'iOS étaient erronées en production : le framework Vision d'Apple renvoie 13 chiffres pour les codes-barres UPC-A (encodage EAN-13). BarcodeScanning.Native.Maui laisse passer ceci sans correction. Si les codes UPC-A étaient stockés avec un zéro initial, les enregistrements d'inventaire, les recherches aux points de vente ou les intégrations de la chaîne d'approvisionnement auraient pu être silencieusement perturbés. Code-barres IronBarcode renvoie la valeur UPC-A à 12 chiffres correcte sans normalisation manuelle.
La numérisation des fichiers PDF417 s'avérait peu fiable : les problèmes signalés sur GitHub par la bibliothèque qualifient le format PDF417 de " très problématique — la plupart des numérisations n'ont jamais lieu ". Pour les étiquettes d'expédition, les permis de conduire et les cartes d'embarquement, cela constitue un obstacle majeur.
Génération nécessaire : BarcodeScanning.Native.Maui ne peut pas générer de codes-barres. Code-barres IronBarcode génère des codes Code128, QR, DataMatrix et autres formats sous forme de fichiers image ou de tableaux d'octets.
Introduction du traitement côté serveur : BarcodeScanning.Native.Maui est un contrôle d'interface utilisateur de caméra ; il ne peut pas s'exécuter dans un processus serveur. Lorsque la lecture des codes-barres côté serveur est requise en plus de la numérisation mobile, Code-barres IronBarcode couvre les deux aspects avec le même package et la même API.
Le problème fondamental
BarcodeScanning.Native.Maui lie entièrement la lecture de vos codes-barres au modèle d'événements de la caméra en direct. Dès qu'une exigence sort de ce modèle, la bibliothèque ne propose rien :
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 accepte tout type de données d'entrée (capture d'écran, fichier, PDF, tableau d'octets) et fonctionne sur toutes les plateformes :
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
Comparaison des fonctionnalités Code-barres IronBarcode et de BarcodeScanning.MAUI
| Fonction | BarcodeScanning.MAUI | Code-barres IronBarcode |
|---|---|---|
| lecture en direct des images de la caméra | Oui — Contrôle CameraView | Non (utilisez MediaPicker pour capturer, puis lire) |
| Viseur de caméra intégré à l'application | Oui — en continu en temps réel | Non — utilise l'interface utilisateur de la caméra système via MediaPicker |
| Lire à partir d'un fichier image | Non | Oui — BarcodeReader.Read(path) |
| Lecture à partir d'un tableau d'octets | Non | Oui — BarcodeReader.Read(bytes) |
| Lecture à partir du flux | Non | Oui — BarcodeReader.Read(stream) |
| Lire le PDF | Non | Oui — BarcodeReader.Read(pdf) |
| génération de codes-barres | Non | Oui — BarcodeWriter + QRCodeWriter |
| Prise en charge de Windows MAUI | Non | Oui |
| Prise en charge d'iOS MAUI | Oui | Oui |
| Prise en charge d'Android MAUI | Oui | Oui |
| Prise en charge de macOS MAUI | Non documenté | Oui |
| Côté serveur / ASP.NET | Non | Oui |
| Docker / Azure / AWS Lambda | Non | Oui |
| Précision du code UPC-A iOS | Renvoie 13 chiffres (bug), nécessite une normalisation manuelle. | Renvoie le code UPC-A à 12 chiffres correct |
| Fiabilité du PDF417 | " La plupart des analyses n'ont jamais lieu " (Problèmes GitHub ) | Prise en charge |
| Détection de plusieurs codes-barres | Oui (multiples par cadre via e.BarcodeResults) |
Oui (ExpectMultipleBarcodes option) |
| Contrôle de la vitesse de lecture | None | ReadingSpeed.Faster / Balanced / Detailed / ExtremeDetail |
| Licence | MIT (logiciel libre et gratuit) | Commercial — Lite 749 $, Plus 1 499 $, Professional 2 999 $, Version Illimitée 5 999 $ |
| Prise en charge du .NET Framework | Non (MAUI uniquement) | Oui — .NET Framework 4.6.2 et versions ultérieures |
Démarrage rapide : Migration de BarcodeScanning.MAUI vers IronBarcode
Étape 1 : Remplacer le package NuGet
Supprimer BarcodeScanning.Native.Maui :
dotnet remove package BarcodeScanning.Native.Maui
dotnet remove package BarcodeScanning.Native.Maui
Installer IronBarcode:
dotnet add package IronBarcode
dotnet add package IronBarcode
Étape 2 : Mise à jour des espaces de noms
Supprimez l'espace de noms BarcodeScanning de tous les fichiers :
// Remove
using BarcodeScanning;
// Remove
using BarcodeScanning;
Imports BarcodeScanning
Ajoutez l'espace de noms IronBarcode :
// Add
using IronBarCode;
// Add
using IronBarCode;
Imports IronBarCode
Dans les fichiers XAML, supprimez la déclaration de l'espace de noms XML scanner: :
xmlns:scanner="clr-namespace:BarcodeScanning;assembly=BarcodeScanning.Native.Maui"
xmlns:scanner="clr-namespace:BarcodeScanning;assembly=BarcodeScanning.Native.Maui"
Étape 3 : initialisation de la licence
Ajoutez l'initialisation de la licence au démarrage de l'application — dans MauiProgram.cs ou App.xaml.cs :
IronBarCode.License.LicenseKey = "YOUR-LICENSE-KEY";
IronBarCode.License.LicenseKey = "YOUR-LICENSE-KEY";
Imports IronBarCode
IronBarCode.License.LicenseKey = "YOUR-LICENSE-KEY"
Exemples de migration de code
Numérisation de la caméra : CameraView vers MediaPicker
Le contrôle CameraView offrait un viseur en temps réel avec détection continue des cadres. Le remplacement Code-barres IronBarcode utilise MediaPicker de MAUI pour ouvrir la caméra système, capturer une photo et traiter l'image résultante.
Approche BarcodeScanning.MAUI — 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>
Approche BarcodeScanning.MAUI — 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
Approche Code-barres IronBarcode — 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>
Approche Code-barres IronBarcode — 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
Ce code fonctionne sur iOS, Android et Windows MAUI sans aucune branche spécifique à la plateforme. L'expérience utilisateur passe d'un viseur intégré à l'application à l'écran natif de la caméra de la plateforme, ce qui convient à la plupart des applications professionnelles. Le guide de lecture Code-barres IronBarcode MAUI couvre des options de configuration supplémentaires.
Gestion de plusieurs codes-barres par scan
Approche BarcodeScanning.MAUI :
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
Approche IronBarcode :
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 indique au lecteur de continuer la numérisation après avoir trouvé le premier code-barres. Sans cette option, l'appel se termine dès la première correspondance, ce qui est plus rapide dans le cas d'un seul code-barres.
Correctif iOS UPC-A : Suppression de la solution de contournement de normalisation
Si votre code source comporte la solution de contournement pour le zéro initial UPC-A, supprimez-la complètement. Code-barres IronBarcode renvoie la valeur correcte à 12 chiffres sans aucune intervention manuelle.
Approche BarcodeScanning.MAUI — solution de contournement en place :
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
Approche Code-barres IronBarcode — aucune solution de contournement nécessaire :
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
Supprimez toutes les correspondances pour BarcodeFormats.Upca associées à Substring(1) — ce code est obsolète après la migration.
Ajout de la prise en charge des fichiers et des PDF
BarcodeScanning.Native.Maui n'a pas d'équivalent pour la saisie de fichiers ou de PDF. S'il s'agit d'une nouvelle exigence à satisfaire au moment de la migration :
Approche BarcodeScanning.MAUI :
// Non equivalent exists — BarcodeScanning.Native.Maui cannot read from files or PDFs
// Non equivalent exists — BarcodeScanning.Native.Maui cannot read from files or PDFs
' Non equivalent exists — BarcodeScanning.Native.Maui cannot read from files or PDFs
Approche IronBarcode :
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
La documentation Code-barres IronBarcode sur la lecture des PDF couvre la prise en charge des PDF multipages et la sélection de plages de pages.
Traitement des codes-barres côté serveur
Si votre application a une API ASP.NET backend qui nécessite également un traitement de code-barres, le même appel BarcodeReader.Read() s'exécute là sans modification. BarcodeScanning.Native.Maui n'a pas d'équivalent côté serveur.
Approche BarcodeScanning.MAUI :
// Non equivalent exists — BarcodeScanning.Native.Maui is a camera UI control
// and cannot run in a server process
// Non equivalent exists — BarcodeScanning.Native.Maui is a camera UI control
// and cannot run in a server process
' Non equivalent exists — BarcodeScanning.Native.Maui is a camera UI control
' and cannot run in a server process
Approche IronBarcode :
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
Le même package, la même API, le même comportement — sur mobile et sur serveur.
Générer des codes-barres
BarcodeScanning.Native.Maui ne possède pas d'API de génération. Code-barres IronBarcode génère plusieurs formats.
Approche BarcodeScanning.MAUI :
// Non equivalent exists — BarcodeScanning.Native.Maui cannot generate barcodes
// Non equivalent exists — BarcodeScanning.Native.Maui cannot generate barcodes
' Non equivalent exists — BarcodeScanning.Native.Maui cannot generate barcodes
Approche IronBarcode :
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()
La documentation relative à la génération de IronBarcode couvre tous les formats pris en charge et les options de style.
Référence de correspondance entre l'API BarcodeScanning.MAUI et IronBarcode
| BarcodeScanning.Native.Maui | Code-barres IronBarcode |
|---|---|
CameraView contrôle XAML |
Supprimez — utilisez Button + MediaPicker.CapturePhotoAsync() |
OnDetectionFinished événement |
BarcodeReader.Read(imageBytes) valeur de retour |
OnDetectionFinishedEventArg e |
Résultat IEnumerable de BarcodeReader.Read() |
e.BarcodeResults |
Valeur de retour de BarcodeReader.Read() |
e.BarcodeResults.FirstOrDefault() |
results.FirstOrDefault() |
barcode.DisplayValue |
result.Value |
barcode.BarcodeFormat |
result.Format |
BarcodeFormats="All" |
Détection automatique — aucune configuration requise |
CameraEnabled="True" |
await MediaPicker.CapturePhotoAsync() |
| iOS et Android uniquement | iOS, Android, Windows, macOS MAUI |
| Aucun fichier d'entrée | BarcodeReader.Read(filePath) |
| Aucune entrée PDF | BarcodeReader.Read("document.pdf") |
| Aucune génération | BarcodeWriter.CreateBarcode() / QRCodeWriter.CreateQrCode() |
| Le code UPC-A d'iOS renvoie 13 chiffres | Renvoie les 12 chiffres corrects — aucune normalisation nécessaire |
| PDF417 non fiable | Prise en charge |
Problèmes de migration courants et solutions
Problème n° 1 : L'expérience de visée directe perdue
BarcodeScanning.MAUI : Le contrôle CameraView intégrait un aperçu caméra en temps réel directement dans la page MAUI. Les utilisateurs pouvaient visualiser le flux vidéo de la caméra et viser un code-barres ; la détection s'effectuait automatiquement, sans qu'il soit nécessaire d'appuyer sur un bouton.
Solution : MediaPicker.CapturePhotoAsync() affiche l'écran de la caméra de la plateforme à la place. Pour la plupart des flux de travail d'entreprise, cela est acceptable. Pour les applications consommateurs qui nécessitent un aperçu en direct continu, les cadres de la caméra peuvent être passés directement à BarcodeReader.Read() :
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
Cela nécessite de connecter une source d'images de caméra séparément d' IronBarcode. Avant d'opter pour cette solution, évaluez si un aperçu en direct est réellement nécessaire ou si l'interface utilisateur de la caméra système est suffisante.
Problème n° 2 : Modifications apportées au nom et à l'énumération de la propriété e.BarcodeResults
BarcodeScanning.MAUI : barcode.DisplayValue renvoie la chaîne décodée ; barcode.BarcodeFormat renvoie une valeur énumérée de la bibliothèque BarcodeScanning.
Solution : Remplacez DisplayValue par result.Value et barcode.BarcodeFormat par result.Format . Le schéma d'itération est le même :
// 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
Problème 3 : Sérialisation des threads pour les mises à jour de l'interface utilisateur
BarcodeScanning.MAUI : OnDetectionFinished se déclenche sur un thread en arrière-plan, donc toutes les mises à jour de l'interface utilisateur nécessitent MainThread.BeginInvokeOnMainThread().
Solution : Avec le modèle MediaPicker + async, la continuation après await revient sur le contexte d'appel — typiquement le fil principal. Les wrappers MainThread.BeginInvokeOnMainThread() autour de l'affichage des résultats peuvent généralement être supprimés, simplifiant ainsi le code du gestionnaire.
Problème n° 4 : Autorisations de la caméra MAUI
BarcodeScanning.MAUI : Le package ajoute automatiquement les autorisations de caméra à AndroidManifest.xml et Info.plist dans le cadre de son installation.
Solution : Avec Code-barres IronBarcode utilisant MediaPicker, les autorisations de caméra standard de MAUI doivent être présentes manuellement. Ce sont les mêmes autorisations dont toute application MAUI a besoin pour MediaPicker.CapturePhotoAsync() et elles sont généralement déjà en place. Vérifiez que android.permission.CAMERA est déclaré dans AndroidManifest.xml et que NSCameraUsageDescription est défini dans Info.plist avant de tester sur l'appareil.
Liste de contrôle de migration BarcodeScanning.MAUI
Tâches préalables à la migration
Exécutez ces recherches pour trouver toutes les utilisations de BarcodeScanning.Native.Maui avant d'apporter des modifications :
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" .
Documentez chaque impact. Notez quels fichiers contiennent une utilisation de CameraView dans XAML (nécessitent des modifications XAML) versus ceux qui ne contiennent que des modifications de code-behind. Identifier les solutions de contournement pour la normalisation UPC-A qui doivent être supprimées après la migration.
Tâches de mise à jour du code
- Supprimez le package NuGet
BarcodeScanning.Native.Maui - Installez le package NuGet
IronBarcode - Ajoutez
IronBarCode.License.LicenseKey = "YOUR-LICENSE-KEY";dansMauiProgram.csouApp.xaml.cs - Remplacez
using BarcodeScanning;parusing IronBarCode;dans tous les fichiers.cs - Supprimez les déclarations de l'espace de noms
xmlns:scanner="..."de tous les fichiers XAML - Remplacez les contrôles
scanner:CameraViewdans XAML par unButtondéclenchantMediaPicker.CapturePhotoAsync() - Supprimez le câblage d'événements
OnDetectionFinished="..."de XAML - Remplacez les gestionnaires d'événements
OnDetectionFinishedpar des gestionnaires de clics boutonsasyncutilisantBarcodeReader.Read() - Remplacez
barcode.DisplayValueparresult.Valuepartout - Remplacez
barcode.BarcodeFormatparresult.Formatpartout - Supprimez toutes les solutions de contournement de normalisation
BarcodeFormats.Upca+Substring(1) - Ajoutez
ExpectMultipleBarcodes = trueàBarcodeReaderOptionsoù la détection multi-code-barres s'appuyait auparavant sure.BarcodeResultsretournant plusieurs éléments - Supprimez les wrappers
MainThread.BeginInvokeOnMainThread()du code d'affichage des résultats lorsque le modèle asynchrone les rend inutiles - Vérifiez que les autorisations de caméra
AndroidManifest.xmletInfo.plistsont présentes
Test de post-migration
- Vérifier que la lecture des codes-barres iOS fonctionne et que les valeurs UPC-A sont renvoyées sous forme de chaînes de 12 chiffres sans zéros non significatifs.
- Vérifier que la lecture des codes-barres sous Android produit des valeurs correctes pour tous les formats utilisés dans l'application.
- Vérifiez que la lecture des codes-barres MAUI sous Windows fonctionne si Windows est une cible de compilation
- Tester la numérisation PDF417 sur de véritables étiquettes d'expédition, permis de conduire ou cartes d'embarquement, le cas échéant.
- Testez les scénarios multi-code-barres avec
ExpectMultipleBarcodes = trueet confirmez que tous les codes-barres d'une image sont retournés - Vérifiez que l'analyse du sélecteur de fichiers (
BarcodeReader.Read(filePath)) fonctionne sur toutes les cibles MAUI - Vérifier si la lecture des codes-barres PDF est une nouvelle fonctionnalité ajoutée lors de la migration
- Confirmez que
BarcodeReader.Read()côté serveur produit les résultats corrects si un composant backend a été ajouté - Exécutez les tests automatisés existants et comparez les valeurs des codes-barres aux valeurs de référence avant migration.
Principaux avantages de la migration vers IronBarcode
Prise en charge complète de MAUI sous Windows : Code-barres IronBarcode fonctionne sur les quatre plateformes MAUI (iOS, Android, Windows et macOS) en utilisant le même code et le même package. Aucune implémentation de code-barres spécifique à la plateforme n'est nécessaire pour Windows, et aucun bloc #if WINDOWS n'est requis dans le code de l'application.
Toute source d'entrée : BarcodeReader.Read() accepte les chemins de fichiers, les tableaux d'octets, les flux et les documents PDF. Quel que soit le scénario de code-barres (capture par appareil photo, téléchargement de fichier, image de galerie, traitement PDF côté serveur), il utilise la même méthode statique avec le même type de résultat.
Valeurs UPC-A correctes : Code-barres IronBarcode renvoie la valeur UPC-A à 12 chiffres correcte sur iOS sans aucun code de normalisation dans l'application. Les données UPC-A historiques stockées avec un zéro initial en raison du comportement de BarcodeScanning.Native.Maui n'affectent pas la précision des valeurs lues après la migration.
PDF417 fiable : le format PDF417 est entièrement pris en charge et sa lecture est fiable. Les étiquettes d'expédition, les permis de conduire et les cartes d'embarquement sont scannés sans la limitation " la plupart des scans n'ont jamais lieu " documentée dans les problèmes GitHub de BarcodeScanning.Native.Maui.
Génération de code-barres : BarcodeWriter.CreateBarcode() et QRCodeWriter.CreateQrCode() génèrent des Code128, QR, DataMatrix et d'autres formats sous forme de fichiers PNG ou de tableaux d'octets. La génération et la lecture sont disponibles à partir du même package, sans dépendance supplémentaire.
Déploiement côté serveur : Le même appel BarcodeReader.Read() fonctionne dans ASP.NET, Fonctions Azure, containers Docker et AWS Lambda. La logique des codes-barres mobiles et serveur peut partager la même API, la même prise en charge des formats et le même type de résultat sans nécessiter deux implémentations de codes-barres distinctes.
Questions Fréquemment Posées
Pourquoi devrais-je migrer de BarcodeScanning.MAUI vers IronBarcode ?
Les raisons les plus courantes sont la simplification des licences (suppression de la complexité du SDK + de la clé d'exécution), l'élimination des limites de débit, la prise en charge native des PDF, l'amélioration du déploiement Docker/CI/CD et la réduction de l'API boilerplate dans le code de production.
Comment remplacer les appels de l'API BarcodeScanning.MAUI par IronBarcode ?
Remplacer la création d'instance et le modèle de licence par IronBarCode.License.LicenseKey = "key". Remplacer les appels au lecteur par BarcodeReader.Read(path) et les appels à l'écrivain par BarcodeWriter.CreateBarcode(data, encoding). Les méthodes statiques ne nécessitent aucune gestion d'instance.
Quelle quantité de code change lors de la migration de BarcodeScanning.MAUI vers IronBarcode ?
La plupart des migrations permettent de réduire le nombre de lignes de code. Les modèles de licence, les constructeurs d'instances et la configuration explicite des formats sont supprimés. Les principales opérations de lecture/écriture sont converties en équivalents plus courts d'IronBarcode avec des objets de résultat plus propres.
Ai-je besoin de garder à la fois BarcodeScanning.MAUI et IronBarcode installés pendant la migration ?
Non. La plupart des migrations sont des remplacements directs plutôt que des opérations parallèles. Migrez une classe de service à la fois, remplacez la référence NuGet et mettez à jour les modèles d'instanciation et d'appel d'API avant de passer à la classe suivante.
Quel est le nom du package NuGet pour IronBarcode ?
Le paquet est "IronBarcode" (avec un B et un C majuscules). Installez-le avec "Install-Package IronBarCode" ou "dotnet add package IronBarCode". La directive using dans le code est "using IronBarCode ;".
Comment IronBarcode simplifie-t-il le déploiement de Docker par rapport à BarcodeScanning.MAUI ?
IronBarcode est un package NuGet sans fichiers SDK externes ni configuration de licence montée. Dans Docker, définissez la variable d'environnement IRONBARCODE_LICENSE_KEY et le paquetage gère la validation de la licence au démarrage.
IronBarcode détecte-t-il automatiquement tous les formats de codes-barres après avoir migré de BarcodeScanning.MAUI ?
Oui. IronBarcode détecte automatiquement la symbologie dans tous les formats pris en charge. L'énumération explicite des BarcodeTypes n'est pas nécessaire. Si le format est déjà connu et que la performance est importante, BarcodeReaderOptions permet de restreindre l'espace de recherche en tant qu'optimisation.
IronBarcode peut-il lire des codes-barres à partir de PDF sans bibliothèque séparée ?
Oui, BarcodeReader.Read("document.pdf") traite les fichiers PDF de manière native. Les résultats incluent le numéro de page, le format, la valeur et la confiance pour chaque code-barres trouvé. Aucune étape de rendu PDF externe n'est requise.
Comment IronBarcode gère-t-il le traitement parallèle des codes-barres ?
Les méthodes statiques d'IronBarcode sont sans état et à l'abri des threads. Utilisez Parallel.ForEach directement sur les listes de fichiers sans gestion d'instance par thread. BarcodeReaderOptions.MaxParallelThreads contrôle le budget interne des threads.
Quelles propriétés de résultat changent lors de la migration de BarcodeScanning.MAUI vers IronBarcode ?
Renommages courants : BarcodeValue devient Value, BarcodeType devient Format. Les résultats d'IronBarcode ajoutent également Confidence et PageNumber. Une recherche et un remplacement à l'échelle de la solution gèrent les renommages dans le code existant de traitement des résultats.
Comment configurer l'octroi de licences IronBarcode dans un pipeline CI/CD ?
Stockez IRONBARCODE_LICENSE_KEY en tant que secret de pipeline et attribuez IronBarCode.License.LicenseKey dans le code de démarrage de l'application. Un seul secret couvre tous les environnements, y compris le développement, les tests, la mise en scène et la production.
IronBarcode prend-il en charge la génération de codes QR avec un style personnalisé ?
Oui. QRCodeWriter.CreateQrCode() prend en charge les couleurs personnalisées via ChangeBarCodeColor(), l'intégration de logos via AddBrandLogo(), les niveaux de correction d'erreur configurables et plusieurs formats de sortie, notamment PNG, JPG, PDF et stream.

