Saltar al pie de página
VIDEOS

Cómo Leer y Escanear Códigos de Barras en C# Usando NET MAUI

Migrating from BarcodeLibto IronBarcode

Esta guía proporciona una ruta de migración completa de BarcodeLiba IronBarcode para desarrolladores .NET . Cubre las razones por las que los equipos realizan esta transición, el reemplazo de paquetes paso a paso, ejemplos de migración de código para cada patrón común de BarcodeLib, una referencia completa de mapeo de API y una lista de verificación estructurada para administrar la migración en toda la base de código.

¿Por qué migrar desde BarcodeLib?

Los equipos que migran de BarcodeLiba IronBarcode informan de los siguientes factores desencadenantes:

Sin API de lectura: BarcodeLibnunca ha incluido una capacidad de lectura o decodificación. Cuando un proyecto que generaba imágenes de códigos de barras recibe un nuevo requisito para escanear también códigos de barras (ya sea a partir de imágenes cargadas, escáneres de almacén o documentos de proveedores), BarcodeLibno puede satisfacerlo. La única opción es añadir una segunda biblioteca, como ZXing .NET, lo que introduce un segundo gráfico de dependencias y una segunda interfaz API que mantener junto con BarcodeLib.

Conflicto de versión de SkiaSharp: BarcodeLib3.x introdujo SkiaSharp como backend de gráficos para reemplazar System.Drawing.Common. La biblioteca está vinculada a un rango de versiones específico de SkiaSharp. En los proyectos MAUI, los proyectos Blazor y cualquier proyecto en el que otra dependencia también incluya SkiaSharp, la versión resuelta suele quedar fuera del rango esperado por BarcodeLib. Esto produce advertencias NU1608 durante la restauración y, en el peor de los casos, fallos de enlace de ensamblados en tiempo de ejecución en el dispositivo.

Sin compatibilidad con PDF: Las aplicaciones que generan documentos PDF con códigos de barras incrustados (facturas, órdenes de trabajo, manifiestos de envío) a veces necesitan leer esos códigos de barras durante el procesamiento posterior. BarcodeLibgenera imágenes de códigos de barras, pero no tiene soporte para PDF en ninguno de los extremos. Para extraer códigos de barras de un PDF con BarcodeLib, es necesario convertir las páginas del PDF en imágenes con una biblioteca de PDF independiente y, a continuación, pasar esas imágenes a una biblioteca de lectura independiente.

Paso de codificación de flujo para salida de matriz de bytes: BarcodeLib3.x devuelve SKImage, lo que requiere un paso de codificación de SkiaSharp en un MemoryStream para producir la salida de byte[] que las respuestas HTTP, las columnas de BLOB de bases de datos y la mayoría de los consumidores posteriores realmente necesitan. IronBarcode ofrece .ToPngBinaryData() directamente en la cadena de generación.

El problema fundamental

La arquitectura de BarcodeLib, que solo permite la generación de código fuente, implica que añadir cualquier capacidad de escaneo obliga a incorporar una segunda biblioteca:

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

IronBarcode maneja ambos en el mismo paquete con la misma declaración de 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"
$vbLabelText   $csharpLabel

IronBarcode vs BarcodeLib: Comparación de características

Característica BarcodeLib IronBarcode
Generación de códigos de barras
Lectura/escaneo de códigos de barras No Sí (BarcodeReader.Read())
Generación de código QR No (solo 1D) Sí (avanzado, con inserción de logotipo)
Lectura de códigos de barras PDF No Sí (nativo, sin biblioteca adicional)
Salida de generación de código de barras PDF No
Dependencia de SkiaSharp Sí (riesgo de conflicto de versiones) No
Compatibilidad con proyectos MAUI Riesgo de conflicto (NU1608) No hay conflicto
API fluida y encadenable No
byte[] salida directamente Manual (vía MemoryStream) .ToPngBinaryData()
Detección de múltiples códigos de barras No Sí (ExpectMultipleBarcodes)
Ajuste de velocidad de lectura N/A Sí (ReadingSpeed enum)
Compatibilidad con Linux/macOS Parcial (dependiente de SkiaSharp) Completo
Compatibilidad con Docker/contenedores Se requiere configuración
Mantenimiento activo Sí (comunidad) Sí (comercial)
Soporte comercial / SLA No
Licencia Apache 2.0 (gratuito) $999–$5,999 perpetuo

Inicio rápido: Migración de BarcodeLiba IronBarcode

La migración puede comenzar inmediatamente con estos pasos básicos.

Paso 1: Sustituir el paquete NuGet

Eliminar primero el paquete de BarcodeLib:

dotnet remove package BarcodeLib
dotnet remove package BarcodeLib
SHELL

Si no está seguro de cómo se hace referencia, verifique el archivo .csproj:

grep -n "BarcodeLib" YourProject.csproj
grep -n "BarcodeLib" YourProject.csproj
SHELL

Elimine todas las entradas de <PackageReference> relacionadas con BarcodeLib. Si agregó anulaciones explícitas de <PackageReference Include="SkiaSharp"> para solucionar las advertencias NU1608 de BarcodeLib, elimínelas también. Después de instalar IronBarcode, evalúe si SkiaSharp todavía se necesita por otras razones. Luego instala IronBarcode:

dotnet add package IronBarcode
dotnet add package IronBarcode
SHELL

Paso 2: Actualizar los espacios de nombres

Reemplace las directivas using de BarcodeLiben cada archivo que las refiera:

// Before
using BarcodeStandard;
using SkiaSharp;

// After
using IronBarCode;
// Before
using BarcodeStandard;
using SkiaSharp;

// After
using IronBarCode;
Imports IronBarCode
Imports SkiaSharp
$vbLabelText   $csharpLabel

Paso 3: Inicializar licencia

Añadir inicialización de licencia al inicio de la aplicación:

IronBarCode.License.LicenseKey = "YOUR-LICENSE-KEY";
IronBarCode.License.LicenseKey = "YOUR-LICENSE-KEY";
Imports IronBarCode

IronBarCode.License.LicenseKey = "YOUR-LICENSE-KEY"
$vbLabelText   $csharpLabel

Para aplicaciones ASP.NET Core, coloque esto en Program.cs antes de builder.Build(). Para aplicaciones de consola, colóquelo en la parte superior de Main(). Para las bibliotecas de clases a las que se llama desde otras aplicaciones, inicialícelas dondequiera que se inicie la aplicación anfitriona.

Ejemplos de migración de código

Generación de código básico128

El patrón más común de BarcodeLib: crear una instancia, establecer propiedades, llamar a Encode().

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

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

El bloque de configuración de propiedades se transforma en una cadena fluida. .AddAnnotationTextBelowBarcode() reemplaza a b.IncludeLabel = true — acepta la cadena de etiqueta explícitamente para que controle qué texto aparece debajo de las barras. .ResizeTo() reemplaza los argumentos de ancho/altura. Para opciones de generación avanzadas, consulte la documentación de generación de códigos de barras de IronBarcode .

Devolver byte[] — el patrón común de API web

BarcodeLib 3.x devuelve un SKImage. Obtener bytes de él requiere codificación a través de SkiaSharp en un MemoryStream. IronBarcode ofrece .ToPngBinaryData() directamente.

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

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

El paso intermedio de MemoryStream se ha eliminado. .ToPngBinaryData() devuelve el byte[] directamente, que es lo que los cuerpos de respuestas HTTP, las columnas BLOB de bases de datos y los escritores de archivos realmente quieren.

Acción del controlador de la API web

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

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

La acción del controlador se reduce eliminando el bloque MemoryStream y el paso de codificación SkiaSharp. La matriz de bytes fluye directamente de .ToPngBinaryData() a File().

Generación de códigos QR

BarcodeLib 3.x no genera códigos QR; el enum BarcodeStandard.Type no contiene entradas 2D. Los proyectos que necesitaban QR junto a BarcodeLibtípicamente agregaban una segunda biblioteca como QRCoder. IronBarcode utiliza una clase QRCodeWriter dedicada con opciones adicionales para la incrustación de logotipos y estilo.

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

Enfoque de 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")
$vbLabelText   $csharpLabel

QRCodeWriter.CreateQrCode() toma la cadena de datos y el tamaño de píxel como parámetros. La incrustación del logotipo, la personalización del color y el nivel de corrección de errores están disponibles mediante métodos encadenados. Para conocer las opciones de estilo del código QR, consulte la documentación de códigos QR de IronBarcode .

EAN-13 y UPC-A

Son habituales en los sistemas de inventario de las tiendas minoristas. Los nombres de las enumeraciones cambian, pero los valores son equivalentes directos.

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

Enfoque de 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")
$vbLabelText   $csharpLabel

Incorporación de la lectura de códigos de barras (nueva funcionalidad)

BarcodeLib no tiene una API de lectura. Si su migración se debe a un nuevo requisito para escanear códigos de barras (desde imágenes cargadas, escáneres de almacén o documentos PDF escaneados), agregue esto sin una segunda biblioteca:

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

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

BarcodeReader.Read() acepta archivos de imagen, archivos PDF, flujos y objetos System.Drawing.Bitmap. El enum ReadingSpeed le permite intercambiar exhaustividad por rendimiento al escanear en volumen. Para leer las opciones de configuración, consulte la documentación de lectura de IronBarcode .

Resolución del conflicto de SkiaSharp

Si la migración se debe a las advertencias de NU1608, verifique que el conflicto se haya resuelto después de cambiar de paquete. Después de ejecutar dotnet remove package BarcodeLib y dotnet add package IronBarcode, reconstruya y verifique la salida:

dotnet build 2>&1 | grep -i &quot;NU1608\|SkiaSharp"
dotnet build 2>&1 | grep -i &quot;NU1608\|SkiaSharp"
SHELL

Si no aparece ninguna salida, el conflicto se ha resuelto. Si las advertencias de SkiaSharp persisten, provienen de un paquete diferente en su gráfico de dependencias; IronBarcode no es la fuente.

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

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

Referencia de mapeo de la API de BarcodeLiba IronBarcode

BarcodeLib IronBarcode
new Barcode() API estática: no se requiere instancia.
b.Encode(Type.Code128, "data", w, h) BarcodeWriter.CreateBarcode("data", BarcodeEncoding.Code128)
b.IncludeLabel = true .AddAnnotationTextBelowBarcode("text")
Ancho/altura pasada a Encode() .ResizeTo(width, height)
Devuelve SKImage .SaveAsPng(path) / .ToPngBinaryData()
Type.Code128 BarcodeEncoding.Code128
Type.Code39 BarcodeEncoding.Code39
Type.Ean13 BarcodeEncoding.EAN13
Type.UpcA BarcodeEncoding.UPCA
No hay soporte para QR (solo 1D) BarcodeEncoding.QRCode (también QRCodeWriter)
Type.Itf14 BarcodeEncoding.ITF14
Type.Codabar BarcodeEncoding.Codabar
No se puede leer la API BarcodeReader.Read(path)
Conflicto de versiones de SkiaSharp en MAUI Sin dependencias conflictivas
img.Encode(...).SaveTo(stream) .SaveAsPng(path)
MemoryStream + codificación SkiaSharp .ToPngBinaryData()

Problemas comunes de migración y soluciones

Problema 1: Cambio de Namespace de Enum de Tipo

BarcodeLib 3.x: Usa BarcodeStandard.Type.Code128 (PascalCase, en el espacio de nombres BarcodeStandard). El código de la versión 2.x más antiguo puede usar BarcodeLib.TYPE.CODE128 (constantes en mayúsculas, espacio de nombres BarcodeLib) — ambas formas aparecen en bases de código reales durante la migración.

Solución: Reemplace con BarcodeEncoding.Code128. Un grep a través de los archivos .cs identifica todas las ocurrencias:

grep -rn "Type\.\|TYPE\." --include="*.cs" .
grep -rn "Type\.\|TYPE\." --include="*.cs" .
SHELL

Reemplazos comunes: Type.Code128 / TYPE.CODE128BarcodeEncoding.Code128, Type.Ean13 / TYPE.EAN13BarcodeEncoding.EAN13, Type.UpcA / TYPE.UPCABarcodeEncoding.UPCA, Type.Itf14 / TYPE.ITF14BarcodeEncoding.ITF14, Type.Codabar / TYPE.CO/DABARBarcodeEncoding.Codabar. BarcodeLibno tiene entrada para QR; cualquier TYPE.QR_Code es código muerto de una versión 2.x o un fork — reemplácelo con BarcodeEncoding.QRCode (o use QRCodeWriter para salida estilizada).

Problema 2: Tipo de Retorno SKImage / Image

BarcodeLib: b.Encode() devuelve SKImage en 3.x y System.Drawing.Image en 2.x. Cualquiera de los dos tipos no compilará contra IronBarcode.

Solución: Elimine la variable de imagen intermedia y reemplace la lógica de guardado con el método terminal adecuado en la cadena fluida:

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

Busque los patrones SKImage img = b.Encode y Image img = b.Encode para encontrar todas las ubicaciones afectadas.

Problema 3: Parámetros de Ancho y Alto

BarcodeLib: El ancho y la altura son argumentos posicionales en Encode(Type, string, int, int) en 3.x, y asignaciones de propiedades separadas b.Width / b.Height en el código 2.x más antiguo. Cualquiera de las formas necesita ser portada.

Solución: El ancho/altura se convierten en una sola llamada .ResizeTo(width, height) encadenada después de CreateBarcode(). Encuentre los sitios de llamada:

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

Luego reemplace los argumentos de tamaño o el par de propiedades con una sola llamada encadenada .ResizeTo(width, height).

Problema 4: Incluir etiqueta booleana (alternar)

BarcodeLib: b.IncludeLabel = true es un booleano que automáticamente representa la cadena de datos codificada como el texto visible debajo de las barras.

Solución: Use .AddAnnotationTextBelowBarcode("text"), que toma la cadena de etiqueta explícitamente. En la mayoría de los casos, utilice la misma cadena de datos que se codificó en el código de barras. Si el código original usaba IncludeLabel = true y dependía de BarcodeLibpara representar automáticamente los datos como la etiqueta, pase explícitamente esa misma cadena de datos:

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

Problema 5: Referencias a SkiaSharp que quedan tras la eliminación de BarcodeLib

BarcodeLib: Los proyectos frecuentemente acumulaban entradas explícitas de <PackageReference Include="SkiaSharp"> específicamente para anular la restricción de versión de BarcodeLib. Estos elementos quedan huérfanos después de que se elimina BarcodeLib.

Solución: Después de cambiar a IronBarcode, verifique si SkiaSharp todavía es necesario para algún otro paquete antes de eliminar la referencia explícita:

# 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
SHELL

Si SkiaSharp solo aparece debido a la ahora eliminada <PackageReference> explícita, elimine esa entrada. Si MAUI u otra dependencia aún lo requiere, déjelo; IronBarcode no entrará en conflicto con él.

Lista de verificación de migración de BarcodeLib

Tareas previas a la migración

Realice estas búsquedas antes de comenzar a comprender el alcance de los cambios necesarios:

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

Documente todos los archivos afectados por cada búsqueda. Observe qué proyectos hacen referencia a BarcodeLibdirectamente y cuáles lo heredan de forma transitiva. Identifique cualquier modificación explícita de la versión de SkiaSharp que se haya agregado únicamente para resolver conflictos de BarcodeLib.

Tareas de actualización de código

  1. Ejecute dotnet remove package BarcodeLib para cada proyecto
  2. Elimine cualquier referencia explícita a la anulación de la versión de SkiaSharp que se haya agregado únicamente para solucionar conflictos con BarcodeLib.
  3. Ejecute dotnet add package IronBarcode para cada proyecto
  4. Agregue IronBarCode.License.LicenseKey = "YOUR-LICENSE-KEY"; al inicio de la aplicación en cada proyecto
  5. Reemplace using BarcodeStandard; (o using BarcodeLib; en el código más antiguo) y using SkiaSharp; con using IronBarCode; en todos los archivos .cs
  6. Elimine las importaciones de using System.Drawing.Imaging; sobrantes del uso ImageFormat.Png de 2.x
  7. Reemplace las llamadas new Barcode() + Encode() con cadenas fluidas BarcodeWriter.CreateBarcode()
  8. Reemplace Type.Code128 / TYPE.CODE128BarcodeEncoding.Code128 y todos los demás valores del enum
  9. Reemplace los argumentos de ancho/alto (o b.Width = N; de 2.x b.Height = M;) with .ResizeTo(N, M) cadenas de llamadas
  10. Reemplace b.IncludeLabel = true; con .AddAnnotationTextBelowBarcode(data)
  11. Reemplace img.Encode(SKEncodedImageFormat.Png, 100).SaveTo(...) con .SaveAsPng(path) o .ToPngBinaryData()
  12. Elimine variables intermedias SKImage / Image y bloques MemoryStream donde .ToPngBinaryData() los reemplace
  13. Agregue código de lectura de códigos de barras donde sea necesario (BarcodeReader.Read())

Pruebas posteriores a la migración

  • Compile el proyecto y confirme que no quedan advertencias NU1608 en la salida de restauración.
  • Ejecutar dotnet build 2&gt;&amp;1 | grep -i "NU1608|SkiaSharp"` para verificar que el conflicto de SkiaSharp esté completamente resuelto.
  • Compare la salida visual de los códigos de barras generados con muestras válidas conocidas de BarcodeLib.
  • Verifique que los códigos QR se decodifiquen correctamente usando un escáner móvil o el método BarcodeReader.Read()
  • Pruebe los códigos de barras EAN-13 y UPC-A con el hardware del escáner de la tienda, si corresponde.
  • Verificar que las imágenes se muestren correctamente en todos los destinos de salida: sistema de archivos, respuesta HTTP, almacenamiento de base de datos.
  • Pruebe cualquier escenario de lectura de códigos de barras PDF usando BarcodeReader.Read("file.pdf") en documentos reales
  • Confirma que las compilaciones multiplataforma se realicen correctamente si el proyecto está dirigido a Linux o macOS.
  • Verificar que las compilaciones de MAUI se completen sin errores de enlace de SkiaSharp en dispositivos Android e iOS.

Principales ventajas de migrar a IronBarcode

Lectura de códigos de barras sin una segunda biblioteca: La ventaja más inmediata para los equipos que necesitaban capacidad de lectura es la eliminación de la dependencia de una segunda biblioteca. BarcodeReader.Read() está en el mismo paquete, usa la misma declaración de using IronBarCode; y no requiere instalaciones adicionales de NuGet. ZXing .NET y su propio gráfico de dependencias ya no forman parte del proyecto.

Sin conflicto de versiones de SkiaSharp: IronBarcode no comparte el gráfico de dependencias de SkiaSharp con el código de la aplicación. Los proyectos MAUI, los proyectos Blazor y cualquier proyecto en el que varios paquetes converjan en SkiaSharp pueden instalar IronBarcode sin advertencias NU1608 ni fallos de enlace en tiempo de ejecución. La negociación de versiones que introdujo BarcodeLibha desaparecido.

Salida de matriz de bytes directa: .ToPngBinaryData() devuelve byte[] al final de la cadena fluida. El intermediario MemoryStream que BarcodeLibrequería para la salida de matriz de bytes se elimina de cada acción del controlador, método de servicio y manejador de API que genera códigos de barras.

Procesamiento de código de barras PDF: BarcodeReader.Read() acepta archivos PDF de forma nativa. Las aplicaciones que generan documentos PDF con códigos de barras incrustados pueden leer esos códigos de barras sin necesidad de una biblioteca de renderizado de PDF independiente. Todo el proceso —generación, incrustación en PDF y lectura— se gestiona dentro de IronBarcode.

Soporte Comercial y SLA: IronBarcode cuenta con el respaldo del modelo de soporte comercial de Iron Software con una cadencia de actualizaciones definida. Cuando aterrizan nuevas versiones de .NET o aparecen cambios disruptivos en el ecosistema de .NET, IronBarcode publica actualizaciones de compatibilidad en un cronograma atado al SLA comercial en lugar de la disponibilidad de la comunidad.

Generación de códigos QR sin una segunda biblioteca: QRCodeWriter admite incrustación de logotipos, personalización de colores y configuración de nivel de corrección de errores a través de métodos encadenados. BarcodeLib3.x genera solo simbologías 1D — los proyectos que necesitaban QR junto a BarcodeLibanteriormente añadían una segunda biblioteca como QRCoder. Los equipos cuyos requisitos de códigos QR han aumentado obtienen estas características dentro del mismo paquete, sin cambiar su flujo de trabajo de generación.

Preguntas Frecuentes

¿Por qué debería migrar de BarcodeLib a IronBarcode?

Entre las razones más comunes se incluyen la simplificación de licencias (eliminando la complejidad de SDK + clave de tiempo de ejecución), la eliminación de límites de rendimiento, la obtención de compatibilidad nativa con PDF, la mejora de la implementación de Docker/CI/CD y la reducción de la repetición de API en el código de producción.

¿Cómo puedo sustituir las llamadas a la API de BarcodeLib por IronBarcode?

Sustituya la creación de instancias y la repetición de licencias por IronBarCode.License.LicenseKey = "key". Sustituya las llamadas al lector por BarcodeReader.Read(path) y las llamadas al escritor por BarcodeWriter.CreateBarcode(data, encoding). Los métodos estáticos no requieren gestión de instancias.

¿Cuánto código cambia al migrar de BarcodeLib a IronBarcode?

La mayoría de las migraciones se traducen en menos líneas de código. Se eliminan la repetición de licencias, los constructores de instancias y la configuración explícita de formatos. Las operaciones básicas de lectura/escritura se traducen a equivalentes IronBarcode más cortos con objetos de resultado más limpios.

¿Necesito tener instalados tanto BarcodeLib como IronBarcode durante la migración?

No. La mayoría de las migraciones son sustituciones directas en lugar de operaciones paralelas. Migre una clase de servicio cada vez, sustituya la referencia NuGet y actualice los patrones de instanciación y llamada a la API antes de pasar a la siguiente clase.

¿Cuál es el nombre del paquete NuGet para IronBarcode?

El paquete es 'IronBarCode' (con B y C mayúsculas). Instálalo con 'Install-Package IronBarCode' o 'dotnet add package IronBarCode'. La directiva using en el código es 'using IronBarCode;'.

¿Cómo simplifica IronBarcode el despliegue de Docker en comparación con BarcodeLib?

IronBarcode es un paquete NuGet sin archivos SDK externos ni configuración de licencia montada. En Docker, establezca la variable de entorno IRONBARCODE_LICENSE_KEY y el paquete se encargará de la validación de la licencia al inicio.

¿IronBarcode detecta automáticamente todos los formatos de código de barras después de migrar desde BarcodeLib?

Sí, IronBarcode detecta automáticamente la simbología de todos los formatos compatibles. No es necesaria la enumeración explícita de BarcodeTypes. Si ya se conoce el formato y el rendimiento es importante, BarcodeReaderOptions permite restringir el espacio de búsqueda como optimización.

¿Puede IronBarcode leer códigos de barras de PDF sin una biblioteca independiente?

Sí. BarcodeReader.Read("document.pdf") procesa archivos PDF de forma nativa. Los resultados incluyen PageNumber, Format, Value y Confidence para cada código de barras encontrado. No es necesario ningún paso externo de procesamiento de PDF.

¿Cómo gestiona IronBarcode el procesamiento paralelo de códigos de barras?

Los métodos estáticos de IronBarcode no tienen estado y son seguros para los hilos. Utilice Parallel.ForEach directamente sobre listas de archivos sin gestión de instancias por subproceso. BarcodeReaderOptions.MaxParallelThreads controla el presupuesto interno de hilos.

¿Qué propiedades de los resultados cambian al migrar de BarcodeLib a IronBarcode?

Cambios de nombre comunes: BarcodeValue se convierte en Value, BarcodeType se convierte en Format. Los resultados de IronBarcode también añaden Confidence y PageNumber. Una búsqueda y sustitución en toda la solución gestiona los cambios de nombre en el código de procesamiento de resultados existente.

¿Cómo configuro las licencias de IronBarcode en un proceso CI/CD?

Almacene IRONBARCODE_LICENSE_KEY como un secreto de canalización y asigne IronBarCode.License.LicenseKey en el código de inicio de la aplicación. Un secreto cubre todos los entornos, incluidos los de desarrollo, prueba, montaje y producción.

¿Admite IronBarcode la generación de códigos QR con estilos personalizados?

Sí. QRCodeWriter.CreateQrCode() admite colores personalizados mediante ChangeBarCodeColor(), incrustación de logotipos mediante AddBrandLogo(), niveles de corrección de errores configurables y múltiples formatos de salida, incluidos PNG, JPG, PDF y stream.

Curtis Chau
Escritor Técnico

Curtis Chau tiene una licenciatura en Ciencias de la Computación (Carleton University) y se especializa en el desarrollo front-end con experiencia en Node.js, TypeScript, JavaScript y React. Apasionado por crear interfaces de usuario intuitivas y estéticamente agradables, disfruta trabajando con frameworks modernos y creando manuales bien ...

Leer más

Equipo de soporte de Iron

Estamos disponibles online las 24 horas, 5 días a la semana.
Chat
Email
Llámame