Comment personnaliser et ajouter des logos aux codes QR en C#
Passer de Accusoft BarcodeXpressà IronBarcode
La majeure partie du travail lié à cette migration consiste à supprimer des données. Le système de licence à deux clés — SetSolutionName, SetSolutionKey, et SetOEMLicenseKey pour l'exécution — disparaît entièrement. Les opérations de code-barres réelles (lire une image, écrire un code-barres sur un fichier) sont traduites en équivalents plus courts d'IronBarcode. Si votre base de code comporte une classe BarcodeService qui encapsule BarcodeXpress, le code de licence en est souvent une grande partie. Après la migration, cette classe se réduit.
Pourquoi migrer depuis Accusoft BarcodeXpress?
Les équipes migrant depuis BarcodeXpress signalent les déclencheurs suivants :
Mode d'évaluation bloque le benchmarking précis : Sans une clé OEM/exécution valide, BarcodeXpress tamponne les résultats décodés avec la chaîne littérale " UNLICENSED accusoft.com " et applique le même tampon aux codes-barres 2D générés. Les tests de précision avant l'achat sur des documents réels produisent cette sortie filigranée, vous ne pouvez donc pas vérifier si la bibliothèque lit correctement vos types de scan réels avant de vous engager dans un achat.
La licence à deux clés augmente les frais opérationnels : BarcodeXpress sépare la licence SDK (SetSolutionName + SetSolutionKey) de la licence OEM/exécution (SetOEMLicenseKey). Les pipelines CI/CD, les conteneurs Docker et les orchestrateurs de conteneurs nécessitent chacun la gestion de ces deux systèmes clés comme des secrets distincts. Une clé d'exécution manquante ou invalide revient à une sortie filigranée plutôt qu'à une levée d'erreur, créant un mode d'échec qui peut passer des tests automatisés si les assertions vérifient seulement pour des résultats non nuls.
Cinq licences d'exécution minimum pour tout déploiement en production : même un déploiement sur un seul serveur nécessite l'achat d'au moins cinq licences d'exécution. Les équipes qui gèrent un serveur de production et un serveur de préproduction paient au minimum dix licences d'exécution, indépendamment de leur utilisation réelle.
Limite de 40 PPM pour l'édition standard : L'édition standard limite le traitement à 40 pages par minute. À ce rythme, le traitement d'un lot de 100 000 documents prend environ 41 heures. Pour supprimer cette limitation, il faut passer à l'édition Professional , ce qui entraîne un coût plus élevé par poste de développeur, en plus des licences d'exécution déjà achetées.
Prise en charge native des fichiers PDF non disponible : les fichiers PDF doivent être convertis en images à l'aide d'une bibliothèque distincte avant que BarcodeXpress puisse les lire. Cette dépendance externe engendre un second coût de licence, une étape de conversion et une pression supplémentaire sur la mémoire due au stockage des images de pages rendues.
La sécurité des threads nécessite l'isolation des instances : L'objet reader de BarcodeXpress est à état et n'est pas sûr pour un accès concurrent. Le traitement par lots parallèle nécessite une instance BarcodeXpress entièrement initialisée par thread, avec l'initialisation complète de la licence à deux niveaux répétée dans chaque contexte de thread.
Le problème fondamental
BarcodeXpress nécessite une initialisation en plusieurs étapes, un chargement de Bitmap, et une configuration BarcodeType[] avant que tout code-barres puisse être lu :
using var bitmap = new Bitmap(imagePath);
var barcodeXpress = new BarcodeXpress(".");
barcodeXpress.Licensing.SetSolutionName("AcmeCorp");
barcodeXpress.Licensing.SetSolutionKey(1, 2, 3, 4);
barcodeXpress.Licensing.SetOEMLicenseKey("2.0.OEMLicenseStringFromAccusoft...");
barcodeXpress.reader.BarcodeTypes = new[]
{
BarcodeType.Code128Barcode,
BarcodeType.DataMatrixBarcode,
BarcodeType.QRCodeBarcode
};
Result[] results = barcodeXpress.reader.Analyze(bitmap);
var value = results.FirstOrDefault()?.BarcodeValue;
using var bitmap = new Bitmap(imagePath);
var barcodeXpress = new BarcodeXpress(".");
barcodeXpress.Licensing.SetSolutionName("AcmeCorp");
barcodeXpress.Licensing.SetSolutionKey(1, 2, 3, 4);
barcodeXpress.Licensing.SetOEMLicenseKey("2.0.OEMLicenseStringFromAccusoft...");
barcodeXpress.reader.BarcodeTypes = new[]
{
BarcodeType.Code128Barcode,
BarcodeType.DataMatrixBarcode,
BarcodeType.QRCodeBarcode
};
Result[] results = barcodeXpress.reader.Analyze(bitmap);
var value = results.FirstOrDefault()?.BarcodeValue;
Imports System.Drawing
Imports Accusoft.BarcodeXpressSdk
Using bitmap As New Bitmap(imagePath)
Dim barcodeXpress = New BarcodeXpress(".")
barcodeXpress.Licensing.SetSolutionName("AcmeCorp")
barcodeXpress.Licensing.SetSolutionKey(1, 2, 3, 4)
barcodeXpress.Licensing.SetOEMLicenseKey("2.0.OEMLicenseStringFromAccusoft...")
barcodeXpress.Reader.BarcodeTypes = New BarcodeType() {
BarcodeType.Code128Barcode,
BarcodeType.DataMatrixBarcode,
BarcodeType.QRCodeBarcode
}
Dim results As Result() = barcodeXpress.Reader.Analyze(bitmap)
Dim value = results.FirstOrDefault()?.BarcodeValue
End Using
IronBarcode remplace ce bloc entier par un seul appel statique :
var value = BarcodeReader.Read(imagePath).First().Value;
var value = BarcodeReader.Read(imagePath).First().Value;
Dim value = BarcodeReader.Read(imagePath).First().Value
Comparaison des fonctionnalités Code-barres IronBarcode et d'Accusoft BarcodeXpress
| Fonction | Accusoft BarcodeXpress | Code-barres IronBarcode |
|---|---|---|
| Modèle de licence | Clé SDK + clé OEM/exécution (achats séparés) | Clé perpétuelle unique |
| Licences d'exécution minimales | 5 (même pour 1 serveur) | Concept de licence sans exécution |
| Mode d'évaluation | Valeurs décodées et codes-barres 2D générés estampillés avec " UNLICENSED accusoft.com " | Valeurs complètes renvoyées ; filigrane sur le résultat généré uniquement |
| Limite de débit | 40 PPM (Édition standard) | Aucune limite à aucun niveau |
| Détection automatique du format | Manuel — doit assigner un tableau BarcodeType[] à BarcodeTypes |
Automatique pour tous les formats pris en charge |
| Prise en charge des fichiers PDF | Nécessite une bibliothèque externe pour rendre les pages en Bitmaps | Natif — BarcodeReader.Read("doc.pdf") |
| Style API | Basé sur les instances; entrée bitmap; configuration propriété/méthode | Méthodes de fabrique statiques, API fluide |
| Sécurité des threads | Instance par thread requise | Méthodes statiques sans état — sûres pour les threads |
| Configuration de la licence Docker | montage de fichier de licence ou serveur de licences | Variable d'environnement unique |
| secrets CI/CD requis | Paire de clés SDK + clé OEM/exécution | Un secret |
| .NET Framework / .NET Core | Paquets séparés : Accusoft.BarcodeXpress.Net et Accusoft.BarcodeXpress.NetCore |
Paquet unique IronBarcode (.NET Framework 4.6.2+, .NET Core 3.1+, .NET 5–8) |
| Linux/macOS | Oui (via le paquet .NetCore) | Oui — Windows x64/x86, Linux x64, macOS x64/ARM |
| Code QR avec logo | Superposition GDI+ manuelle requise | AddBrandLogo("logo.png") intégré |
| point d'entrée en matière de prix | $1,960+ SDK + minimum 5 licences runtime | Licence perpétuelle à 749 $ (Lite, 1 développeur) |
| Licence perpétuelle | Non standard — contactez le service commercial | Oui, tous les niveaux |
Démarrage rapide : Migration d'Accusoft BarcodeXpress vers IronBarcode
Étape 1 : Remplacer le package NuGet
dotnet remove package Accusoft.BarcodeXpress.NetCore
dotnet add package IronBarcode
dotnet remove package Accusoft.BarcodeXpress.NetCore
dotnet add package IronBarcode
Étape 2 : Mise à jour des espaces de noms
// Remove
using Accusoft.BarcodeXpressSdk;
// Add
using IronBarCode;
// Remove
using Accusoft.BarcodeXpressSdk;
// Add
using IronBarCode;
Imports IronBarCode
Étape 3 : initialisation de la licence
Ajoutez l'initialisation de la licence une fois au démarrage de l'application dans Program.cs, Startup.cs, ou votre configuration d'injection de dépendances :
// Add once at application startup
IronBarCode.License.LicenseKey = "YOUR-LICENSE-KEY";
// Add once at application startup
IronBarCode.License.LicenseKey = "YOUR-LICENSE-KEY";
' Add once at application startup
IronBarCode.License.LicenseKey = "YOUR-LICENSE-KEY"
En production, lisez la clé à partir d'une variable d'environnement ou de votre gestionnaire de secrets :
IronBarCode.License.LicenseKey =
Environment.GetEnvironmentVariable("IRONBARCODE_LICENSE")
?? throw new InvalidOperationException("IronBarcode license key not configured");
IronBarCode.License.LicenseKey =
Environment.GetEnvironmentVariable("IRONBARCODE_LICENSE")
?? throw new InvalidOperationException("IronBarcode license key not configured");
Imports IronBarCode
Imports System
License.LicenseKey = If(Environment.GetEnvironmentVariable("IRONBARCODE_LICENSE"), Throw New InvalidOperationException("IronBarcode license key not configured"))
Pas de SetSolutionKey, pas de SetOEMLicenseKey, pas d'activation par serveur à l'exécution. Voilà la configuration complète des licences.
Exemples de migration de code
Initialisation de la licence
Approche BarcodeXpress :
using Accusoft.BarcodeXpressSdk;
public class BarcodeService
{
private readonly BarcodeXpress _barcodeXpress;
public BarcodeService()
{
// Constructor takes the path containing the Barcode Xpress runtime files.
_barcodeXpress = new BarcodeXpress(".");
// SDK license
_barcodeXpress.Licensing.SetSolutionName("AcmeCorp");
_barcodeXpress.Licensing.SetSolutionKey(1, 2, 3, 4);
// OEM/runtime license — separate purchase, minimum 5 licenses required.
// Without this call, decoded values and generated 2D barcodes are
// stamped with " UNLICENSED accusoft.com ".
_barcodeXpress.Licensing.SetOEMLicenseKey(
"2.0.OEMLicenseStringFromAccusoft...");
}
}
using Accusoft.BarcodeXpressSdk;
public class BarcodeService
{
private readonly BarcodeXpress _barcodeXpress;
public BarcodeService()
{
// Constructor takes the path containing the Barcode Xpress runtime files.
_barcodeXpress = new BarcodeXpress(".");
// SDK license
_barcodeXpress.Licensing.SetSolutionName("AcmeCorp");
_barcodeXpress.Licensing.SetSolutionKey(1, 2, 3, 4);
// OEM/runtime license — separate purchase, minimum 5 licenses required.
// Without this call, decoded values and generated 2D barcodes are
// stamped with " UNLICENSED accusoft.com ".
_barcodeXpress.Licensing.SetOEMLicenseKey(
"2.0.OEMLicenseStringFromAccusoft...");
}
}
Imports Accusoft.BarcodeXpressSdk
Public Class BarcodeService
Private ReadOnly _barcodeXpress As BarcodeXpress
Public Sub New()
' Constructor takes the path containing the Barcode Xpress runtime files.
_barcodeXpress = New BarcodeXpress(".")
' SDK license
_barcodeXpress.Licensing.SetSolutionName("AcmeCorp")
_barcodeXpress.Licensing.SetSolutionKey(1, 2, 3, 4)
' OEM/runtime license — separate purchase, minimum 5 licenses required.
' Without this call, decoded values and generated 2D barcodes are
' stamped with " UNLICENSED accusoft.com ".
_barcodeXpress.Licensing.SetOEMLicenseKey("2.0.OEMLicenseStringFromAccusoft...")
End Sub
End Class
Approche IronBarcode :
using IronBarCode;
// In Program.cs
IronBarCode.License.LicenseKey = Environment.GetEnvironmentVariable("IRONBARCODE_LICENSE");
// BarcodeService no longer needs a constructor or any license management
public class BarcodeService
{
// Ready to use — no initialization needed
}
using IronBarCode;
// In Program.cs
IronBarCode.License.LicenseKey = Environment.GetEnvironmentVariable("IRONBARCODE_LICENSE");
// BarcodeService no longer needs a constructor or any license management
public class BarcodeService
{
// Ready to use — no initialization needed
}
Imports IronBarCode
' In Program.vb
IronBarCode.License.LicenseKey = Environment.GetEnvironmentVariable("IRONBARCODE_LICENSE")
' BarcodeService no longer needs a constructor or any license management
Public Class BarcodeService
' Ready to use — no initialization needed
End Class
Le constructeur BarcodeXpress existe uniquement pour gérer deux systèmes de clés de licence et le chemin d'exécution. Code-barres IronBarcode le remplace par une ligne au démarrage de l'application. La classe BarcodeService ne nécessite aucun constructeur.
Lecture de codes-barres
Approche BarcodeXpress :
using System.Drawing;
using Accusoft.BarcodeXpressSdk;
public string ReadFirstBarcode(string imagePath)
{
// Analyze takes a System.Drawing.Bitmap; the SDK does not read PDFs directly.
using var bitmap = new Bitmap(imagePath);
_barcodeXpress.reader.BarcodeTypes = new[]
{
BarcodeType.Code128Barcode,
BarcodeType.DataMatrixBarcode,
BarcodeType.QRCodeBarcode
};
Result[] results = _barcodeXpress.reader.Analyze(bitmap);
return results.FirstOrDefault()?.BarcodeValue;
}
using System.Drawing;
using Accusoft.BarcodeXpressSdk;
public string ReadFirstBarcode(string imagePath)
{
// Analyze takes a System.Drawing.Bitmap; the SDK does not read PDFs directly.
using var bitmap = new Bitmap(imagePath);
_barcodeXpress.reader.BarcodeTypes = new[]
{
BarcodeType.Code128Barcode,
BarcodeType.DataMatrixBarcode,
BarcodeType.QRCodeBarcode
};
Result[] results = _barcodeXpress.reader.Analyze(bitmap);
return results.FirstOrDefault()?.BarcodeValue;
}
Imports System.Drawing
Imports Accusoft.BarcodeXpressSdk
Public Function ReadFirstBarcode(imagePath As String) As String
' Analyze takes a System.Drawing.Bitmap; the SDK does not read PDFs directly.
Using bitmap As New Bitmap(imagePath)
_barcodeXpress.reader.BarcodeTypes = New BarcodeType() {
BarcodeType.Code128Barcode,
BarcodeType.DataMatrixBarcode,
BarcodeType.QRCodeBarcode
}
Dim results As Result() = _barcodeXpress.reader.Analyze(bitmap)
Return results.FirstOrDefault()?.BarcodeValue
End Using
End Function
Approche IronBarcode :
using IronBarCode;
public string ReadFirstBarcode(string imagePath)
{
var results = BarcodeReader.Read(imagePath);
return results.First().Value;
}
using IronBarCode;
public string ReadFirstBarcode(string imagePath)
{
var results = BarcodeReader.Read(imagePath);
return results.First().Value;
}
Imports IronBarCode
Public Function ReadFirstBarcode(imagePath As String) As String
Dim results = BarcodeReader.Read(imagePath)
Return results.First().Value
End Function
Le filtrage par tableau BarcodeTypes et l'étape de chargement new Bitmap(...) disparaissent tous les deux. Code-barres IronBarcode détecte automatiquement le format parmi toutes les symbologies prises en charge et accepte directement un chemin de fichier. Si un fournisseur passe du Code 128 au DataMatrix, Code-barres IronBarcode continue de fonctionner sans aucun changement de code. Les noms des propriétés des résultats changent également : BarcodeValue devient Value, et BarcodeType devient Format. Une fonction de recherche et de remplacement à l'échelle de la solution gère les deux renommages.
Lecture de plusieurs codes-barres à partir d'une seule image
Approche BarcodeXpress :
using System.Drawing;
using Accusoft.BarcodeXpressSdk;
public IReadOnlyList<string> ReadAllBarcodes(string imagePath)
{
using var bitmap = new Bitmap(imagePath);
_barcodeXpress.reader.BarcodeTypes = new[]
{
BarcodeType.Code128Barcode,
BarcodeType.QRCodeBarcode
};
Result[] results = _barcodeXpress.reader.Analyze(bitmap);
return results.Select(r => r.BarcodeValue).ToList();
}
using System.Drawing;
using Accusoft.BarcodeXpressSdk;
public IReadOnlyList<string> ReadAllBarcodes(string imagePath)
{
using var bitmap = new Bitmap(imagePath);
_barcodeXpress.reader.BarcodeTypes = new[]
{
BarcodeType.Code128Barcode,
BarcodeType.QRCodeBarcode
};
Result[] results = _barcodeXpress.reader.Analyze(bitmap);
return results.Select(r => r.BarcodeValue).ToList();
}
Imports System.Drawing
Imports Accusoft.BarcodeXpressSdk
Public Function ReadAllBarcodes(imagePath As String) As IReadOnlyList(Of String)
Using bitmap As New Bitmap(imagePath)
_barcodeXpress.reader.BarcodeTypes = New BarcodeType() {
BarcodeType.Code128Barcode,
BarcodeType.QRCodeBarcode
}
Dim results As Result() = _barcodeXpress.reader.Analyze(bitmap)
Return results.Select(Function(r) r.BarcodeValue).ToList()
End Using
End Function
Approche IronBarcode :
using IronBarCode;
public IReadOnlyList<string> ReadAllBarcodes(string imagePath)
{
var options = new BarcodeReaderOptions { ExpectMultipleBarcodes = true };
var results = BarcodeReader.Read(imagePath, options);
return results.Select(r => r.Value).ToList();
}
using IronBarCode;
public IReadOnlyList<string> ReadAllBarcodes(string imagePath)
{
var options = new BarcodeReaderOptions { ExpectMultipleBarcodes = true };
var results = BarcodeReader.Read(imagePath, options);
return results.Select(r => r.Value).ToList();
}
Imports IronBarCode
Public Function ReadAllBarcodes(imagePath As String) As IReadOnlyList(Of String)
Dim options As New BarcodeReaderOptions With {.ExpectMultipleBarcodes = True}
Dim results = BarcodeReader.Read(imagePath, options)
Return results.Select(Function(r) r.Value).ToList()
End Function
ExpectMultipleBarcodes indique à Code-barres IronBarcode de continuer le scannage après le premier résultat correspondant, ce qui est utile pour les documents avec plusieurs codes dans différentes régions. Pour plus de détails sur les options de lecture, consultez la documentation de lecture IronBarcode .
Traitement par lots
BarcodeXpress est basé sur les instances et son objet reader est à état, donc le traitement par lots parallèle nécessite une instance par thread avec l'initialisation complète de la licence à deux niveaux répétée par thread. Les méthodes statiques d'IronBarcode sont sans état, donc Parallel.ForEach ne nécessite pas de gestion des instances.
Approche BarcodeXpress :
using System.Collections.Generic;
using System.Drawing;
using Accusoft.BarcodeXpressSdk;
public Dictionary<string, string> ProcessBatch(IEnumerable<string> imagePaths)
{
var results = new Dictionary<string, string>();
foreach (var path in imagePaths)
{
using var bitmap = new Bitmap(path);
_barcodeXpress.reader.BarcodeTypes = new[]
{
BarcodeType.Code128Barcode,
BarcodeType.QRCodeBarcode
};
Result[] barcodes = _barcodeXpress.reader.Analyze(bitmap);
if (barcodes.Length > 0)
results[path] = barcodes[0].BarcodeValue;
}
return results;
}
using System.Collections.Generic;
using System.Drawing;
using Accusoft.BarcodeXpressSdk;
public Dictionary<string, string> ProcessBatch(IEnumerable<string> imagePaths)
{
var results = new Dictionary<string, string>();
foreach (var path in imagePaths)
{
using var bitmap = new Bitmap(path);
_barcodeXpress.reader.BarcodeTypes = new[]
{
BarcodeType.Code128Barcode,
BarcodeType.QRCodeBarcode
};
Result[] barcodes = _barcodeXpress.reader.Analyze(bitmap);
if (barcodes.Length > 0)
results[path] = barcodes[0].BarcodeValue;
}
return results;
}
Imports System.Collections.Generic
Imports System.Drawing
Imports Accusoft.BarcodeXpressSdk
Public Function ProcessBatch(imagePaths As IEnumerable(Of String)) As Dictionary(Of String, String)
Dim results As New Dictionary(Of String, String)()
For Each path In imagePaths
Using bitmap As New Bitmap(path)
_barcodeXpress.reader.BarcodeTypes = New BarcodeType() {
BarcodeType.Code128Barcode,
BarcodeType.QRCodeBarcode
}
Dim barcodes As Result() = _barcodeXpress.reader.Analyze(bitmap)
If barcodes.Length > 0 Then
results(path) = barcodes(0).BarcodeValue
End If
End Using
Next
Return results
End Function
Approche IronBarcode :
using IronBarCode;
using System.Collections.Concurrent;
using System.Threading.Tasks;
public Dictionary<string, string> ProcessBatch(string[] imagePaths)
{
var results = new ConcurrentDictionary<string, string>();
Parallel.ForEach(imagePaths, file =>
{
var r = BarcodeReader.Read(file);
var first = r.FirstOrDefault();
if (first != null)
results[file] = first.Value;
});
return new Dictionary<string, string>(results);
}
using IronBarCode;
using System.Collections.Concurrent;
using System.Threading.Tasks;
public Dictionary<string, string> ProcessBatch(string[] imagePaths)
{
var results = new ConcurrentDictionary<string, string>();
Parallel.ForEach(imagePaths, file =>
{
var r = BarcodeReader.Read(file);
var first = r.FirstOrDefault();
if (first != null)
results[file] = first.Value;
});
return new Dictionary<string, string>(results);
}
Imports IronBarCode
Imports System.Collections.Concurrent
Imports System.Threading.Tasks
Public Function ProcessBatch(imagePaths As String()) As Dictionary(Of String, String)
Dim results = New ConcurrentDictionary(Of String, String)()
Parallel.ForEach(imagePaths, Sub(file)
Dim r = BarcodeReader.Read(file)
Dim first = r.FirstOrDefault()
If first IsNot Nothing Then
results(file) = first.Value
End If
End Sub)
Return New Dictionary(Of String, String)(results)
End Function
Si la limite de 40 pages par minute de l'édition standard de BarcodeXpress vous a obligé à ajouter du code de gestion de la limite de débit (attente entre les groupes de 40, suivi d'un compteur par minute ou ajout de délais), supprimez entièrement ce code. Code-barres IronBarcode n'a pas de limite de débit.
Ajout de la prise en charge des fichiers PDF
BarcodeXpress ne lit pas les codes-barres directement à partir des fichiers PDF. La solution de contournement classique consiste à ajouter une bibliothèque de rendu PDF distincte, à convertir chaque page en image en mémoire, puis à transmettre ces images au lecteur de codes-barres une par une.
Approche BarcodeXpress :
// Requires a separate PDF library (not shown — varies by team choice)
// Pattern: render each PDF page to a Bitmap, then pass it to Analyze.
foreach (Bitmap pageBitmap in pdfRenderer.RenderPages("document.pdf"))
{
using (pageBitmap)
{
_barcodeXpress.reader.BarcodeTypes = Enum.GetValues(typeof(BarcodeType));
Result[] barcodes = _barcodeXpress.reader.Analyze(pageBitmap);
// ... collect results
}
}
// Requires a separate PDF library (not shown — varies by team choice)
// Pattern: render each PDF page to a Bitmap, then pass it to Analyze.
foreach (Bitmap pageBitmap in pdfRenderer.RenderPages("document.pdf"))
{
using (pageBitmap)
{
_barcodeXpress.reader.BarcodeTypes = Enum.GetValues(typeof(BarcodeType));
Result[] barcodes = _barcodeXpress.reader.Analyze(pageBitmap);
// ... collect results
}
}
Imports System
Imports System.Drawing
' Requires a separate PDF library (not shown — varies by team choice)
' Pattern: render each PDF page to a Bitmap, then pass it to Analyze.
For Each pageBitmap As Bitmap In pdfRenderer.RenderPages("document.pdf")
Using pageBitmap
_barcodeXpress.reader.BarcodeTypes = [Enum].GetValues(GetType(BarcodeType))
Dim barcodes As Result() = _barcodeXpress.reader.Analyze(pageBitmap)
' ... collect results
End Using
Next
Approche IronBarcode :
using IronBarCode;
// One call — no rendering step, no external dependency
var results = BarcodeReader.Read("document.pdf");
foreach (var barcode in results)
{
Console.WriteLine($"Page {barcode.PageNumber}: [{barcode.Format}] {barcode.Value}");
}
using IronBarCode;
// One call — no rendering step, no external dependency
var results = BarcodeReader.Read("document.pdf");
foreach (var barcode in results)
{
Console.WriteLine($"Page {barcode.PageNumber}: [{barcode.Format}] {barcode.Value}");
}
Imports IronBarCode
' One call — no rendering step, no external dependency
Dim results = BarcodeReader.Read("document.pdf")
For Each barcode In results
Console.WriteLine($"Page {barcode.PageNumber}: [{barcode.Format}] {barcode.Value}")
Next
Si Aspose.PDF, PdfiumViewer, itext7, ou toute autre bibliothèque PDF a été ajoutée uniquement pour supporter le flux de travail de lecture de BarcodeXpress, elle peut être retirée après la migration. Voir le guide de lecture de PDF IronBarcode pour des options supplémentaires incluant la sélection de plage de pages.
Génération de codes-barres
Approche BarcodeXpress :
using System.Drawing;
using Accusoft.BarcodeXpressSdk;
public void GenerateBarcode(string data, string outputPath)
{
_barcodeXpress.writer.BarcodeType = BarcodeType.Code128Barcode;
_barcodeXpress.writer.BarcodeValue = data;
// CreateBitmap returns a System.Drawing.Bitmap; persist via Bitmap.Save.
using Bitmap bitmap = _barcodeXpress.writer.CreateBitmap();
bitmap.Save(outputPath);
}
using System.Drawing;
using Accusoft.BarcodeXpressSdk;
public void GenerateBarcode(string data, string outputPath)
{
_barcodeXpress.writer.BarcodeType = BarcodeType.Code128Barcode;
_barcodeXpress.writer.BarcodeValue = data;
// CreateBitmap returns a System.Drawing.Bitmap; persist via Bitmap.Save.
using Bitmap bitmap = _barcodeXpress.writer.CreateBitmap();
bitmap.Save(outputPath);
}
Imports System.Drawing
Imports Accusoft.BarcodeXpressSdk
Public Sub GenerateBarcode(data As String, outputPath As String)
_barcodeXpress.writer.BarcodeType = BarcodeType.Code128Barcode
_barcodeXpress.writer.BarcodeValue = data
' CreateBitmap returns a System.Drawing.Bitmap; persist via Bitmap.Save.
Using bitmap As Bitmap = _barcodeXpress.writer.CreateBitmap()
bitmap.Save(outputPath)
End Using
End Sub
Approche IronBarcode :
using IronBarCode;
public void GenerateBarcode(string data, string outputPath)
{
BarcodeWriter.CreateBarcode(data, BarcodeEncoding.Code128)
.ResizeTo(400, 100)
.SaveAsPng(outputPath);
}
using IronBarCode;
public void GenerateBarcode(string data, string outputPath)
{
BarcodeWriter.CreateBarcode(data, BarcodeEncoding.Code128)
.ResizeTo(400, 100)
.SaveAsPng(outputPath);
}
Imports IronBarCode
Public Sub GenerateBarcode(data As String, outputPath As String)
BarcodeWriter.CreateBarcode(data, BarcodeEncoding.Code128) _
.ResizeTo(400, 100) _
.SaveAsPng(outputPath)
End Sub
La chaîne fluide remplace les affectations de propriétés, l'appel CreateBitmap et l'étape Bitmap.Save. Pour obtenir le code-barres en tant que données binaires pour stockage dans une base de données ou retour d'une API :
byte[] pngBytes = BarcodeWriter.CreateBarcode(data, BarcodeEncoding.Code128)
.ToPngBinaryData();
byte[] pngBytes = BarcodeWriter.CreateBarcode(data, BarcodeEncoding.Code128)
.ToPngBinaryData();
Dim pngBytes As Byte() = BarcodeWriter.CreateBarcode(data, BarcodeEncoding.Code128).ToPngBinaryData()
Génération de codes QR
Approche BarcodeXpress :
_barcodeXpress.writer.BarcodeType = BarcodeType.QRCodeBarcode;
_barcodeXpress.writer.BarcodeValue = data;
using Bitmap bitmap = _barcodeXpress.writer.CreateBitmap();
bitmap.Save("qr.png");
// Logo overlay required manual GDI+ drawing on the returned Bitmap
_barcodeXpress.writer.BarcodeType = BarcodeType.QRCodeBarcode;
_barcodeXpress.writer.BarcodeValue = data;
using Bitmap bitmap = _barcodeXpress.writer.CreateBitmap();
bitmap.Save("qr.png");
// Logo overlay required manual GDI+ drawing on the returned Bitmap
Imports System.Drawing
_barcodeXpress.writer.BarcodeType = BarcodeType.QRCodeBarcode
_barcodeXpress.writer.BarcodeValue = data
Using bitmap As Bitmap = _barcodeXpress.writer.CreateBitmap()
bitmap.Save("qr.png")
' Logo overlay required manual GDI+ drawing on the returned Bitmap
End Using
Approche IronBarcode :
using IronBarCode;
using IronSoftware.Drawing;
// Simple QR
QRCodeWriter.CreateQrCode("https://example.com", 500)
.SaveAsPng("qr.png");
// With branded logo
QRCodeWriter.CreateQrCode("https://example.com", 500)
.AddBrandLogo("logo.png")
.SaveAsPng("qr-branded.png");
// With high error correction (for logo overlays)
QRCodeWriter.CreateQrCode(
"https://example.com",
500,
QRCodeWriter.QrErrorCorrectionLevel.Highest)
.AddBrandLogo("logo.png")
.SaveAsPng("qr-branded-high-ecc.png");
// Colored QR code
QRCodeWriter.CreateQrCode("https://example.com", 300)
.ChangeBarCodeColor(Color.DarkBlue)
.SaveAsPng("qr-colored.png");
using IronBarCode;
using IronSoftware.Drawing;
// Simple QR
QRCodeWriter.CreateQrCode("https://example.com", 500)
.SaveAsPng("qr.png");
// With branded logo
QRCodeWriter.CreateQrCode("https://example.com", 500)
.AddBrandLogo("logo.png")
.SaveAsPng("qr-branded.png");
// With high error correction (for logo overlays)
QRCodeWriter.CreateQrCode(
"https://example.com",
500,
QRCodeWriter.QrErrorCorrectionLevel.Highest)
.AddBrandLogo("logo.png")
.SaveAsPng("qr-branded-high-ecc.png");
// Colored QR code
QRCodeWriter.CreateQrCode("https://example.com", 300)
.ChangeBarCodeColor(Color.DarkBlue)
.SaveAsPng("qr-colored.png");
Imports IronBarCode
Imports IronSoftware.Drawing
' Simple QR
QRCodeWriter.CreateQrCode("https://example.com", 500) _
.SaveAsPng("qr.png")
' With branded logo
QRCodeWriter.CreateQrCode("https://example.com", 500) _
.AddBrandLogo("logo.png") _
.SaveAsPng("qr-branded.png")
' With high error correction (for logo overlays)
QRCodeWriter.CreateQrCode( _
"https://example.com", _
500, _
QRCodeWriter.QrErrorCorrectionLevel.Highest) _
.AddBrandLogo("logo.png") _
.SaveAsPng("qr-branded-high-ecc.png")
' Colored QR code
QRCodeWriter.CreateQrCode("https://example.com", 300) _
.ChangeBarCodeColor(Color.DarkBlue) _
.SaveAsPng("qr-colored.png")
L'intégration de logos, le niveau de correction d'erreurs et la personnalisation des couleurs sont tous intégrés à l'API Fluent. BarcodeXpress nécessite un dessin manuel GDI+ après l'écriture initiale du fichier pour chacune de ces fonctionnalités. Pour plus d'options de QR code, voir le guide de génération de QR code.
Référence de mappage de l'API Accusoft BarcodeXpressvers IronBarcode
| Accusoft BarcodeXpress | Code-barres IronBarcode |
|---|---|
new BarcodeXpress(".") |
Méthodes statiques — aucune instance requise |
Licensing.SetSolutionName("...") |
IronBarCode.License.LicenseKey = "key" |
Licensing.SetSolutionKey(a, b, c, d) |
(removed — not needed) |
Licensing.SetOEMLicenseKey(string) |
(removed — no OEM/runtime key concept) |
new Bitmap(path) + reader.Analyze(bitmap) |
BarcodeReader.Read(path) |
reader.BarcodeTypes = new[] { BarcodeType.Code128Barcode, ... } |
(removed — auto-detection handles all formats) |
result.BarcodeValue |
result.Value |
result.BarcodeType |
result.Format |
writer.BarcodeType = BarcodeType.Code128Barcode |
BarcodeWriter.CreateBarcode("data", BarcodeEncoding.Code128) |
writer.BarcodeValue = "data" |
(first argument to CreateBarcode) |
writer.CreateBitmap() + bitmap.Save(path) |
.SaveAsPng(path) |
writer.BarcodeType = BarcodeType.QRCodeBarcode |
QRCodeWriter.CreateQrCode(data, size) |
| Limite standard de 40 ppm | Aucune limite de débit à aucun niveau |
Problèmes de migration courants et solutions
Problème 1 : Erreurs de compilation du nom de propriété
BarcodeXpress : Les objets de résultat exposent BarcodeValue et BarcodeType, qui n'existent pas dans IronBarcode.
Solution : Exécutez une recherche et un remplacement dans toute la solution avant la compilation :
grep -r "\.BarcodeValue" --include="*.cs" .
grep -r "\.BarcodeType" --include="*.cs" .
grep -r "\.BarcodeValue" --include="*.cs" .
grep -r "\.BarcodeType" --include="*.cs" .
Remplacez result.BarcodeValue par result.Value et result.BarcodeType par result.Format dans tous les fichiers trouvés.
Problème 2 : Appels de configuration de licence orphelins
BarcodeXpress : SetSolutionName, SetSolutionKey, et SetOEMLicenseKey appels — plus toute affirmation personnalisée qui détectent le filigrane ' UNLICENSED accusoft.com ' dans le résultat décodé — existent dans de nombreuses bases de code comme défenses contre le mode échec du résultat filigrané.
Solution : Localisez et supprimez tous ces points d'appel — Code-barres IronBarcode n'a pas d'état équivalent. La clé de licence est soit valide, soit non, et si elle ne l'est pas, les limites d'essai s'appliquent uniformément plutôt que de dégrader chaque valeur décodée individuellement :
grep -r "SetOEMLicenseKey" --include="*.cs" .
grep -r "SetSolutionName" --include="*.cs" .
grep -r "SetSolutionKey" --include="*.cs" .
grep -r "UNLICENSED accusoft" --include="*.cs" .
grep -r "SetOEMLicenseKey" --include="*.cs" .
grep -r "SetSolutionName" --include="*.cs" .
grep -r "SetSolutionKey" --include="*.cs" .
grep -r "UNLICENSED accusoft" --include="*.cs" .
Tous ces sites d'appel peuvent être supprimés.
Problème 3 : Montage du fichier de licence Docker dans une variable d'environnement
BarcodeXpress : Les déploiements Docker montent généralement un fichier de configuration de licence BarcodeXpress dans le conteneur à un chemin connu en utilisant une instruction COPY ou une instruction de montage de volume.
Solution : Supprimez la copie du fichier de configuration et remplacez-la par une variable d'environnement :
# Remove this
COPY accusoft-license.lic /app/license/
# Add this
ENV IRONBARCODE_LICENSE=YOUR-LICENSE-KEY
Au démarrage de l'application :
IronBarCode.License.LicenseKey =
Environment.GetEnvironmentVariable("IRONBARCODE_LICENSE");
IronBarCode.License.LicenseKey =
Environment.GetEnvironmentVariable("IRONBARCODE_LICENSE");
Imports System
IronBarCode.License.LicenseKey = Environment.GetEnvironmentVariable("IRONBARCODE_LICENSE")
Dans Kubernetes, la clé de licence devient une référence secrète dans la spécification du pod :
env:
- name: IRONBARCODE_LICENSE
valueFrom:
secretKeyRef:
name: ironbarcode-secrets
key: license-key
env:
- name: IRONBARCODE_LICENSE
valueFrom:
secretKeyRef:
name: ironbarcode-secrets
key: license-key
Problème 4 : Code de gestion des limites de débit
BarcodeXpress : Les équipes traitant de grands lots dans la limite de 40 PPM de l'édition standard ajoutaient souvent du code pour faire une pause entre les groupes de documents, suivre les compteurs par minute ou introduire des délais pour rester dans la limite.
Solution : Supprimer tout le code de limitation de débit. Localisez-le avec :
grep -r "40\|PPM\|pagesPerMinute\|minuteStart" --include="*.cs" .
grep -r "40\|PPM\|pagesPerMinute\|minuteStart" --include="*.cs" .
IronBarcode n'a pas de limite de débit : traitez les données à la vitesse que votre infrastructure supporte.
Problème 5 : Sécurité des threads — Suppression du pool d'instances
BarcodeXpress : Les bases de code qui supportent le traitement concurrent maintiennent souvent un pool d'instances BarcodeXpress ou utilisent un modèle ThreadLocal<BarcodeXpress> pour isoler le lecteur à état par thread.
Solution : Supprimer complètement la logique de mise en pool. Les BarcodeReader.Read et BarcodeWriter.CreateBarcode d'IronBarcode sont des méthodes statiques sans état. Les appels simultanés provenant d'un nombre quelconque de threads n'interfèrent pas entre eux.
Liste de contrôle de migration Accusoft BarcodeXpress
Tâches préalables à la migration
Avant d'apporter toute modification au code, auditez la base de code afin d'identifier toutes les utilisations de BarcodeXpress :
grep -r "BarcodeXpress" --include="*.cs" .
grep -r "Accusoft" --include="*.cs" .
grep -r "SetSolutionName" --include="*.cs" .
grep -r "SetSolutionKey" --include="*.cs" .
grep -r "SetOEMLicenseKey" --include="*.cs" .
grep -r "reader\.Analyze" --include="*.cs" .
grep -r "writer\.CreateBitmap" --include="*.cs" .
grep -r "\.BarcodeValue" --include="*.cs" .
grep -r "\.BarcodeType" --include="*.cs" .
grep -r "BarcodeType\." --include="*.cs" .
grep -r "BarcodeXpress" --include="*.cs" .
grep -r "Accusoft" --include="*.cs" .
grep -r "SetSolutionName" --include="*.cs" .
grep -r "SetSolutionKey" --include="*.cs" .
grep -r "SetOEMLicenseKey" --include="*.cs" .
grep -r "reader\.Analyze" --include="*.cs" .
grep -r "writer\.CreateBitmap" --include="*.cs" .
grep -r "\.BarcodeValue" --include="*.cs" .
grep -r "\.BarcodeType" --include="*.cs" .
grep -r "BarcodeType\." --include="*.cs" .
- Notez quels formats de code-barres sont explicitement listés dans les affectations
BarcodeTypes— ils deviennent tous auto-détectés dans IronBarcode - Identifier tout code de gestion des limitations de débit qui peut être supprimé
- Identifiez les bibliothèques de rendu PDF ajoutées uniquement pour la lecture BarcodeXpress ; celles-ci peuvent également être supprimées.
- Obtenez votre clé de licence Code-barres IronBarcode et ajoutez-la à votre gestionnaire de secrets
Tâches de mise à jour du code
- Supprimez
Accusoft.BarcodeXpress.NetCorede tous les fichiers.csproj - Ajoutez
IronBarcodeà tous les fichiers.csprojqui nécessitent la fonctionnalité de code-barres - Remplacez
using Accusoft.BarcodeXpressSdk;parusing IronBarCode;dans tous les fichiers - Ajoutez
IronBarCode.License.LicenseKey = ...au démarrage de l'application - Supprimez tous les appels de constructeur
BarcodeXpresset champs d'instance - Supprimez tous les appels
SetSolutionName,SetSolutionKey, etSetOEMLicenseKey - Supprimez toutes les assertions personnalisées qui analysent les sorties décodées à la recherche du filigrane " UNLICENSED accusoft.com "
- Remplacez
new Bitmap(path)+reader.Analyze(bitmap)parBarcodeReader.Read(path) - Supprimez toutes les affectations
reader.BarcodeTypes = ... - Remplacez
result.BarcodeValueparresult.Value - Remplacez
result.BarcodeTypeparresult.Format - Remplacez
writer.CreateBitmap()+bitmap.Save(path)parBarcodeWriter.CreateBarcode(data, encoding).SaveAsPng(path) - Supprimer le code de limitation de débit
- Supprimez le code intermédiaire de rendu PDF s'il est présent.
- Supprimez les pools d'instance ou les modèles
ThreadLocalpour les instances de BarcodeXpress - Supprimez les points de montage des fichiers de licence des fichiers Dockerfile et docker-compose.
- Ajoutez une variable d'environnement
IRONBARCODE_LICENSEaux configurations Docker et conteneur - Mettre à jour les secrets Kubernetes et les spécifications des pods
- Mettez à jour les secrets du pipeline CI/CD — supprimez
ACCUSOFT_SOLUTION_KEYetACCUSOFT_RUNTIME_KEY; ajoutezIRONBARCODE_LICENSE
Test de post-migration
- Compiler la solution — corriger les erreurs de compilation restantes dues aux propriétés renommées
- Exécuter des tests unitaires sur toutes les opérations de lecture de codes-barres
- Exécuter des tests unitaires sur toutes les opérations de génération de codes-barres
- Effectuer des tests avec des entrées PDF, le cas échéant.
- Effectuez un test de traitement par lots pour confirmer l'absence de limitation de débit.
- Déployez dans un environnement de test et vérifiez que la clé de licence est correctement résolue à partir de la variable d'environnement.
Principaux avantages de la migration vers IronBarcode
Élimination de la complexité de licence à deux clés : La configuration SetSolutionName, SetSolutionKey, et SetOEMLicenseKey disparaît entièrement. Une clé couvre chaque environnement du développement à la production, et le mode d'essai renvoie des valeurs décodées complètes (plutôt que d'estampiller chacune d'elles avec " UNLICENSED accusoft.com ") afin que la valorisation pré-achat sur des documents réels soit possible.
Aucun achat minimum de licences d'exécution : BarcodeXpress requiert un minimum de cinq licences d'exécution pour tout déploiement en production. Code-barres IronBarcode n'a pas de concept de licence d'exécution — la clé perpétuelle unique couvre un nombre illimité de déploiements en production au sein de son niveau.
Débit sans plafond : la limite de 40 PPM de l'édition standard et tout code de limitation de débit écrit pour rester en deçà peuvent être supprimés. Code-barres IronBarcode traite les données à la vitesse maximale supportée par le matériel et le réseau sous-jacents, sans plafond imposé par logiciel à aucun niveau de prix.
Lecture PDF native : BarcodeReader.Read("document.pdf") traite les fichiers PDF directement, retournant des résultats par page avec numéro de page, format, valeur, et score de confiance. Toute bibliothèque de rendu PDF ajoutée uniquement pour prendre en charge BarcodeXpress peut être supprimée, ce qui réduit les dépendances et les coûts de licence.
Sécurité des threads sans état : BarcodeReader.Read et BarcodeWriter.CreateBarcode sont des méthodes statiques sans état. Les pools d'instances, les modèles ThreadLocal et les blocs d'initialisation par thread peuvent tous être supprimés. Le traitement concurrent avec Parallel.ForEach ne nécessite pas de changements structurels au-delà de la suppression des solutions de contournement du threading.
Déploiement simplifié de conteneurs : les déploiements Docker et Kubernetes utilisent une seule variable d'environnement pour la configuration des licences. La distribution des fichiers de licence, l'infrastructure des serveurs de licences et les points de montage des fichiers de configuration sont tous éliminés.
Questions Fréquemment Posées
Pourquoi devrais-je migrer d'Accusoft BarcodeXpress 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 d'Accusoft BarcodeXpress 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 d'Accusoft BarcodeXpress 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 à la fois Accusoft BarcodeXpress 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 à Accusoft BarcodeXpress ?
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 Accusoft BarcodeXpress ?
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 d'Accusoft BarcodeXpress 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.

