Syncfusion Barcode vs IronBarcode: Comparación de bibliotecas de códigos de barras C#
ZXing.Net vs IronBarcode: Elegir una biblioteca de códigos de barras .NET en 2026
ZXing.Net's BarcodeReader no es seguro para hilos. Cada ruta de lectura concurrente en su aplicación — cada ForEach paralelo, cada acción de controlador asíncrona que maneja solicitudes simultáneas — requiere su propia instancia de lector. Eso significa configuración de formato repetida por instancia, carga y disposición de Bitmap por llamada, y asignación de lector en cada solicitud. El método estático de IronBarcode maneja el mismo trabajo sin asignación por solicitud. La seguridad de los subprocesos es solo uno de los puntos de la lista: la falta de compatibilidad nativa con PDF, la fragmentación de los paquetes de enlace entre Windows y Linux, y la necesidad de especificar cada formato de código de barras que se pretende escanear; estas son las características que provocan que los proyectos .NET con ZX acumulen soluciones alternativas con el tiempo.
Comprender ZXing .NET
ZXing .NET es una adaptación de código abierto de la biblioteca Java ZXing ("Zebra Crossing") de Google, publicada bajo la licencia Apache 2.0y mantenida por Michael Jahn en GitHub. Es la biblioteca de códigos de barras de código abierto más descargada para .NET, con una larga trayectoria que se remonta a más de una década. La biblioteca abarca tanto la lectura como la escritura en una amplia gama de formatos de códigos de barras, y su licencia gratuita la hace accesible para proyectos de todos los tamaños, incluidos los productos de código abierto que requieren dependencias compatibles con Apache.
La arquitectura de ZXing.Net refleja sus orígenes como una adaptación de Java. La clase BarcodeReader es un objeto con estado: llamar a Decode escribe estado interno, lo que hace que las instancias no sean seguras para compartir entre hilos. El uso concurrente correcto requiere ya sea un nuevo lector por hilo o un grupo de ThreadLocal<BarcodeReader> — ambos de los cuales colocan la responsabilidad de seguridad de hilos en el llamador. La carga de imágenes tampoco está incluida en el paquete principal; En cambio, ZXing .NET proporciona paquetes de enlace específicos para cada plataforma, cada uno de los cuales expone una interfaz API diferente.
Las características arquitectónicas clave incluyen:
- Licencia Apache 2.0: Gratuita para uso comercial y de código abierto, sin coste alguno y sin necesidad de contactar con el departamento de ventas.
- Lector de Códigos de Barra con Estado: La instancia de
BarcodeReaderno es segura para hilos; Se debe crear una nueva instancia por cada hilo o por cada operación paralela. - Especificación Manual de Formato: Los llamadores deben establecer
reader.Options.PossibleFormatsantes de cada decodificación; Los formatos que no aparecen en la lista se omiten silenciosamente sin ningún error ni advertencia. - Sin soporte nativo para PDF: la biblioteca solo lee imágenes; La entrada de archivos PDF requiere una biblioteca de renderizado de PDF independiente, como PdfiumViewer, para convertir las páginas en mapas de bits antes de la decodificación.
- Fragmentación de la vinculación de la plataforma: el paquete principal no proporciona carga de imágenes; paquetes de vinculación separados (
ZXing.Net.Bindings.Windows.CompatibilityusandoSystem.Drawing,ZXing.Net.Bindings.ImageSharp/.V2/.V3usando SixLabors.ImageSharp, además deZXing.Net.Bindings.SkiaSharpyZXing.Net.Bindings.Magick) exponen diferentes APIs para diferentes objetivos de implementación. - Comunidad activa: Los problemas, las solicitudes de extracción y los debates son activos en GitHub, lo que proporciona soporte a nivel de comunidad sin coste alguno.
- Amplia compatibilidad de formatos: Admite códigos QR, Code 128, Code 39, EAN-13, EAN-8, UPC-A, Data Matrix, PDF 417, Aztec y otras simbologías de uso común.
La arquitectura del lector estatal
El BarcodeReader de ZXing.Net requiere una nueva instancia para cada hilo u operación paralela. El siguiente patrón muestra la configuración mínima correcta para el procesamiento concurrente:
// ZXing.Net: a new reader instance is created per iteration
Parallel.ForEach(imagePaths, path =>
{
var reader = new BarcodeReader();
reader.Options.PossibleFormats = new List<BarcodeFormat>
{
BarcodeFormat.QR_CODE,
BarcodeFormat.CODE_128,
BarcodeFormat.EAN_13
};
using var bitmap = new Bitmap(path);
var result = reader.Decode(bitmap);
if (result != null)
results[path] = result.Text;
});
// ZXing.Net: a new reader instance is created per iteration
Parallel.ForEach(imagePaths, path =>
{
var reader = new BarcodeReader();
reader.Options.PossibleFormats = new List<BarcodeFormat>
{
BarcodeFormat.QR_CODE,
BarcodeFormat.CODE_128,
BarcodeFormat.EAN_13
};
using var bitmap = new Bitmap(path);
var result = reader.Decode(bitmap);
if (result != null)
results[path] = result.Text;
});
Imports System.Collections.Concurrent
Imports System.Drawing
Imports ZXing
Parallel.ForEach(imagePaths, Sub(path)
Dim reader = New BarcodeReader()
reader.Options.PossibleFormats = New List(Of BarcodeFormat) From {
BarcodeFormat.QR_CODE,
BarcodeFormat.CODE_128,
BarcodeFormat.EAN_13
}
Using bitmap As New Bitmap(path)
Dim result = reader.Decode(bitmap)
If result IsNot Nothing Then
results(path) = result.Text
End If
End Using
End Sub)
El patrón ThreadLocal<BarcodeReader> reduce la asignación por llamada reutilizando una instancia por hilo, pero agrega complejidad de disposición. De cualquier forma, la seguridad de hilos es responsabilidad del llamador en ZXing.Net.
Entendiendo IronBarcode
IronBarcode es una biblioteca comercial de códigos de barras .NET desarrollada por Iron Software. Proporciona lectura y generación de códigos de barras a través de una API estática sin estado: BarcodeReader.Read y BarcodeWriter.CreateBarcode son los puntos de entrada principales, y ninguno requiere creación o configuración de instancias antes de su uso. La biblioteca se distribuye como un único paquete NuGet que se ejecuta de forma idéntica en Windows, Linux, macOSy dentro de contenedores Docker sin necesidad de paquetes de enlace específicos de la plataforma.
El motor de lectura de IronBarcode realiza una detección automática del formato en más de 50 simbologías de códigos de barras. Quienes llaman no especifican qué formatos buscar; El motor evalúa cada imagen comparándola con todos los formatos compatibles y devuelve todos los códigos de barras encontrados. Para aplicaciones que necesitan equilibrar la velocidad de escaneo con la exhaustividad, un enum ReadingSpeed (Faster, Balanced, Detailed, ExtremeDetail) brinda control sin requerir enumeración de formato. La biblioteca también incluye compatibilidad nativa con PDF, lo que permite leer códigos de barras directamente desde documentos PDF en todas las páginas sin necesidad de una biblioteca de renderizado de PDF independiente.
Las características clave incluyen:
- Licencia comercial: Requiere una clave de licencia de pago; El modo de prueba está disponible para su evaluación.
- API Estática Sin Estado:
BarcodeReader.ReadyBarcodeWriter.CreateBarcodeson métodos estáticos seguros para hilos; No se requiere administración de instancias. - Detección automática de formato: Se detectan los más de 50 formatos de código de barras compatibles sin necesidad de una lista de formatos; los usuarios priorizan la velocidad en lugar del alcance del formato.
- Soporte Nativo de PDF:
BarcodeReader.Readacepta rutas de archivos PDF directamente, procesando todas las páginas sin una biblioteca PDF externa. - Paquete único multiplataforma: Un único paquete NuGet se ejecuta en Windows, Linux, macOSy Docker con la misma interfaz API.
- API de Generación Fluida:
BarcodeWriter.CreateBarcodedevuelve un objetoGeneratedBarcodecon métodos de salida integrados que incluyenSaveAsPng,SaveAsPdf,ToPngBinaryData, yToStream. - Soporte comercial: Las licencias de pago incluyen acceso al equipo de soporte de Iron Software con compromisos de nivel de servicio.
Comparación de características
La siguiente tabla destaca las diferencias fundamentales entre ZXing .NET e IronBarcode:
| Característica | ZXing.Net | IronBarcode |
|---|---|---|
| Licencia | Apache 2.0(gratuito) | Comercial |
| Seguridad de hilos | No es seguro para subprocesos: se requiere una nueva instancia por cada subproceso. | API estática segura para subprocesos |
| Detección de formato | Manual — lista de PossibleFormats requerida |
Automático: más de 50 formatos |
| Lectura de PDF | No — requiere PdfiumViewer o similar | Nativo: llamada a un solo método |
| Soporte de Plataforma | Paquetes de enlace separados por plataforma | Paquete único, todas las plataformas |
| Generación de códigos de barras | Devuelve Bitmap, requiere guardado manual |
API fluida con salida integrada |
| Precios | Gratis | Desde $749 (Lite) / $1,499 (Plus) |
Comparación detallada de características
| Característica | ZXing.Net | IronBarcode |
|---|---|---|
| Lectura | ||
| Lectura segura para subprocesos | No, se requieren instancias por hilo. | Sí, API estática sin estado |
| Detección automática de formato | No — PossibleFormats requerido |
Sí, todos los formatos se detectan automáticamente. |
| Varios códigos de barras por imagen | Sí — DecodeMultiple |
Sí — comportamiento predeterminado |
| Lectura de códigos de barras PDF | No — se requiere biblioteca externa | Sí, nativo |
| Recuperación de códigos de barras dañados | bandera TryHarder |
Corrección de imágenes mediante aprendizaje automático |
| Ajuste de velocidad/precisión | Reducción de lista de formato | enum ReadingSpeed |
| Generación | ||
| Código 128 / Código 39 | Sí | Sí |
| Código QR | Sí | Sí |
| Código QR con logotipo | No | Sí |
| Personalización del color del código QR | No | Sí |
| Salida a PNG/JPEG/PDF | Manual vía System.Drawing |
Métodos de salida integrados |
| Cadena de generación fluida | No | Sí |
| Plataforma y despliegue | ||
| Ventanas (Dibujo del sistema) | Sí — ZXing.Net.Bindings.Windows.Compatibility |
Sí |
| Linux / Docker | Sí —ZXing.Net.Bindings.ImageSharp / .V2 / .V3(API diferente) |
Sí, la misma API. |
| macOS | Sí — ZXing.Net.Bindings.ImageSharp / .V2 / .V3 |
Sí |
| Dependencias adicionales de Docker | Puede requerir libgdiplus |
None |
| Paquete NuGet único | No — núcleo + enlace + ImageSharp opcional | Sí |
| Licencias y soporte | ||
| Tipo de licencia | Apache 2.0 | Comercial |
| Coste | Gratis | A partir de 749 |
| Apoyo de la comunidad | Problemas en GitHub , comunidad activa | Sí |
| Soporte para SLA comerciales | No | Sí |
| Compatible con el código abierto | Sí | No |
Seguridad de subprocesos y procesamiento concurrente
La seguridad de los subprocesos es la diferencia operativa más importante entre las dos bibliotecas, y afecta a más proyectos de lo que podrían sugerir las advertencias de la documentación.
Enfoque ZXing .NET
El BarcodeReader de ZXing.Net es un objeto con estado. Cuando se llama a Decode, se escribe el estado interno. Si dos hilos comparten la misma instancia, se produce una condición de carrera en las escrituras. Los resultados no son deterministas: puede obtener un resultado de una imagen diferente, un valor nulo donde existe un código de barras o una excepción. El enfoque correcto consiste en crear un lector por hilo, lo que significa que cada ruta paralela o asíncrona asigna un lector, lo configura, lo usa una vez y lo descarta:
// ZXing.Net: one reader instance per parallel operation
Parallel.ForEach(imagePaths, path =>
{
var reader = new BarcodeReader();
reader.Options.PossibleFormats = new List<BarcodeFormat>
{
BarcodeFormat.QR_CODE,
BarcodeFormat.CODE_128,
BarcodeFormat.EAN_13
};
using var bitmap = new Bitmap(path);
var result = reader.Decode(bitmap);
if (result != null)
results[path] = result.Text;
});
// ZXing.Net: one reader instance per parallel operation
Parallel.ForEach(imagePaths, path =>
{
var reader = new BarcodeReader();
reader.Options.PossibleFormats = new List<BarcodeFormat>
{
BarcodeFormat.QR_CODE,
BarcodeFormat.CODE_128,
BarcodeFormat.EAN_13
};
using var bitmap = new Bitmap(path);
var result = reader.Decode(bitmap);
if (result != null)
results[path] = result.Text;
});
Imports System.Collections.Concurrent
Imports System.Drawing
Imports ZXing
Parallel.ForEach(imagePaths, Sub(path)
Dim reader As New BarcodeReader()
reader.Options.PossibleFormats = New List(Of BarcodeFormat) From {
BarcodeFormat.QR_CODE,
BarcodeFormat.CODE_128,
BarcodeFormat.EAN_13
}
Using bitmap As New Bitmap(path)
Dim result = reader.Decode(bitmap)
If result IsNot Nothing Then
results(path) = result.Text
End If
End Using
End Sub)
El patrón ThreadLocal<BarcodeReader> reduce la asignación por llamada reutilizando un lector por hilo, pero agrega complejidad de disposición y todavía requiere configuración de formato en cada instancia.
Enfoque IronBarcode
El BarcodeReader.Read de IronBarcode es un método estático sin estado. No hay ninguna instancia que compartir, ninguna instancia que aislar y ningún estado de configuración que proteger. La misma llamada se ejecuta de forma segura desde cualquier número de hilos concurrentes:
// IronBarcode: static method — no instance management
var options = new BarcodeReaderOptions
{
Speed = ReadingSpeed.Balanced,
ExpectMultipleBarcodes = true,
MaxParallelThreads = 4
};
Parallel.ForEach(imagePaths, path =>
{
var result = BarcodeReader.Read(path, options).FirstOrDefault();
if (result != null)
results[path] = result.Value;
});
// IronBarcode: static method — no instance management
var options = new BarcodeReaderOptions
{
Speed = ReadingSpeed.Balanced,
ExpectMultipleBarcodes = true,
MaxParallelThreads = 4
};
Parallel.ForEach(imagePaths, path =>
{
var result = BarcodeReader.Read(path, options).FirstOrDefault();
if (result != null)
results[path] = result.Value;
});
Imports IronBarcode
Dim options As New BarcodeReaderOptions With {
.Speed = ReadingSpeed.Balanced,
.ExpectMultipleBarcodes = True,
.MaxParallelThreads = 4
}
Parallel.ForEach(imagePaths, Sub(path)
Dim result = BarcodeReader.Read(path, options).FirstOrDefault()
If result IsNot Nothing Then
results(path) = result.Value
End If
End Sub)
La documentación de IronBarcode sobre la lectura de códigos de barras asíncrona y multihilo explica el modelo interno de agrupación de hilos. La propiedad MaxParallelThreads controla el grado de paralelismo sin requerir coordinación externa.
Detección de formato
La política de detección de formato es la segunda diferencia operativa significativa entre las dos bibliotecas.
Enfoque ZXing .NET
ZXing.Net requiere que reader.Options.PossibleFormats esté poblado antes de cada decodificación. Si un formato de código de barras no aparece en la lista, no se detectará, sin error, sin advertencia y sin resultado parcial:
// ZXing.Net: PossibleFormats list controls which symbologies are decoded
var reader = new BarcodeReader();
reader.Options.PossibleFormats = new List<BarcodeFormat>
{
BarcodeFormat.QR_CODE,
BarcodeFormat.CODE_128,
BarcodeFormat.CODE_39,
BarcodeFormat.EAN_13,
BarcodeFormat.EAN_8,
BarcodeFormat.UPC_A,
BarcodeFormat.DATA_MATRIX,
BarcodeFormat.PDF_417
};
reader.Options.TryHarder = true;
using var bitmap = new Bitmap(imagePath);
var results = reader.DecodeMultiple(bitmap);
// ZXing.Net: PossibleFormats list controls which symbologies are decoded
var reader = new BarcodeReader();
reader.Options.PossibleFormats = new List<BarcodeFormat>
{
BarcodeFormat.QR_CODE,
BarcodeFormat.CODE_128,
BarcodeFormat.CODE_39,
BarcodeFormat.EAN_13,
BarcodeFormat.EAN_8,
BarcodeFormat.UPC_A,
BarcodeFormat.DATA_MATRIX,
BarcodeFormat.PDF_417
};
reader.Options.TryHarder = true;
using var bitmap = new Bitmap(imagePath);
var results = reader.DecodeMultiple(bitmap);
Imports ZXing
Imports ZXing.Common
' ZXing.Net: PossibleFormats list controls which symbologies are decoded
Dim reader As New BarcodeReader()
reader.Options.PossibleFormats = New List(Of BarcodeFormat) From {
BarcodeFormat.QR_CODE,
BarcodeFormat.CODE_128,
BarcodeFormat.CODE_39,
BarcodeFormat.EAN_13,
BarcodeFormat.EAN_8,
BarcodeFormat.UPC_A,
BarcodeFormat.DATA_MATRIX,
BarcodeFormat.PDF_417
}
reader.Options.TryHarder = True
Using bitmap As New Bitmap(imagePath)
Dim results = reader.DecodeMultiple(bitmap)
End Using
Si se enumeran todos los formatos para evitar omisiones, el rendimiento se degrada. Si solo se enumeran los formatos esperados, existe el riesgo de que se produzcan errores silenciosos cuando las imágenes provienen de fuentes externas. ZXing .NET no dispone de ningún mecanismo para informar de que ha encontrado un código de barras en un formato no listado.
Enfoque IronBarcode
IronBarcode detecta automáticamente los más de 50 formatos compatibles. No se requiere ni se acepta ninguna lista de formatos:
// IronBarcode: automatic detection across all supported formats
var results = BarcodeReader.Read(imagePath);
foreach (var barcode in results)
{
Console.WriteLine($"{barcode.Value} ({barcode.Format})");
}
// IronBarcode: automatic detection across all supported formats
var results = BarcodeReader.Read(imagePath);
foreach (var barcode in results)
{
Console.WriteLine($"{barcode.Value} ({barcode.Format})");
}
Imports IronBarcode
' IronBarcode: automatic detection across all supported formats
Dim results = BarcodeReader.Read(imagePath)
For Each barcode In results
Console.WriteLine($"{barcode.Value} ({barcode.Format})")
Next
Para aplicaciones que ajustan la velocidad de lectura contra la exhaustividad de detección, IronBarcode expone un enum ReadingSpeed — Faster, Balanced, Detailed, ExtremeDetail — sin requerir enumeración de formato. La optimización de la velocidad afecta a la agresividad con la que el motor procesa cada imagen, no a los formatos que considera.
Compatibilidad con documentos PDF
La lectura de archivos PDF es una limitación insalvable en ZXing .NET: la biblioteca no ofrece ningún tipo de soporte para PDF.
Enfoque ZXing .NET
Cuando un código de barras llega incrustado en un PDF, ZXing .NET requiere una biblioteca externa de renderizado de PDF. La solución alternativa más común utiliza PdfiumViewer, que añade aproximadamente 20 MB de binarios nativos y un bucle de renderizado de página que los usuarios deben implementar y mantener:
// ZXing.Net: PDF input is handled by PdfiumViewer with a per-page render loop
using var pdfDocument = PdfDocument.Load(pdfPath);
var reader = new BarcodeReader();
reader.Options.PossibleFormats = new List<BarcodeFormat>
{
BarcodeFormat.QR_CODE,
BarcodeFormat.CODE_128,
BarcodeFormat.PDF_417
};
for (int i = 0; i < pdfDocument.PageCount; i++)
{
string tempPath = Path.Combine(Path.GetTempPath(), $"{Guid.NewGuid()}.png");
try
{
using var pageImage = pdfDocument.Render(i, 200, 200, PdfRenderFlags.CorrectFromDpi);
pageImage.Save(tempPath, ImageFormat.Png);
using var bitmap = new Bitmap(tempPath);
var decoded = reader.DecodeMultiple(bitmap);
if (decoded != null)
results.AddRange(decoded.Select(d => d.Text));
}
finally
{
File.Delete(tempPath);
}
}
// ZXing.Net: PDF input is handled by PdfiumViewer with a per-page render loop
using var pdfDocument = PdfDocument.Load(pdfPath);
var reader = new BarcodeReader();
reader.Options.PossibleFormats = new List<BarcodeFormat>
{
BarcodeFormat.QR_CODE,
BarcodeFormat.CODE_128,
BarcodeFormat.PDF_417
};
for (int i = 0; i < pdfDocument.PageCount; i++)
{
string tempPath = Path.Combine(Path.GetTempPath(), $"{Guid.NewGuid()}.png");
try
{
using var pageImage = pdfDocument.Render(i, 200, 200, PdfRenderFlags.CorrectFromDpi);
pageImage.Save(tempPath, ImageFormat.Png);
using var bitmap = new Bitmap(tempPath);
var decoded = reader.DecodeMultiple(bitmap);
if (decoded != null)
results.AddRange(decoded.Select(d => d.Text));
}
finally
{
File.Delete(tempPath);
}
}
Imports System.IO
Imports System.Drawing
Imports PdfiumViewer
Imports ZXing
Imports ZXing.Common
' ZXing.Net: PDF input is handled by PdfiumViewer with a per-page render loop
Using pdfDocument As PdfDocument = PdfDocument.Load(pdfPath)
Dim reader As New BarcodeReader()
reader.Options.PossibleFormats = New List(Of BarcodeFormat) From {
BarcodeFormat.QR_CODE,
BarcodeFormat.CODE_128,
BarcodeFormat.PDF_417
}
For i As Integer = 0 To pdfDocument.PageCount - 1
Dim tempPath As String = Path.Combine(Path.GetTempPath(), $"{Guid.NewGuid()}.png")
Try
Using pageImage As Image = pdfDocument.Render(i, 200, 200, PdfRenderFlags.CorrectFromDpi)
pageImage.Save(tempPath, Imaging.ImageFormat.Png)
Using bitmap As New Bitmap(tempPath)
Dim decoded = reader.DecodeMultiple(bitmap)
If decoded IsNot Nothing Then
results.AddRange(decoded.Select(Function(d) d.Text))
End If
End Using
End Using
Finally
File.Delete(tempPath)
End Try
Next
End Using
Este patrón presenta modos de fallo reales: una configuración incorrecta de DPI provoca fallos silenciosos, los permisos de archivos temporales fallan en entornos restringidos, las bibliotecas nativas de PdfiumViewer requieren una gestión de implementación independiente y la configuración no funciona en Linux sin una configuración adicional.
Enfoque IronBarcode
IronBarcode lee códigos de barras de archivos PDF de forma nativa : todas las páginas, todos los formatos, sin dependencias externas. La misma llamada BarcodeReader.Read acepta rutas de PDF directamente:
// IronBarcode: one call processes every page of the PDF
var results = BarcodeReader.Read("invoice.pdf");
foreach (var barcode in results)
Console.WriteLine($"Page {barcode.PageNumber}: {barcode.Value}");
// IronBarcode: one call processes every page of the PDF
var results = BarcodeReader.Read("invoice.pdf");
foreach (var barcode in results)
Console.WriteLine($"Page {barcode.PageNumber}: {barcode.Value}");
Imports IronBarcode
' IronBarcode: one call processes every page of the PDF
Dim results = BarcodeReader.Read("invoice.pdf")
For Each barcode In results
Console.WriteLine($"Page {barcode.PageNumber}: {barcode.Value}")
Next
Sin enumeración de páginas, sin configuración de DPI, sin archivos temporales y sin biblioteca independiente para implementar junto con la aplicación.
Enlaces de plataforma e implementación
El manejo de imágenes de ZXing.Net se distribuye entre paquetes de enlace específicos de la plataforma, cada uno con una interfaz API diferente.
Enfoque ZXing .NET
El paquete central ZXing.Net proporciona lógica de decodificación pero no carga de imagen. Los usuarios deben elegir un enlace en función de su destino de implementación:
| Ambiente | Paquete | Notas |
|---|---|---|
| Escritorio de Windows / WPF | ZXing.Net.Bindings.Windows.Compatibility |
Usa System.Drawing — compatible con Windows; necesita libgdiplus en Linux |
| Linux / Docker/multiplataforma | ZXing.Net.Bindings.ImageSharp / .V2 / .V3 |
Superficie API diferente; añade la dependencia SixLabors.ImageSharp (V2/V3 sigue las versiones principales de ImageSharp) |
| macOS | ZXing.Net.Bindings.ImageSharp / .V2 / .V3 |
El mismo camino que en Linux. |
La consecuencia práctica es que el código de Windows usando System.Drawing.Bitmap no se compila ni se ejecuta en Linux. La contenerización requiere cambiar los paquetes de enlace y reescribir el código de carga de imágenes:
// Windows binding path — uses System.Drawing
using ZXing.Windows.Compatibility;
using System.Drawing;
var reader = new BarcodeReader();
using var bitmap = new Bitmap(imagePath);
var result = reader.Decode(bitmap);
// Windows binding path — uses System.Drawing
using ZXing.Windows.Compatibility;
using System.Drawing;
var reader = new BarcodeReader();
using var bitmap = new Bitmap(imagePath);
var result = reader.Decode(bitmap);
Imports ZXing.Windows.Compatibility
Imports System.Drawing
Dim reader As New BarcodeReader()
Using bitmap As New Bitmap(imagePath)
Dim result = reader.Decode(bitmap)
End Using
// Cross-platform path — different package, different API
using ZXing.ImageSharp;
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.PixelFormats;
var reader = new BarcodeReader<Rgba32>();
using var image = Image.Load<Rgba32>(imagePath);
var result = reader.Decode(image);
// Cross-platform path — different package, different API
using ZXing.ImageSharp;
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.PixelFormats;
var reader = new BarcodeReader<Rgba32>();
using var image = Image.Load<Rgba32>(imagePath);
var result = reader.Decode(image);
Imports ZXing.ImageSharp
Imports SixLabors.ImageSharp
Imports SixLabors.ImageSharp.PixelFormats
Dim reader As New BarcodeReader(Of Rgba32)()
Using image As Image(Of Rgba32) = Image.Load(Of Rgba32)(imagePath)
Dim result = reader.Decode(image)
End Using
Usar la vinculación de Windows en un host Linux también requiere libgdiplus en la imagen de Docker, añadiendo aproximadamente 50 MB al contenedor.
Enfoque IronBarcode
IronBarcode envía un único paquete para todas las plataformas. La misma llamada BarcodeReader.Read(path) se compila y corre de forma idéntica en Windows, Linux, macOSy dentro de contenedores Docker. No se requieren paquetes de enlace, ni condicionales de plataforma, ni dependencias de sistema adicionales. Para los equipos que utilizan contenedores para aplicaciones .NET , la guía de configuración de Docker y Linux de IronBarcode cubre en detalle el patrón de implementación de paquete único.
API de generación
Ambas bibliotecas generan códigos de barras, pero sus API reflejan enfoques de diseño diferentes.
Enfoque ZXing .NET
La clase BarcodeWriter de ZXing.Net crea un objeto escritor, acepta opciones de codificación, llama a Write, y retorna un Bitmap que los llamadores deben guardar manualmente usando System.Drawing.Imaging:
// ZXing.Net: create writer, set options, call Write, save Bitmap
using ZXing;
using ZXing.Common;
using ZXing.Windows.Compatibility;
using System.Drawing.Imaging;
var writer = new BarcodeWriter
{
Format = BarcodeFormat.CODE_128,
Options = new EncodingOptions
{
Width = 300,
Height = 100,
Margin = 10
}
};
using var bitmap = writer.Write("PRODUCT-001");
bitmap.Save("output.png", ImageFormat.Png);
// ZXing.Net: create writer, set options, call Write, save Bitmap
using ZXing;
using ZXing.Common;
using ZXing.Windows.Compatibility;
using System.Drawing.Imaging;
var writer = new BarcodeWriter
{
Format = BarcodeFormat.CODE_128,
Options = new EncodingOptions
{
Width = 300,
Height = 100,
Margin = 10
}
};
using var bitmap = writer.Write("PRODUCT-001");
bitmap.Save("output.png", ImageFormat.Png);
Imports ZXing
Imports ZXing.Common
Imports ZXing.Windows.Compatibility
Imports System.Drawing.Imaging
Dim writer As New BarcodeWriter With {
.Format = BarcodeFormat.CODE_128,
.Options = New EncodingOptions With {
.Width = 300,
.Height = 100,
.Margin = 10
}
}
Using bitmap = writer.Write("PRODUCT-001")
bitmap.Save("output.png", ImageFormat.Png)
End Using
Guardar en formatos distintos a PNG o JPEG, guardar en un PDF o producir salida binaria para una respuesta HTTP requieren una plomería adicional de System.Drawing que el llamador implementa.
Enfoque IronBarcode
El BarcodeWriter.CreateBarcode de IronBarcode devuelve un objeto GeneratedBarcode que proporciona métodos de salida integrados a través de una cadena fluida:
// IronBarcode: create and save in one fluent chain
BarcodeWriter.CreateBarcode("PRODUCT-001", BarcodeEncoding.Code128)
.ResizeTo(300, 100)
.SaveAsPng("output.png");
// IronBarcode: create and save in one fluent chain
BarcodeWriter.CreateBarcode("PRODUCT-001", BarcodeEncoding.Code128)
.ResizeTo(300, 100)
.SaveAsPng("output.png");
Imports IronBarCode
' IronBarcode: create and save in one fluent chain
BarcodeWriter.CreateBarcode("PRODUCT-001", BarcodeEncoding.Code128) _
.ResizeTo(300, 100) _
.SaveAsPng("output.png")
El objeto GeneratedBarcode también expone .ToPngBinaryData(), .ToJpegBinaryData(), .ToStream(), y .SaveAsPdf() — objetivos de salida que ZXing.Net requiere que los llamadores implementen ellos mismos usando System.Drawing.
Referencia de mapeo de API
| ZXing.Net | IronBarcode | Notas |
|---|---|---|
new BarcodeReader() |
Estático: ninguna instancia | BarcodeReader.Read(...) es una llamada estática |
lector.Opciones.FormatosPosibles = nueva lista<BarcodeFormat> { ... } |
No es necesario | La detección automática cubre todos los formatos. |
reader.Options.TryHarder = true |
Speed = ReadingSpeed.Balanced |
Ajuste de precisión vía BarcodeReaderOptions |
reader.Decode(bitmap) |
BarcodeReader.Read(imagePath) |
Pase ruta directamente — no se necesita Bitmap |
reader.DecodeMultiple(bitmap) |
BarcodeReader.Read(imagePath) |
Siempre devuelve una colección |
result.Text |
result.Value |
Propiedad renombrada |
result.BarcodeFormat |
result.Format |
Propiedad renombrada |
BarcodeFormat.QR_CODE |
BarcodeEncoding.QRCode |
Cambio en la convención de nomenclatura de enumeraciones |
BarcodeFormat.CODE_128 |
BarcodeEncoding.Code128 |
Cambio en la convención de nomenclatura de enumeraciones |
BarcodeFormat.EAN_13 |
BarcodeEncoding.EAN13 |
Cambio en la convención de nomenclatura de enumeraciones |
new BarcodeWriter { Format = BarcodeFormat.CODE_128, Options = new EncodingOptions { ... } }|BarcodeWriter.CreateBarcode(data, BarcodeEncoding.Code128)` |
Método de fábrica estática | |
writer.Write(data) devuelve Bitmap |
.SaveAsPng(path) / .ToPngBinaryData() |
Métodos de salida integrados en GeneratedBarcode |
| No admite archivos PDF; requiere PdfiumViewer. | BarcodeReader.Read("doc.pdf") |
Compatibilidad nativa con PDF |
| No es seguro para subprocesos | API estática segura para subprocesos | No se necesita administración de instancias |
Cuando los equipos consideran pasar de ZXing .NET a IronBarcode
Diversos escenarios llevan a los equipos de desarrollo a evaluar IronBarcode como una alternativa a ZXing .NET.
Procesamiento concurrente y de alto rendimiento
Una integración de ZXing .NET que funciona correctamente en una aplicación de consola de un solo hilo puede presentar un comportamiento no determinista cuando el mismo código se traslada a un controlador ASP.NET Core que gestiona solicitudes concurrentes, o a un trabajo en segundo plano que procesa lotes en paralelo. El patrón de instancia por hilo que requiere ZXing .NET implica que cada solicitud o tarea paralela asigna un objeto lector completo con su conjunto de decodificadores configurado, lo usa una vez y lo descarta. A medida que aumenta el volumen de solicitudes, esta presión de asignación se vuelve cuantificable. Los equipos que llegan a este punto, en particular aquellos que gestionan sistemas de escaneo de alto rendimiento en logística, almacenamiento o procesamiento de documentos, suelen buscar una biblioteca cuyo modelo de subprocesos no imponga esta sobrecarga a cada usuario.
Escaneo de documentos de formato mixto
Las aplicaciones que aceptan documentos de terceros suelen encontrarse con formatos de código de barras que no se previeron al configurar la lista de formatos. Una integración de envíos creada para Code 128 recibe un envío de un socio mediante códigos QR. Un sistema de registros médicos configurado para encuentros PDF 417 con simbologías Data Matrix de un nuevo proveedor de equipos. En ZXing .NET, cada uno de estos casos produce un valor nulo silencioso en lugar de un error de decodificación, lo que significa que el fallo puede no manifestarse hasta que falle el procesamiento posterior. Los equipos que han sufrido las consecuencias de errores de formato silenciosos, especialmente en contextos donde un código de barras omitido tiene repercusiones comerciales, comienzan a sopesar el coste del mantenimiento de la lista de formatos frente a una biblioteca que detecta los formatos automáticamente.
Extracción de códigos de barras PDF
Muchos documentos comerciales llegan en formato PDF: facturas, manifiestos de envío, historiales de pacientes, certificados de cumplimiento. ZXing .NET no puede leerlos directamente. Los equipos que necesitan extraer códigos de barras de archivos PDF terminan creando y manteniendo una canalización de renderizado sobre ZXing .NET : seleccionando una biblioteca de PDF, gestionando sus dependencias nativas, implementando un bucle de renderizado de página, manejando la configuración de DPI y escribiendo lógica de limpieza para archivos temporales. Ese código de infraestructura no es lógica de código de barras; Su única función es salvar la brecha entre lo que ZXing .NET acepta (mapas de bits) y lo que realmente son los documentos comerciales (PDF). Los equipos que se ven obligados a mantener este puente, especialmente cuando la propia biblioteca de PDF tiene sus propias consideraciones sobre licencias, implementación y plataforma, suelen preferir una única biblioteca que gestione toda la superficie de entrada.
Reducción de la complejidad de la unión
Los proyectos que se inician en Windows y posteriormente se implementan en Linux o Docker se topan directamente con la fragmentación de enlaces de ZXing.Net: el paquete de enlace de Windows utiliza una API diferente a la del enlace multiplataforma ImageSharp, y cambiar entre ellos requiere modificar tanto las referencias de NuGet como el código de carga de imágenes. Los equipos que, por práctica habitual, utilizan contenedores para sus aplicaciones .NET , o que ejecutan el mismo código fuente en máquinas de desarrollo (Windows o macOS) y servidores de producción (Linux), descubren que mantener dos rutas de código para la carga de imágenes añade fricción a cada cambio futuro en la capa de escaneo.
Consideraciones comunes sobre la migración
Los equipos que estén migrando de ZXing .NET a IronBarcode deben planificar estos cambios técnicos específicos.
Eliminación de instancias de lector de códigos de barras
Cada llamada new BarcodeReader() en la base de código se elimina durante la migración. El patrón de instanciación —creación del lector, configuración del formato, carga de la imagen, llamada de decodificación— se reduce a una única llamada a un método estático. Los archivos que importan los espacios de nombres de ZXing, ZXing.Common, ZXing.Windows.Compatibility, ZXing.ImageSharp, y SixLabors.ImageSharp tienen esas importaciones eliminadas y reemplazadas por un solo using IronBarCode;.
Eliminación de la configuración de PossibleFormats
El bloque de asignación reader.Options.PossibleFormats se elimina en cada sitio de llamada. IronBarcode realiza detección automática de formatos y no acepta una lista de restricción de formatos. La bandera TryHarder es reemplazada por la propiedad ReadingSpeed en BarcodeReaderOptions, que controla el esfuerzo de detección sin reducir el alcance del formato.
Limpieza del paquete de encuadernación
La migración elimina ZXing.Net, ZXing.Net.Bindings.Windows.Compatibility, cualquier variante ZXing.Net.Bindings.ImageSharp (.V2 / .V3), y cualquier paquete PdfiumViewer que se haya añadido para soportar la lectura de PDF. Si libgdiplus fue añadido a un Dockerfile para soportar System.Drawing a través de la vinculación de Windows en Linux, esa línea también es eliminada. IronBarcode no requiere dependencias específicas de la plataforma en la imagen de Docker.
Funcionalidades adicionales de IronBarcode
Además de las funcionalidades descritas en las secciones comparativas anteriores, IronBarcode ofrece:
- Código QR con logotipo incrustado : Genera códigos QR con una imagen de logotipo personalizada superpuesta en el centro, con corrección automática de errores para garantizar su escaneo.
- Personalización del color del código QR : Configure los colores de primer plano y de fondo en los códigos QR generados para lograr una presentación acorde con la marca.
- Impresión de códigos de barras en archivos PDF : Permite escribir códigos de barras directamente en páginas PDF existentes en coordenadas específicas sin necesidad de una biblioteca PDF independiente.
- Compatibilidad con códigos de barras GS1 : Permite leer y generar códigos de barras con formato GS1, incluidos GS1-128 y GS1 DataBar, utilizados en las cadenas de suministro del sector minorista y sanitario.
- Lectura Asíncrona Multihilo: Métodos asíncronos integrados para integrar la lectura de códigos de barras en pipelines
awaitsin bloquear. - Corrección de Imágenes Potenciada por ML: Mejora automática de imágenes para códigos de barras dañados, borrosos o de bajo contraste que
TryHarderno puede recuperar.
Compatibilidad con .NET y preparación para el futuro
IronBarcode apunta a .NET Standard 2.0 y superiores, ofreciendo compatibilidad con .NET Framework 4.6.2+, .NET Core 3.1, .NET 5, .NET 6, .NET 7, .NET 8, y .NET 9. La biblioteca recibe actualizaciones regulares alineadas con el ciclo de lanzamiento de .NET de Microsoft, asegurando que la compatibilidad con .NET 10 estará disponible en o cerca del lanzamiento. ZXing .NET también mantiene una amplia compatibilidad con .NET a través de sus destinos de paquetes NuGet , y ambas bibliotecas son adecuadas para proyectos .NET modernos desde esta perspectiva.
Conclusión
ZXing .NET e IronBarcode representan filosofías diferentes en el diseño de bibliotecas de códigos de barras. ZXing .NET es una biblioteca con estado, basada en instancias, que delega la responsabilidad de la gestión de subprocesos, la especificación del formato y la conversión a PDF completamente al usuario. IronBarcode es una biblioteca sin estado y con API estática que internaliza el manejo de hilos, detecta formatos automáticamente y gestiona la entrada de archivos PDF de forma nativa. La consecuencia práctica de esta diferencia es que la codificación ZX del código .NET en contextos concurrentes o de procesamiento de documentos tiende a acumular infraestructura (patrones de instancias por hilo, listas de formatos, canalizaciones de renderizado de PDF y ramas de enlace específicas de la plataforma), mientras que el código IronBarcode para los mismos escenarios no requiere ninguna de esas estructuras circundantes.
ZXing .NET es una opción realmente sólida para proyectos con requisitos de coste cero. Su licencia Apache 2.0la hace compatible con proyectos de código abierto y con productos comerciales que prefieren dependencias libres. En entornos controlados —formatos de código de barras conocidos, imágenes nítidas, procesamiento de un solo hilo o concurrente ligero— su rendimiento es fiable. Su activa comunidad en GitHub proporciona respuestas oportunas a los problemas, y la amplitud de su cobertura de formatos es comparable a la de las alternativas comerciales. Para las aplicaciones en las que se cumplen esas condiciones, la ventaja de costes de ZXing.Net es real y sus limitaciones técnicas son manejables.
IronBarcode aborda los escenarios en los que las limitaciones de diseño de ZXing.Net se convierten en costes operativos: API web concurrentes donde la asignación de instancias por solicitud es medible, flujos de documentos donde la entrada de PDF es la norma en lugar de la excepción, escaneo de formatos mixtos donde los fallos silenciosos conllevan riesgos para el negocio y despliegues multiplataforma donde dos paquetes de enlace significan dos rutas de código. Para esos contextos, la licencia comercial de la biblioteca proporciona un modelo de subprocesos que no impone la gestión de instancias, una detección de formato que no requiere mantenimiento y compatibilidad con PDF que no requiere una segunda biblioteca.
La decisión depende de los requisitos del proyecto. Un prototipo de formato único, un escáner de código abierto o una herramienta de bajo volumen donde el costo es la principal limitación: en estos casos, ZXing .NET es la opción adecuada. Una API web de producción que procesa documentos de fuentes externas en múltiples hilos: ahí es donde las premisas de diseño de IronBarcode se alinean con la realidad operativa. Para obtener una visión más amplia de cómo se comparan las bibliotecas en cuanto a tasas de detección y escenarios de escaneo del mundo real, la comparación de escáneres de códigos de barras ZXing .NET vs IronBarcode proporciona un análisis adicional.
Preguntas Frecuentes
¿Qué es ZXing.Net?
ZXing.Net es una biblioteca de códigos de barras .NET para generar y leer códigos de barras en aplicaciones C#. Es una de las varias alternativas que los desarrolladores evalúan cuando seleccionan una solución de código de barras para proyectos .NET.
¿Cuáles son las principales diferencias entre ZXing.Net e IronBarcode?
IronBarcode utiliza una API estática y sin estado que no requiere gestión de instancias, mientras que ZXing.Net suele requerir la creación y configuración de instancias antes de su uso. IronBarcode también ofrece compatibilidad nativa con PDF, detección automática de formatos y licencia de clave única en todos los entornos.
¿Es IronBarcode más fácil de licenciar que ZXing.Net?
IronBarcode utiliza una única clave de licencia que cubre tanto el desarrollo como los despliegues de producción. Esto simplifica las canalizaciones de CI/CD y las configuraciones de Docker en comparación con los sistemas de licencias que separan las claves de SDK de las claves de tiempo de ejecución.
¿Es IronBarcode compatible con todos los formatos de código de barras que admite ZXing.Net?
IronBarcode es compatible con más de 30 simbologías de códigos de barras, incluidos QR Code, Code 128, Code 39, DataMatrix, PDF417, Aztec, EAN-13, UPC-A, GS1 y muchos más. La autodetección de formatos significa que no se requiere una enumeración explícita de formatos.
¿Es IronBarcode compatible con la lectura nativa de códigos de barras en PDF?
Sí. IronBarcode lee códigos de barras directamente desde archivos PDF utilizando BarcodeReader.Read("document.pdf") sin necesidad de una biblioteca de renderizado de PDF independiente. Los resultados por página incluyen el número de página, el formato del código de barras, el valor y la puntuación de confianza.
¿Cómo gestiona IronBarcode el procesamiento por lotes en comparación con ZXing.Net?
Los métodos estáticos de IronBarcode no tienen estado y son naturalmente seguros para subprocesos, lo que permite el uso directo de Parallel.ForEach sin gestión de instancias por subproceso. No hay límite de rendimiento en ningún nivel de precios.
¿Qué versiones de .NET admite IronBarcode ?
IronBarcode es compatible con .NET Framework 4.6.2+, .NET Core 3.1 y .NET 5, 6, 7, 8 y 9 en un único paquete NuGet. Las plataformas de destino incluyen Windows x64/x86, Linux x64 y macOS x64/ARM.
¿Cómo instalo IronBarcode en un proyecto .NET?
Instale IronBarcode a través de NuGet: ejecute 'Install-Package IronBarCode' en la consola del gestor de paquetes, o 'dotnet add package IronBarCode' en la CLI. No se necesitan instaladores SDK ni archivos de ejecución adicionales.
¿Puedo evaluar IronBarcode antes de comprarlo, a diferencia de ZXing.Net?
Sí. El modo de prueba de IronBarcode devuelve los valores completos de los códigos de barras descodificados; sólo las imágenes de salida generadas reciben una marca de agua. Puede comprobar la precisión de la lectura en sus propios documentos antes de comprometerse con la compra.
¿Cuál es la diferencia de precio entre ZXing.Net e IronBarcode?
IronBarcode cuesta a partir de 749 dólares por una licencia perpetua de desarrollador único que cubre el desarrollo y la producción. Los detalles de precios y opciones de volumen están disponibles en la página de licencias de IronBarcode. No se requiere una licencia de ejecución por separado.
¿Es fácil migrar de ZXing.Net a IronBarcode?
La migración de ZXing.Net a IronBarcode implica principalmente la sustitución de las llamadas a la API basadas en instancias por los métodos estáticos de IronBarcode, la eliminación de la repetición de licencias y la actualización de los nombres de las propiedades de los resultados. La mayoría de las migraciones implican reducir código en lugar de añadirlo.
¿IronBarcode genera códigos QR con logotipos?
Sí. QRCodeWriter.CreateQrCode().AddBrandLogo("logo.png") incrusta una imagen de marca en un código QR de forma nativa con corrección de errores configurable. Los códigos QR coloreados también son compatibles con ChangeBarCodeColor().

