Comment lire et scanner un code-barres en C# avec .NET MAUI
Passer de BarcodeLibà IronBarcode
Ce guide propose une procédure de migration complète de BarcodeLibvers Code-barres IronBarcode pour les développeurs .NET . Il aborde les raisons pour lesquelles les équipes effectuent cette transition, le remplacement étape par étape des packages, des exemples de migration de code pour chaque modèle BarcodeLibcourant, une référence complète de mappage d'API et une liste de contrôle structurée pour gérer la migration à travers une base de code.
Pourquoi migrer depuis BarcodeLib?
Les équipes qui migrent de BarcodeLibvers Code-barres IronBarcode signalent les déclencheurs suivants :
Absence d'API de lecture : BarcodeLibn'a jamais inclus de fonctionnalité de lecture ou de décodage. Lorsqu'un projet générant des images de codes-barres reçoit une nouvelle exigence de scanner également les codes-barres (à partir d'images téléchargées, de scanners d'entrepôt ou de documents de fournisseurs), BarcodeLibne peut pas y répondre. La seule option consiste à ajouter une seconde bibliothèque telle que ZXing .NET, ce qui introduit un second graphe de dépendances et une seconde surface d'API à maintenir en plus de BarcodeLib.
Conflit de version SkiaSharp : BarcodeLib3.x a introduit SkiaSharp comme arrière-plan graphique pour remplacer System.Drawing.Common. La bibliothèque est liée à une plage de versions spécifiques de SkiaSharp. Dans les projets MAUI, les projets Blazor et tout projet où une autre dépendance utilise également SkiaSharp, la version résolue se situe fréquemment en dehors de la plage attendue par BarcodeLib. Cela produit des avertissements NU1608 lors de la restauration et, dans les pires cas, des échecs de liaison d'assemblage d'exécution sur le périphérique.
Absence de prise en charge des fichiers PDF : les applications qui génèrent des documents PDF avec des codes-barres intégrés (factures, bons de commande, manifestes d'expédition) ont parfois besoin de relire ces codes-barres lors du traitement en aval. BarcodeLibgénère des images de codes-barres mais ne prend pas en charge le format PDF à aucune des deux extrémités. L'extraction de codes-barres à partir d'un PDF avec BarcodeLibnécessite le rendu des pages PDF en images à l'aide d'une bibliothèque PDF distincte, puis le passage de ces images à une bibliothèque de lecture distincte.
Étape d'encodage en flux pour la sortie de tableau d'octets : BarcodeLib3.x renvoie SKImage, ce qui nécessite une étape SkiaSharp d'encodage dans un MemoryStream pour produire la sortie byte[] dont les réponses HTTP, les colonnes BLOB des bases de données et la plupart des consommateurs en aval ont réellement besoin. Code-barres IronBarcode fournit .ToPngBinaryData() directement sur la chaîne de génération.
Le problème fondamental
L'architecture de BarcodeLib, basée uniquement sur la génération de code, implique que l'ajout d'une fonctionnalité de numérisation nécessite l'intégration d'une seconde bibliothèque dans la pile :
// BarcodeLib: generation only — reading requires a completely separate library
using BarcodeStandard;
using SkiaSharp;
var b = new Barcode();
SKImage img = b.Encode(Type.Code128, "PRODUCT-12345", 300, 100);
using var stream = File.OpenWrite("barcode.png");
img.Encode(SKEncodedImageFormat.Png, 100).SaveTo(stream);
// To read it back, a separate scanning library such as ZXing.Net is required —
// separate API, separate dependency graph to maintain alongside BarcodeLib.
// BarcodeLib: generation only — reading requires a completely separate library
using BarcodeStandard;
using SkiaSharp;
var b = new Barcode();
SKImage img = b.Encode(Type.Code128, "PRODUCT-12345", 300, 100);
using var stream = File.OpenWrite("barcode.png");
img.Encode(SKEncodedImageFormat.Png, 100).SaveTo(stream);
// To read it back, a separate scanning library such as ZXing.Net is required —
// separate API, separate dependency graph to maintain alongside BarcodeLib.
Imports BarcodeStandard
Imports SkiaSharp
Dim b = New Barcode()
Dim img As SKImage = b.Encode(Type.Code128, "PRODUCT-12345", 300, 100)
Using stream = File.OpenWrite("barcode.png")
img.Encode(SKEncodedImageFormat.Png, 100).SaveTo(stream)
End Using
IronBarcode gère les deux dans le même package avec la même instruction using :
// IronBarcode: generation and reading — no second library needed
using IronBarCode;
// Generate
BarcodeWriter.CreateBarcode("PRODUCT-12345", BarcodeEncoding.Code128)
.ResizeTo(300, 100)
.SaveAsPng("barcode.png");
// Read back — same package, same namespace
var result = BarcodeReader.Read("barcode.png").First().Value;
Console.WriteLine(result); // "PRODUCT-12345"
// IronBarcode: generation and reading — no second library needed
using IronBarCode;
// Generate
BarcodeWriter.CreateBarcode("PRODUCT-12345", BarcodeEncoding.Code128)
.ResizeTo(300, 100)
.SaveAsPng("barcode.png");
// Read back — same package, same namespace
var result = BarcodeReader.Read("barcode.png").First().Value;
Console.WriteLine(result); // "PRODUCT-12345"
Imports IronBarCode
' Generate
BarcodeWriter.CreateBarcode("PRODUCT-12345", BarcodeEncoding.Code128) _
.ResizeTo(300, 100) _
.SaveAsPng("barcode.png")
' Read back — same package, same namespace
Dim result = BarcodeReader.Read("barcode.png").First().Value
Console.WriteLine(result) ' "PRODUCT-12345"
Comparaison des fonctionnalités Code-barres IronBarcode et de BarcodeLib
| Fonction | BarcodeLib | Code-barres IronBarcode |
|---|---|---|
| génération de codes-barres | Oui | Oui |
| Lecture/scan des codes-barres | Non | Oui (BarcodeReader.Read()) |
| génération de code QR | Non (1D uniquement) | Oui (version avancée, avec intégration du logo) |
| lecture de codes-barres PDF | Non | Oui (natif, sans bibliothèque supplémentaire) |
| Génération de codes-barres PDF | Non | Oui |
| Dépendance de SkiaSharp | Oui (risque de conflit de versions) | Non |
| Compatibilité du projet MAUI | Risque de conflit (NU1608) | Aucun conflit |
| API chaînable fluide | Non | Oui |
byte[] sortie directe |
Manuel (via MemoryStream) |
.ToPngBinaryData() |
| Détection de plusieurs codes-barres | Non | Oui (ExpectMultipleBarcodes) |
| Réglage de la vitesse de lecture | N/A | Oui (ReadingSpeed enum) |
| Prise en charge de Linux/macOS | Partiellement (dépendant de SkiaSharp) | Complet |
| Prise en charge de Docker/conteneurs | Configuration requise | Oui |
| Maintenance active | Oui (communauté) | Oui (commercial) |
| Support commercial / SLA | Non | Oui |
| Licence | Apache 2.0 (gratuit) | $999–5 999 $ perpétuel |
Démarrage rapide : Migration de BarcodeLibvers IronBarcode
La migration peut commencer immédiatement grâce à ces étapes fondamentales.
Étape 1 : Remplacer le package NuGet
Retirez d'abord le package BarcodeLib:
dotnet remove package BarcodeLib
dotnet remove package BarcodeLib
Si vous n'êtes pas sûr de la façon dont il est référencé, vérifiez le fichier .csproj :
grep -n "BarcodeLib" YourProject.csproj
grep -n "BarcodeLib" YourProject.csproj
Supprimez toutes les entrées <PackageReference> liées à BarcodeLib. Si vous avez ajouté des remplacements explicites <PackageReference Include="SkiaSharp"> pour contourner les avertissements NU1608 de BarcodeLib, supprimez-les également — après avoir installé IronBarcode, évaluez si SkiaSharp est toujours nécessaire pour d'autres raisons. Installez ensuite IronBarcode:
dotnet add package IronBarcode
dotnet add package IronBarcode
Étape 2 : Mise à jour des espaces de noms
Remplacez les directives using de BarcodeLibdans chaque fichier qui les a référencées :
// Before
using BarcodeStandard;
using SkiaSharp;
// After
using IronBarCode;
// Before
using BarcodeStandard;
using SkiaSharp;
// After
using IronBarCode;
Imports IronBarCode
Imports SkiaSharp
Étape 3 : initialisation de la licence
Ajouter l'initialisation de la licence au démarrage de l'application :
IronBarCode.License.LicenseKey = "YOUR-LICENSE-KEY";
IronBarCode.License.LicenseKey = "YOUR-LICENSE-KEY";
Imports IronBarCode
IronBarCode.License.LicenseKey = "YOUR-LICENSE-KEY"
Pour les applications ASP.NET Core, mettez ceci dans Program.cs avant builder.Build(). Pour les applications de console, mettez-le en haut de Main(). Pour les bibliothèques de classes appelées depuis d'autres applications, initialisez-les à l'endroit où l'application hôte démarre.
Exemples de migration de code
Génération du code de base 128
Le modèle BarcodeLible plus courant : créer une instance, définir les propriétés, appeler Encode().
Approche de BarcodeLib :
using BarcodeStandard;
using SkiaSharp;
public void GenerateShippingLabel(string trackingNumber, string outputPath)
{
var b = new Barcode();
b.IncludeLabel = true;
SKImage img = b.Encode(Type.Code128, trackingNumber, 400, 120);
using var stream = File.OpenWrite(outputPath);
img.Encode(SKEncodedImageFormat.Png, 100).SaveTo(stream);
}
using BarcodeStandard;
using SkiaSharp;
public void GenerateShippingLabel(string trackingNumber, string outputPath)
{
var b = new Barcode();
b.IncludeLabel = true;
SKImage img = b.Encode(Type.Code128, trackingNumber, 400, 120);
using var stream = File.OpenWrite(outputPath);
img.Encode(SKEncodedImageFormat.Png, 100).SaveTo(stream);
}
Imports BarcodeStandard
Imports SkiaSharp
Public Sub GenerateShippingLabel(trackingNumber As String, outputPath As String)
Dim b As New Barcode()
b.IncludeLabel = True
Dim img As SKImage = b.Encode(Type.Code128, trackingNumber, 400, 120)
Using stream = File.OpenWrite(outputPath)
img.Encode(SKEncodedImageFormat.Png, 100).SaveTo(stream)
End Using
End Sub
Approche IronBarcode :
// NuGet: dotnet add package IronBarcode
using IronBarCode;
public void GenerateShippingLabel(string trackingNumber, string outputPath)
{
BarcodeWriter.CreateBarcode(trackingNumber, BarcodeEncoding.Code128)
.ResizeTo(400, 120)
.AddAnnotationTextBelowBarcode(trackingNumber)
.SaveAsPng(outputPath);
}
// NuGet: dotnet add package IronBarcode
using IronBarCode;
public void GenerateShippingLabel(string trackingNumber, string outputPath)
{
BarcodeWriter.CreateBarcode(trackingNumber, BarcodeEncoding.Code128)
.ResizeTo(400, 120)
.AddAnnotationTextBelowBarcode(trackingNumber)
.SaveAsPng(outputPath);
}
Imports IronBarCode
Public Sub GenerateShippingLabel(trackingNumber As String, outputPath As String)
BarcodeWriter.CreateBarcode(trackingNumber, BarcodeEncoding.Code128) _
.ResizeTo(400, 120) _
.AddAnnotationTextBelowBarcode(trackingNumber) _
.SaveAsPng(outputPath)
End Sub
Le bloc de définition des propriétés se réduit à une chaîne fluide. .AddAnnotationTextBelowBarcode() remplace b.IncludeLabel = true — il accepte explicitement la chaîne d'étiquettes pour que vous contrôliez le texte qui apparaît sous les barres. .ResizeTo() remplace les arguments de largeur/hauteur. Pour les options de génération avancées, consultez la documentation sur la génération de codes-barres IronBarcode .
Retourner byte[] — le modèle d'API Web courant
BarcodeLib 3.x renvoie un SKImage. En obtenir les octets nécessite un encodage via SkiaSharp dans un MemoryStream. Code-barres IronBarcode fournit .ToPngBinaryData() directement.
Approche de BarcodeLib :
using BarcodeStandard;
using SkiaSharp;
using System.IO;
public byte[] GetBarcodeBytes(string data)
{
var b = new Barcode();
SKImage img = b.Encode(Type.Code128, data, 300, 100);
using var ms = new MemoryStream();
img.Encode(SKEncodedImageFormat.Png, 100).SaveTo(ms);
return ms.ToArray();
}
using BarcodeStandard;
using SkiaSharp;
using System.IO;
public byte[] GetBarcodeBytes(string data)
{
var b = new Barcode();
SKImage img = b.Encode(Type.Code128, data, 300, 100);
using var ms = new MemoryStream();
img.Encode(SKEncodedImageFormat.Png, 100).SaveTo(ms);
return ms.ToArray();
}
Imports BarcodeStandard
Imports SkiaSharp
Imports System.IO
Public Function GetBarcodeBytes(data As String) As Byte()
Dim b As New Barcode()
Dim img As SKImage = b.Encode(Type.Code128, data, 300, 100)
Using ms As New MemoryStream()
img.Encode(SKEncodedImageFormat.Png, 100).SaveTo(ms)
Return ms.ToArray()
End Using
End Function
Approche IronBarcode :
using IronBarCode;
public byte[] GetBarcodeBytes(string data)
{
return BarcodeWriter.CreateBarcode(data, BarcodeEncoding.Code128)
.ResizeTo(300, 100)
.ToPngBinaryData();
}
using IronBarCode;
public byte[] GetBarcodeBytes(string data)
{
return BarcodeWriter.CreateBarcode(data, BarcodeEncoding.Code128)
.ResizeTo(300, 100)
.ToPngBinaryData();
}
Imports IronBarCode
Public Function GetBarcodeBytes(data As String) As Byte()
Return BarcodeWriter.CreateBarcode(data, BarcodeEncoding.Code128) _
.ResizeTo(300, 100) _
.ToPngBinaryData()
End Function
L'étape intermédiaire MemoryStream est supprimée. .ToPngBinaryData() renvoie directement le byte[], ce que les corps des réponses HTTP, les colonnes BLOB des bases de données et les écrivains de fichiers veulent réellement.
Action du contrôleur d'API Web
Approche de BarcodeLib :
using BarcodeStandard;
using SkiaSharp;
using Microsoft.AspNetCore.Mvc;
using System.IO;
[ApiController]
[Route("api/labels")]
public class LabelsController : ControllerBase
{
[HttpGet("{sku}")]
public IActionResult GetLabel(string sku)
{
var b = new Barcode();
SKImage img = b.Encode(Type.Code128, sku, 400, 120);
using var ms = new MemoryStream();
img.Encode(SKEncodedImageFormat.Png, 100).SaveTo(ms);
return File(ms.ToArray(), "image/png");
}
}
using BarcodeStandard;
using SkiaSharp;
using Microsoft.AspNetCore.Mvc;
using System.IO;
[ApiController]
[Route("api/labels")]
public class LabelsController : ControllerBase
{
[HttpGet("{sku}")]
public IActionResult GetLabel(string sku)
{
var b = new Barcode();
SKImage img = b.Encode(Type.Code128, sku, 400, 120);
using var ms = new MemoryStream();
img.Encode(SKEncodedImageFormat.Png, 100).SaveTo(ms);
return File(ms.ToArray(), "image/png");
}
}
Imports BarcodeStandard
Imports SkiaSharp
Imports Microsoft.AspNetCore.Mvc
Imports System.IO
<ApiController>
<Route("api/labels")>
Public Class LabelsController
Inherits ControllerBase
<HttpGet("{sku}")>
Public Function GetLabel(sku As String) As IActionResult
Dim b As New Barcode()
Dim img As SKImage = b.Encode(Type.Code128, sku, 400, 120)
Using ms As New MemoryStream()
img.Encode(SKEncodedImageFormat.Png, 100).SaveTo(ms)
Return File(ms.ToArray(), "image/png")
End Using
End Function
End Class
Approche IronBarcode :
using IronBarCode;
using Microsoft.AspNetCore.Mvc;
[ApiController]
[Route("api/labels")]
public class LabelsController : ControllerBase
{
[HttpGet("{sku}")]
public IActionResult GetLabel(string sku)
{
byte[] pngBytes = BarcodeWriter.CreateBarcode(sku, BarcodeEncoding.Code128)
.ResizeTo(400, 120)
.ToPngBinaryData();
return File(pngBytes, "image/png");
}
}
using IronBarCode;
using Microsoft.AspNetCore.Mvc;
[ApiController]
[Route("api/labels")]
public class LabelsController : ControllerBase
{
[HttpGet("{sku}")]
public IActionResult GetLabel(string sku)
{
byte[] pngBytes = BarcodeWriter.CreateBarcode(sku, BarcodeEncoding.Code128)
.ResizeTo(400, 120)
.ToPngBinaryData();
return File(pngBytes, "image/png");
}
}
Imports IronBarCode
Imports Microsoft.AspNetCore.Mvc
<ApiController>
<Route("api/labels")>
Public Class LabelsController
Inherits ControllerBase
<HttpGet("{sku}")>
Public Function GetLabel(sku As String) As IActionResult
Dim pngBytes As Byte() = BarcodeWriter.CreateBarcode(sku, BarcodeEncoding.Code128) _
.ResizeTo(400, 120) _
.ToPngBinaryData()
Return File(pngBytes, "image/png")
End Function
End Class
L'action du contrôleur diminue en supprimant le bloc MemoryStream et l'étape d'encodage SkiaSharp. Le tableau d'octets circule directement de .ToPngBinaryData() dans File().
Génération de codes QR
BarcodeLib 3.x ne génère pas de codes QR — l'enum BarcodeStandard.Type ne contient pas d'entrées 2D. Les projets qui avaient besoin de QR à côté de BarcodeLibont généralement ajouté une seconde bibliothèque comme QRCoder. Code-barres IronBarcode utilise une classe dédiée QRCodeWriter avec des options supplémentaires pour l'intégration et le style du logo.
Approche de BarcodeLib :
// BarcodeLibhas no QR Code (or any 2D) support.
// Generating a QR code from a BarcodeLibproject required adding a
// second library such as QRCoder:
//
// using QRCoder;
// var qrGen = new QRCodeGenerator();
// var data = qrGen.CreateQrCode("https://example.com/product/42", QRCodeGenerator.ECCLevel.Q);
// // ... separate API, separate dependency to maintain.
// BarcodeLibhas no QR Code (or any 2D) support.
// Generating a QR code from a BarcodeLibproject required adding a
// second library such as QRCoder:
//
// using QRCoder;
// var qrGen = new QRCodeGenerator();
// var data = qrGen.CreateQrCode("https://example.com/product/42", QRCodeGenerator.ECCLevel.Q);
// // ... separate API, separate dependency to maintain.
' BarcodeLib has no QR Code (or any 2D) support.
' Generating a QR code from a BarcodeLib project required adding a
' second library such as QRCoder:
'
' Imports QRCoder
' Dim qrGen As New QRCodeGenerator()
' Dim data = qrGen.CreateQrCode("https://example.com/product/42", QRCodeGenerator.ECCLevel.Q)
' ' ... separate API, separate dependency to maintain.
Approche IronBarcode :
using IronBarCode;
// Basic QR code
QRCodeWriter.CreateQrCode("https://example.com/product/42", 300)
.SaveAsPng("qr.png");
// QR code with embedded brand logo (not possible with BarcodeLib)
QRCodeWriter.CreateQrCode("https://example.com/product/42", 300)
.AddBrandLogo("logo.png")
.SaveAsPng("qr-branded.png");
using IronBarCode;
// Basic QR code
QRCodeWriter.CreateQrCode("https://example.com/product/42", 300)
.SaveAsPng("qr.png");
// QR code with embedded brand logo (not possible with BarcodeLib)
QRCodeWriter.CreateQrCode("https://example.com/product/42", 300)
.AddBrandLogo("logo.png")
.SaveAsPng("qr-branded.png");
Imports IronBarCode
' Basic QR code
QRCodeWriter.CreateQrCode("https://example.com/product/42", 300) _
.SaveAsPng("qr.png")
' QR code with embedded brand logo (not possible with BarcodeLib)
QRCodeWriter.CreateQrCode("https://example.com/product/42", 300) _
.AddBrandLogo("logo.png") _
.SaveAsPng("qr-branded.png")
QRCodeWriter.CreateQrCode() prend la chaîne de données et la taille des pixels comme paramètres. L'intégration du logo, la personnalisation des couleurs et le niveau de correction des erreurs sont tous disponibles via des méthodes enchaînées. Pour connaître les options de style des codes QR, consultez la documentation relative aux codes QR IronBarcode .
EAN-13 et UPC-A
Ces systèmes sont courants dans les systèmes d'inventaire du commerce de détail. Les noms des énumérations changent, mais les valeurs sont directement équivalentes.
Approche de BarcodeLib :
using BarcodeStandard;
using SkiaSharp;
// EAN-13 product barcode
var b = new Barcode();
SKImage ean = b.Encode(Type.Ean13, "5901234123457", 250, 100);
using (var s = File.OpenWrite("product-ean.png"))
ean.Encode(SKEncodedImageFormat.Png, 100).SaveTo(s);
// UPC-A for US retail
SKImage upc = b.Encode(Type.UpcA, "012345678905", 250, 100);
using (var s = File.OpenWrite("product-upc.png"))
upc.Encode(SKEncodedImageFormat.Png, 100).SaveTo(s);
using BarcodeStandard;
using SkiaSharp;
// EAN-13 product barcode
var b = new Barcode();
SKImage ean = b.Encode(Type.Ean13, "5901234123457", 250, 100);
using (var s = File.OpenWrite("product-ean.png"))
ean.Encode(SKEncodedImageFormat.Png, 100).SaveTo(s);
// UPC-A for US retail
SKImage upc = b.Encode(Type.UpcA, "012345678905", 250, 100);
using (var s = File.OpenWrite("product-upc.png"))
upc.Encode(SKEncodedImageFormat.Png, 100).SaveTo(s);
Imports BarcodeStandard
Imports SkiaSharp
Imports System.IO
' EAN-13 product barcode
Dim b As New Barcode()
Dim ean As SKImage = b.Encode(Type.Ean13, "5901234123457", 250, 100)
Using s = File.OpenWrite("product-ean.png")
ean.Encode(SKEncodedImageFormat.Png, 100).SaveTo(s)
End Using
' UPC-A for US retail
Dim upc As SKImage = b.Encode(Type.UpcA, "012345678905", 250, 100)
Using s = File.OpenWrite("product-upc.png")
upc.Encode(SKEncodedImageFormat.Png, 100).SaveTo(s)
End Using
Approche IronBarcode :
using IronBarCode;
// EAN-13 product barcode
BarcodeWriter.CreateBarcode("5901234123457", BarcodeEncoding.EAN13)
.ResizeTo(250, 100)
.SaveAsPng("product-ean.png");
// UPC-A for US retail
BarcodeWriter.CreateBarcode("012345678905", BarcodeEncoding.UPCA)
.ResizeTo(250, 100)
.SaveAsPng("product-upc.png");
using IronBarCode;
// EAN-13 product barcode
BarcodeWriter.CreateBarcode("5901234123457", BarcodeEncoding.EAN13)
.ResizeTo(250, 100)
.SaveAsPng("product-ean.png");
// UPC-A for US retail
BarcodeWriter.CreateBarcode("012345678905", BarcodeEncoding.UPCA)
.ResizeTo(250, 100)
.SaveAsPng("product-upc.png");
Imports IronBarCode
' EAN-13 product barcode
BarcodeWriter.CreateBarcode("5901234123457", BarcodeEncoding.EAN13) _
.ResizeTo(250, 100) _
.SaveAsPng("product-ean.png")
' UPC-A for US retail
BarcodeWriter.CreateBarcode("012345678905", BarcodeEncoding.UPCA) _
.ResizeTo(250, 100) _
.SaveAsPng("product-upc.png")
Ajout de la lecture des codes-barres (nouvelle fonctionnalité)
BarcodeLib ne possède pas d'API de lecture. Si votre migration est motivée par une nouvelle exigence de numérisation de codes-barres (à partir d'images téléchargées, de scanners d'entrepôt ou de documents PDF numérisés), ajoutez ceci sans deuxième bibliothèque :
Approche de BarcodeLib :
// BarcodeLib— no reading API exists
// Adding reading requires a separate library such as ZXing.Net:
// dotnet add package ZXing.Net
// using ZXing;
// var reader = new BarcodeReader();
// // ... separate API, separate dependency graph to manage
// BarcodeLib— no reading API exists
// Adding reading requires a separate library such as ZXing.Net:
// dotnet add package ZXing.Net
// using ZXing;
// var reader = new BarcodeReader();
// // ... separate API, separate dependency graph to manage
' BarcodeLib— no reading API exists
' Adding reading requires a separate library such as ZXing.Net:
' dotnet add package ZXing.Net
' Imports ZXing
' Dim reader As New BarcodeReader()
' ' ... separate API, separate dependency graph to manage
Approche IronBarcode :
using IronBarCode;
// Read a barcode from an image file
var results = BarcodeReader.Read("incoming-label.png");
foreach (var result in results)
{
Console.WriteLine($"Value: {result.Value}");
Console.WriteLine($"Format: {result.Format}");
}
// Read all barcodes from a multi-page PDF — no PDF library required
var pdfResults = BarcodeReader.Read("supplier-invoice.pdf");
foreach (var result in pdfResults)
{
Console.WriteLine($"Page {result.PageNumber}: {result.Value}");
}
// Configure for high-volume scanning with multiple barcodes per image
var options = new BarcodeReaderOptions
{
Speed = ReadingSpeed.Balanced,
ExpectMultipleBarcodes = true
};
var warehouseResults = BarcodeReader.Read("dock-scan.png", options);
using IronBarCode;
// Read a barcode from an image file
var results = BarcodeReader.Read("incoming-label.png");
foreach (var result in results)
{
Console.WriteLine($"Value: {result.Value}");
Console.WriteLine($"Format: {result.Format}");
}
// Read all barcodes from a multi-page PDF — no PDF library required
var pdfResults = BarcodeReader.Read("supplier-invoice.pdf");
foreach (var result in pdfResults)
{
Console.WriteLine($"Page {result.PageNumber}: {result.Value}");
}
// Configure for high-volume scanning with multiple barcodes per image
var options = new BarcodeReaderOptions
{
Speed = ReadingSpeed.Balanced,
ExpectMultipleBarcodes = true
};
var warehouseResults = BarcodeReader.Read("dock-scan.png", options);
Imports IronBarCode
' Read a barcode from an image file
Dim results = BarcodeReader.Read("incoming-label.png")
For Each result In results
Console.WriteLine($"Value: {result.Value}")
Console.WriteLine($"Format: {result.Format}")
Next
' Read all barcodes from a multi-page PDF — no PDF library required
Dim pdfResults = BarcodeReader.Read("supplier-invoice.pdf")
For Each result In pdfResults
Console.WriteLine($"Page {result.PageNumber}: {result.Value}")
Next
' Configure for high-volume scanning with multiple barcodes per image
Dim options As New BarcodeReaderOptions With {
.Speed = ReadingSpeed.Balanced,
.ExpectMultipleBarcodes = True
}
Dim warehouseResults = BarcodeReader.Read("dock-scan.png", options)
BarcodeReader.Read() accepte les fichiers image, les fichiers PDF, les flux et les objets System.Drawing.Bitmap. L'enum ReadingSpeed vous permet de faire des compromis entre exhaustivité et performance lors de la numérisation en volume. Pour plus d'informations sur les options de configuration de lecture, consultez la documentation de lecture IronBarcode .
Résolution du conflit SkiaSharp
Si votre migration est déclenchée par des avertissements NU1608, vérifiez que le conflit est résolu après le changement de paquets. Après avoir exécuté dotnet remove package BarcodeLib et dotnet add package IronBarcode, reconstruisez et vérifiez la sortie :
dotnet build 2>&1 | grep -i "NU1608\|SkiaSharp"
dotnet build 2>&1 | grep -i "NU1608\|SkiaSharp"
Si aucun résultat n'apparaît, le conflit est résolu. Si les avertissements SkiaSharp persistent, ils proviennent d'un autre paquet dans votre graphe de dépendances — Code-barres IronBarcode n'en est pas la source.
Approche de BarcodeLib :
<ItemGroup>
<PackageReference Include="BarcodeLib" Version="3.1.5" />
<PackageReference Include="SkiaSharp" Version="3.116.1" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="BarcodeLib" Version="3.1.5" />
<PackageReference Include="SkiaSharp" Version="3.116.1" />
</ItemGroup>
Approche IronBarcode :
<ItemGroup>
<PackageReference Include="IronBarcode" Version="*" />
<PackageReference Include="SkiaSharp.Views.Maui.Controls" Version="3.116.1" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="IronBarcode" Version="*" />
<PackageReference Include="SkiaSharp.Views.Maui.Controls" Version="3.116.1" />
</ItemGroup>
Référence de correspondance entre l'API BarcodeLibet IronBarcode
| BarcodeLib | Code-barres IronBarcode |
|---|---|
new Barcode() |
API statique — aucune instance requise |
b.Encode(Type.Code128, "data", w, h) |
BarcodeWriter.CreateBarcode("data", BarcodeEncoding.Code128) |
b.IncludeLabel = true |
.AddAnnotationTextBelowBarcode("text") |
Largeur/hauteur passes à Encode() |
.ResizeTo(width, height) |
Renvoie SKImage |
.SaveAsPng(path) / .ToPngBinaryData() |
Type.Code128 |
BarcodeEncoding.Code128 |
Type.Code39 |
BarcodeEncoding.Code39 |
Type.Ean13 |
BarcodeEncoding.EAN13 |
Type.UpcA |
BarcodeEncoding.UPCA |
| Pas de support QR (1D uniquement) | BarcodeEncoding.QRCode (aussi QRCodeWriter) |
Type.Itf14 |
BarcodeEncoding.ITF14 |
Type.Codabar |
BarcodeEncoding.Codabar |
| API de lecture indisponible | BarcodeReader.Read(path) |
| Conflit de versions de SkiaSharp dans MAUI | Aucune dépendance conflictuelle |
img.Encode(...).SaveTo(stream) |
.SaveAsPng(path) |
MemoryStream + encodage SkiaSharp |
.ToPngBinaryData() |
Problèmes de migration courants et solutions
Problème 1 : Changement de namespace Type Enum
BarcodeLib 3.x : Utilise BarcodeStandard.Type.Code128 (PascalCase, dans l'espace de noms BarcodeStandard). Un code 2.x plus ancien peut utiliser BarcodeLib.TYPE.CODE128 (constantes en majuscules, espace de noms BarcodeLib) — les deux formes apparaissent dans des bases de code réelles en cours de migration.
Solution: Replace with BarcodeEncoding.Code128. Une recherche avec grep dans les fichiers .cs identifie toutes les occurrences :
grep -rn "Type\.\|TYPE\." --include="*.cs" .
grep -rn "Type\.\|TYPE\." --include="*.cs" .
Common replacements: Type.Code128 / TYPE.CODE128 → BarcodeEncoding.Code128, Type.Ean13 / TYPE.EAN13 → BarcodeEncoding.EAN13, Type.UpcA / TYPE.UPCA → BarcodeEncoding.UPCA, Type.Itf14 / TYPE.ITF14 → BarcodeEncoding.ITF14, Type.Codabar / TYPE.CO/DABAR → BarcodeEncoding.Codabar. BarcodeLibn'a pas d'entrée QR ; tout TYPE.QR_Code est un code mort d'une version 2.x ou d'un fork — remplacez par BarcodeEncoding.QRCode (ou utilisez QRCodeWriter pour une sortie stylée).
Problème 2 : Type de retour SKImage / Image
BarcodeLib : b.Encode() renvoie SKImage en 3.x et System.Drawing.Image en 2.x. N'importe quel type ne se compile pas contre IronBarcode.
Solution : Supprimez la variable image intermédiaire et remplacez la logique de sauvegarde par la méthode finale appropriée sur la chaîne fluide :
// Before (BarcodeLib 3.x)
SKImage img = b.Encode(Type.Code128, data, 300, 100);
using var ms = new MemoryStream();
img.Encode(SKEncodedImageFormat.Png, 100).SaveTo(ms);
return ms.ToArray();
// After
return BarcodeWriter.CreateBarcode(data, BarcodeEncoding.Code128)
.ResizeTo(300, 100)
.ToPngBinaryData();
// Before (BarcodeLib 3.x)
SKImage img = b.Encode(Type.Code128, data, 300, 100);
using var ms = new MemoryStream();
img.Encode(SKEncodedImageFormat.Png, 100).SaveTo(ms);
return ms.ToArray();
// After
return BarcodeWriter.CreateBarcode(data, BarcodeEncoding.Code128)
.ResizeTo(300, 100)
.ToPngBinaryData();
Imports System.IO
' Before (BarcodeLib 3.x)
Dim img As SKImage = b.Encode(Type.Code128, data, 300, 100)
Using ms As New MemoryStream()
img.Encode(SKEncodedImageFormat.Png, 100).SaveTo(ms)
Return ms.ToArray()
End Using
' After
Return BarcodeWriter.CreateBarcode(data, BarcodeEncoding.Code128) _
.ResizeTo(300, 100) _
.ToPngBinaryData()
Recherchez les modèles SKImage img = b.Encode et Image img = b.Encode pour trouver tous les emplacements affectés.
Problème 3 : Paramètres de largeur et de hauteur
BarcodeLib : La largeur et la hauteur sont des arguments positionnels sur Encode(Type, string, int, int) en 3.x, et des affectations de propriété b.Width / b.Height distinctes dans un code 2.x plus ancien. L'une ou l'autre forme doit être portée.
Solution : La largeur/hauteur devient un seul appel .ResizeTo(width, height) enchaîné après CreateBarcode(). Trouvez les points d'appel :
# Find Encode() calls and any Width/Height property assignments
grep -n "\.Encode(\|\.Width = \|\.Height = " --include="*.cs" -r .
# Find Encode() calls and any Width/Height property assignments
grep -n "\.Encode(\|\.Width = \|\.Height = " --include="*.cs" -r .
Ensuite, remplacez les arguments de taille ou la paire de propriétés par un seul appel en chaîne .ResizeTo(width, height).
Problème n° 4 : Basculement booléen IncludeLabel
BarcodeLib : b.IncludeLabel = true est un booléen qui rend automatiquement la chaîne de données encodée sous forme de texte visible sous les barres.
Solution : Utilisez .AddAnnotationTextBelowBarcode("text"), qui prend explicitement la chaîne d'étiquettes. Dans la plupart des cas, transmettez la même chaîne de données que celle encodée dans le code-barres. Si le code d'origine utilisait IncludeLabel = true et comptait sur BarcodeLibpour rendre automatiquement les données sous forme d'étiquette, passez cette même chaîne de données explicitement :
BarcodeWriter.CreateBarcode(data, BarcodeEncoding.Code128)
.AddAnnotationTextBelowBarcode(data) // pass the same string
.SaveAsPng(outputPath);
BarcodeWriter.CreateBarcode(data, BarcodeEncoding.Code128)
.AddAnnotationTextBelowBarcode(data) // pass the same string
.SaveAsPng(outputPath);
Dim barcodeWriter = BarcodeWriter.CreateBarcode(data, BarcodeEncoding.Code128)
barcodeWriter.AddAnnotationTextBelowBarcode(data) ' pass the same string
barcodeWriter.SaveAsPng(outputPath)
Problème n° 5 : Références SkiaSharp restantes après la suppression de BarcodeLib
BarcodeLib : Les projets accumulaient fréquemment des entrées explicites <PackageReference Include="SkiaSharp"> spécifiquement pour contourner la contrainte de version de BarcodeLib. Ces éléments deviennent orphelins après la suppression de BarcodeLib.
Solution : Après être passé à IronBarcode, vérifiez si SkiaSharp est toujours requis par un autre paquet avant de supprimer la référence explicite :
# Check if SkiaSharp is still referenced by anything other than the explicit override
dotnet list package --include-transitive 2>&1 | grep -i skia
# Check if SkiaSharp is still referenced by anything other than the explicit override
dotnet list package --include-transitive 2>&1 | grep -i skia
Si SkiaSharp n'apparaît que pour les raisons explicites <PackageReference> supprimées maintenant, supprimez cette entrée. Si ce module est toujours utilisé par MAUI ou une autre dépendance, laissez-le tel quel — Code-barres IronBarcode ne sera pas en conflit avec lui.
Liste de contrôle de migration BarcodeLib
Tâches préalables à la migration
Effectuez ces recherches avant de commencer à comprendre l'étendue des changements nécessaires :
# Find all BarcodeLibusing directives (both 3.x BarcodeStandard and older BarcodeLib)
grep -rn "using BarcodeStandard\|using BarcodeLib" --include="*.cs" .
# Find Barcode object instantiation
grep -rn "new Barcode()" --include="*.cs" .
# Find Encode calls
grep -rn "\.Encode(" --include="*.cs" .
# Find Type enum usage (3.x PascalCase and 2.x uppercase)
grep -rn "Type\.Code128\|Type\.Ean13\|Type\.UpcA\|TYPE\.CODE128\|TYPE\.EAN13\|TYPE\.UPCA" --include="*.cs" .
# Find IncludeLabel usage
grep -rn "IncludeLabel" --include="*.cs" .
# Find the package references in project files
grep -rn "BarcodeLib" --include="*.csproj" .
# Find NU1608 evidence in lock files
grep -rn "NU1608" .
# Find all BarcodeLibusing directives (both 3.x BarcodeStandard and older BarcodeLib)
grep -rn "using BarcodeStandard\|using BarcodeLib" --include="*.cs" .
# Find Barcode object instantiation
grep -rn "new Barcode()" --include="*.cs" .
# Find Encode calls
grep -rn "\.Encode(" --include="*.cs" .
# Find Type enum usage (3.x PascalCase and 2.x uppercase)
grep -rn "Type\.Code128\|Type\.Ean13\|Type\.UpcA\|TYPE\.CODE128\|TYPE\.EAN13\|TYPE\.UPCA" --include="*.cs" .
# Find IncludeLabel usage
grep -rn "IncludeLabel" --include="*.cs" .
# Find the package references in project files
grep -rn "BarcodeLib" --include="*.csproj" .
# Find NU1608 evidence in lock files
grep -rn "NU1608" .
Documentez tous les fichiers concernés par chaque recherche. Notez quels projets référencent directement BarcodeLibet lesquels l'héritent transitivement. Identifiez toutes les substitutions de version SkiaSharp explicites ajoutées uniquement pour résoudre les conflits BarcodeLib.
Tâches de mise à jour du code
- Exécutez
dotnet remove package BarcodeLibpour chaque projet - Supprimez toutes les références explicites de remplacement de version SkiaSharp ajoutées uniquement pour corriger les conflits BarcodeLib.
- Exécutez
dotnet add package IronBarcodepour chaque projet - Ajoutez
IronBarCode.License.LicenseKey = "YOUR-LICENSE-KEY";au démarrage de l'application dans chaque projet - Remplacez
using BarcodeStandard;(ouusing BarcodeLib;dans un ancien code) etusing SkiaSharp;parusing IronBarCode;dans tous les fichiers.cs - Supprimez les imports
using System.Drawing.Imaging;restants de l'utilisationImageFormat.Png2.x - Remplacez les appels
new Barcode()+Encode()par des chaînesBarcodeWriter.CreateBarcode()enchaînées - Remplacez
Type.Code128/TYPE.CODE128→BarcodeEncoding.Code128et toutes les autres valeurs enum - Remplacez les arguments de largeur/hauteur (ou
b.Width = N; b.Height = M;) with.ResizeTo(N, M)appels en chaîne - Remplacez
b.IncludeLabel = true;par.AddAnnotationTextBelowBarcode(data) - Remplacez
img.Encode(SKEncodedImageFormat.Png, 100).SaveTo(...)par.SaveAsPng(path)ou.ToPngBinaryData() - Supprimez les variables intermédiaires
SKImage/Imageet les blocsMemoryStreamoù.ToPngBinaryData()les remplace - Ajoutez le code de lecture de code-barres si nécessaire (
BarcodeReader.Read())
Test de post-migration
- Compilez le projet et vérifiez qu'aucun avertissement NU1608 ne figure dans le résultat de la restauration.
- Exécutez
dotnet build 2>&1| grep -i "NU1608|SkiaSharp"` pour vérifier que le conflit SkiaSharp est entièrement résolu - Comparer le rendu visuel des codes-barres générés avec des échantillons de référence provenant de BarcodeLib
- Vérifiez que les codes QR sont correctement décodés en utilisant un scanner mobile ou la méthode
BarcodeReader.Read() - Tester les codes-barres EAN-13 et UPC-A avec le matériel de lecture des points de vente, le cas échéant.
- Vérifier que les images s'affichent correctement dans tous les supports de sortie : système de fichiers, réponse HTTP, base de données
- Testez tous les scénarios de lecture de code-barres PDF en utilisant
BarcodeReader.Read("file.pdf")sur des documents réels - Vérifiez que les compilations multiplateformes réussissent si le projet cible Linux ou macOS
- Vérifier que les builds MAUI s'exécutent sans erreur de liaison SkiaSharp sur les cibles Android et iOS
Principaux avantages de la migration vers IronBarcode
Lecture des codes-barres sans deuxième bibliothèque : le gain le plus immédiat pour les équipes qui avaient besoin de cette capacité de lecture est l'élimination de la dépendance à une deuxième bibliothèque. BarcodeReader.Read() est dans le même package, utilise la même instruction using IronBarCode;, et ne nécessite pas d'installations supplémentaires de NuGet. ZXing .NET et son propre graphe de dépendances ne font plus partie du projet.
Aucun conflit de version SkiaSharp : Code-barres IronBarcode ne partage pas le graphe de dépendances SkiaSharp avec le code de l'application. Les projets MAUI, les projets Blazor et tout projet où plusieurs packages convergent vers SkiaSharp peuvent installer Code-barres IronBarcode sans avertissements NU1608 ni échecs de liaison à l'exécution. La négociation de versions introduite par BarcodeLiba disparu.
Sortie directe du tableau d'octets : .ToPngBinaryData() renvoie byte[] à la fin de la chaîne enchaînée. L'intermédiaire MemoryStream que BarcodeLibnécessitait pour la sortie du tableau d'octets est éliminé de chaque action de contrôleur, méthode de service et gestionnaire d'API qui génère des codes-barres.
Traitement des codes-barres PDF : BarcodeReader.Read() accepte les fichiers PDF nativement. Les applications qui génèrent des documents PDF avec des codes-barres intégrés peuvent relire ces codes-barres sans bibliothèque de rendu PDF distincte. L'ensemble de la chaîne — génération, intégration de PDF et lecture — est géré par IronBarcode.
Support commercial et SLA : Code-barres IronBarcode est soutenu par le modèle de support commercial d'Iron Software avec une cadence de mise à jour définie. Lorsque de nouvelles versions de .NET arrivent ou que des changements perturbateurs apparaissent dans l'écosystème .NET, Code-barres IronBarcode publie des mises à jour de compatibilité sur une chronologie liée au SLA commercial plutôt qu'à la disponibilité communautaire.
Génération de codes QR sans une deuxième bibliothèque : QRCodeWriter supporte l'intégration de logos, la personnalisation des couleurs et la configuration du niveau de correction d'erreur par les méthodes enchaînées. BarcodeLib3.x génère uniquement des symbologies 1D — les projets qui avaient besoin de QR à côté de BarcodeLibajoutaient auparavant une seconde bibliothèque comme QRCoder. Les équipes dont les exigences de codes QR se sont élargies gagnent ces fonctionnalités à l'intérieur du même package, sans changer leur workflow de génération.
Questions Fréquemment Posées
Pourquoi devrais-je migrer de BarcodeLib 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 API de BarcodeLib 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 BarcodeLib 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.
Dois-je conserver les deux logiciels BarcodeLib 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 à BarcodeLib ?
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é depuis BarcodeLib ?
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 BarcodeLib 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.

