Passer au contenu du pied de page
VIDéOS

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

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

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
SHELL

Installer IronBarcode:

dotnet add package IronBarcode
dotnet add package IronBarcode
SHELL

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

Ajoutez l'espace de noms IronBarcode :

// Add
using IronBarCode;
// Add
using IronBarCode;
Imports IronBarCode
$vbLabelText   $csharpLabel

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"
XML

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

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>
XML

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

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>
XML

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

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

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

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

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

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

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

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

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

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

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

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

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

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" .
SHELL

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

  1. Supprimez le package NuGet BarcodeScanning.Native.Maui
  2. Installez le package NuGet IronBarcode
  3. Ajoutez IronBarCode.License.LicenseKey = "YOUR-LICENSE-KEY"; dans MauiProgram.cs ou App.xaml.cs
  4. Remplacez using BarcodeScanning; par using IronBarCode; dans tous les fichiers .cs
  5. Supprimez les déclarations de l'espace de noms xmlns:scanner="..." de tous les fichiers XAML
  6. Remplacez les contrôles scanner:CameraView dans XAML par un Button déclenchant MediaPicker.CapturePhotoAsync()
  7. Supprimez le câblage d'événements OnDetectionFinished="..." de XAML
  8. Remplacez les gestionnaires d'événements OnDetectionFinished par des gestionnaires de clics boutons async utilisant BarcodeReader.Read()
  9. Remplacez barcode.DisplayValue par result.Value partout
  10. Remplacez barcode.BarcodeFormat par result.Format partout
  11. Supprimez toutes les solutions de contournement de normalisation BarcodeFormats.Upca + Substring(1)
  12. Ajoutez ExpectMultipleBarcodes = true à BarcodeReaderOptions où la détection multi-code-barres s'appuyait auparavant sur e.BarcodeResults retournant plusieurs éléments
  13. Supprimez les wrappers MainThread.BeginInvokeOnMainThread() du code d'affichage des résultats lorsque le modèle asynchrone les rend inutiles
  14. Vérifiez que les autorisations de caméra AndroidManifest.xml et Info.plist sont 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 = true et 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.

Curtis Chau
Rédacteur technique

Curtis Chau détient un baccalauréat en informatique (Université de Carleton) et se spécialise dans le développement front-end avec expertise en Node.js, TypeScript, JavaScript et React. Passionné par la création d'interfaces utilisateur intuitives et esthétiquement plaisantes, Curtis aime travailler avec des frameworks modernes ...

Lire la suite

Équipe de soutien Iron

Nous sommes en ligne 24 heures sur 24, 5 jours sur 7.
Chat
Email
Appelez-moi