Cómo Generar Imágenes de Códigos de Barras en C# for .NET usando IronBarcode
Migrating from Dynamsoft Barcode Reader to IronBarcode
La mayoría de los desarrolladores que migran de Dynamsoft Barcode Reader a IronBarcode caen en uno de dos grupos: aquellos que eligieron Dynamsoft por su reputación y luego descubrieron que la API centrada en la cámara no coincidía con un caso de uso de procesamiento de documentos, y aquellos que se ejecutan en entornos aislados o Docker donde la dependencia del servidor de licencias causó incidentes de producción.
Si perteneces al primer grupo, la migración elimina la biblioteca externa de renderizado de PDF, el bucle de renderizado por página y el patrón de licencia de código de error. Si estás en el segundo grupo, la migración elimina la llamada de red InitLicense, el paquete de contenido de la licencia offline y el ciclo de actualización, y la política de red saliente de tu configuración de Docker o VPC. En cualquier caso, el código fuente se acorta tras esta migración.
Esta guía es honesta sobre lo que pierdes: si tu aplicación procesa cuadros de cámara en tiempo real, la tubería de Capture Vision de Dynamsoft está optimizada para esa carga de trabajo y IronBarcode no es el reemplazo adecuado. Esta guía de migración está destinada al procesamiento de archivos del lado del servidor, flujos de trabajo de documentos y entornos donde el acceso al servidor de licencias supone un problema.
Paso 1: Intercambiar los paquetes NuGet
dotnet remove package Dynamsoft.DotNet.BarcodeReader.Bundle
dotnet add package BarCode
dotnet remove package Dynamsoft.DotNet.BarcodeReader.Bundle
dotnet add package BarCode
Si su proyecto también tiene una biblioteca de renderizado de PDF agregada específicamente para Dynamsoft (PdfiumViewer es la más común), también puede eliminarla:
# Remove if added only for Dynamsoft PDF support
dotnet remove package PdfiumViewer
dotnet remove package PdfiumViewer.Native.x86_64.v8-xfa
# Remove if added only for Dynamsoft PDF support
dotnet remove package PdfiumViewer
dotnet remove package PdfiumViewer.Native.x86_64.v8-xfa
Paso 2: Reemplazar la inicialización de la licencia
Aquí es donde se produce la simplificación más inmediata. El patrón Dynamsoft requiere una comprobación del código de error y un manejo de excepciones en cada inicio:
Antes — Dynamsoft:
using Dynamsoft.License;
using Dynamsoft.Core;
// Must run before any barcode operations
int errorCode = LicenseManager.InitLicense("YOUR-DYNAMSOFT-KEY", out string errorMsg);
if (errorCode != (int)EnumErrorCode.EC_OK)
throw new InvalidOperationException($"License validation failed [{errorCode}]: {errorMsg}");
using Dynamsoft.License;
using Dynamsoft.Core;
// Must run before any barcode operations
int errorCode = LicenseManager.InitLicense("YOUR-DYNAMSOFT-KEY", out string errorMsg);
if (errorCode != (int)EnumErrorCode.EC_OK)
throw new InvalidOperationException($"License validation failed [{errorCode}]: {errorMsg}");
Imports Dynamsoft.License
Imports Dynamsoft.Core
' Must run before any barcode operations
Dim errorCode As Integer = LicenseManager.InitLicense("YOUR-DYNAMSOFT-KEY", errorMsg)
If errorCode <> CType(EnumErrorCode.EC_OK, Integer) Then
Throw New InvalidOperationException($"License validation failed [{errorCode}]: {errorMsg}")
End If
Después — IronBarcode:
// NuGet: dotnet add package BarCode
using IronBarCode;
// Local validation — no network call, no error code
IronBarCode.License.LicenseKey = "YOUR-LICENSE-KEY";
// NuGet: dotnet add package BarCode
using IronBarCode;
// Local validation — no network call, no error code
IronBarCode.License.LicenseKey = "YOUR-LICENSE-KEY";
Imports IronBarCode
' Local validation — no network call, no error code
IronBarCode.License.LicenseKey = "YOUR-LICENSE-KEY"
En una aplicación ASP.NET Core, agrega esto a Program.cs antes de builder.Build():
IronBarCode.License.LicenseKey = Environment.GetEnvironmentVariable("IRONBARCODE_KEY")
?? "YOUR-LICENSE-KEY";
IronBarCode.License.LicenseKey = Environment.GetEnvironmentVariable("IRONBARCODE_KEY")
?? "YOUR-LICENSE-KEY";
Imports IronBarCode
IronBarCode.License.LicenseKey = If(Environment.GetEnvironmentVariable("IRONBARCODE_KEY"), "YOUR-LICENSE-KEY")
En un entorno Docker o Kubernetes, establece la variable de entorno IRONBARCODE_KEY en tu manifiesto de implementación. No se requieren reglas de red saliente.
Paso 3: Reemplazar las importaciones de espacios de nombres
Buscar y reemplazar en todos los archivos fuente:
grep -r "using Dynamsoft\." --include="*.cs" .
grep -r "using Dynamsoft\." --include="*.cs" .
Reemplazar cada aparición:
// Before
using Dynamsoft.CVR;
using Dynamsoft.DBR;
using Dynamsoft.License;
using Dynamsoft.Core;
// After
using IronBarCode;
// Before
using Dynamsoft.CVR;
using Dynamsoft.DBR;
using Dynamsoft.License;
using Dynamsoft.Core;
// After
using IronBarCode;
Imports IronBarCode
Ejemplos de migración de código
Lectura básica de archivos
La operación más fundamental: leer un código de barras a partir de un archivo de imagen.
Antes — Dynamsoft:
using Dynamsoft.CVR;
using Dynamsoft.DBR;
public string ReadBarcodeFromFile(CaptureVisionRouter router, string imagePath)
{
CapturedResult result = router.Capture(imagePath, PresetTemplate.PT_READ_BARCODES);
BarcodeResultItem[] items = result.GetDecodedBarcodesResult()?.GetItems();
if (items == null || items.Length == 0)
return null;
return items[0].GetText();
}
using Dynamsoft.CVR;
using Dynamsoft.DBR;
public string ReadBarcodeFromFile(CaptureVisionRouter router, string imagePath)
{
CapturedResult result = router.Capture(imagePath, PresetTemplate.PT_READ_BARCODES);
BarcodeResultItem[] items = result.GetDecodedBarcodesResult()?.GetItems();
if (items == null || items.Length == 0)
return null;
return items[0].GetText();
}
Imports Dynamsoft.CVR
Imports Dynamsoft.DBR
Public Function ReadBarcodeFromFile(router As CaptureVisionRouter, imagePath As String) As String
Dim result As CapturedResult = router.Capture(imagePath, PresetTemplate.PT_READ_BARCODES)
Dim items As BarcodeResultItem() = result.GetDecodedBarcodesResult()?.GetItems()
If items Is Nothing OrElse items.Length = 0 Then
Return Nothing
End If
Return items(0).GetText()
End Function
Después — IronBarcode:
// NuGet: dotnet add package BarCode
using IronBarCode;
public string ReadBarcodeFromFile(string imagePath)
{
var results = BarcodeReader.Read(imagePath);
return results?.FirstOrDefault()?.Value;
}
// NuGet: dotnet add package BarCode
using IronBarCode;
public string ReadBarcodeFromFile(string imagePath)
{
var results = BarcodeReader.Read(imagePath);
return results?.FirstOrDefault()?.Value;
}
Imports IronBarCode
Public Function ReadBarcodeFromFile(imagePath As String) As String
Dim results = BarcodeReader.Read(imagePath)
Return results?.FirstOrDefault()?.Value
End Function
La instancia del router ha desaparecido. BarcodeReader.Read es estático. BarcodeResultItem.GetText() se convierte en .Value. La comprobación de nulidad en results es más limpia con LINQ.
Lectura de múltiples códigos de barras
Antes — Dynamsoft:
using Dynamsoft.CVR;
using Dynamsoft.DBR;
public List<string> ReadAllBarcodes(CaptureVisionRouter router, string imagePath)
{
SimplifiedCaptureVisionSettings settings = router.GetSimplifiedSettings(
PresetTemplate.PT_READ_BARCODES);
settings.BarcodeSettings.ExpectedBarcodesCount = 0; // 0 = find all
router.UpdateSettings(PresetTemplate.PT_READ_BARCODES, settings);
CapturedResult result = router.Capture(imagePath, PresetTemplate.PT_READ_BARCODES);
BarcodeResultItem[] items = result.GetDecodedBarcodesResult()?.GetItems();
var values = new List<string>();
if (items != null)
{
foreach (var item in items)
values.Add(item.GetText());
}
return values;
}
using Dynamsoft.CVR;
using Dynamsoft.DBR;
public List<string> ReadAllBarcodes(CaptureVisionRouter router, string imagePath)
{
SimplifiedCaptureVisionSettings settings = router.GetSimplifiedSettings(
PresetTemplate.PT_READ_BARCODES);
settings.BarcodeSettings.ExpectedBarcodesCount = 0; // 0 = find all
router.UpdateSettings(PresetTemplate.PT_READ_BARCODES, settings);
CapturedResult result = router.Capture(imagePath, PresetTemplate.PT_READ_BARCODES);
BarcodeResultItem[] items = result.GetDecodedBarcodesResult()?.GetItems();
var values = new List<string>();
if (items != null)
{
foreach (var item in items)
values.Add(item.GetText());
}
return values;
}
Imports Dynamsoft.CVR
Imports Dynamsoft.DBR
Public Function ReadAllBarcodes(router As CaptureVisionRouter, imagePath As String) As List(Of String)
Dim settings As SimplifiedCaptureVisionSettings = router.GetSimplifiedSettings(PresetTemplate.PT_READ_BARCODES)
settings.BarcodeSettings.ExpectedBarcodesCount = 0 ' 0 = find all
router.UpdateSettings(PresetTemplate.PT_READ_BARCODES, settings)
Dim result As CapturedResult = router.Capture(imagePath, PresetTemplate.PT_READ_BARCODES)
Dim items As BarcodeResultItem() = result.GetDecodedBarcodesResult()?.GetItems()
Dim values As New List(Of String)()
If items IsNot Nothing Then
For Each item In items
values.Add(item.GetText())
Next
End If
Return values
End Function
Después — IronBarcode:
using IronBarCode;
public List<string> ReadAllBarcodes(string imagePath)
{
var options = new BarcodeReaderOptions
{
ExpectMultipleBarcodes = true,
MaxParallelThreads = 4
};
return BarcodeReader.Read(imagePath, options)
.Select(r => r.Value)
.ToList();
}
using IronBarCode;
public List<string> ReadAllBarcodes(string imagePath)
{
var options = new BarcodeReaderOptions
{
ExpectMultipleBarcodes = true,
MaxParallelThreads = 4
};
return BarcodeReader.Read(imagePath, options)
.Select(r => r.Value)
.ToList();
}
Imports IronBarCode
Public Function ReadAllBarcodes(imagePath As String) As List(Of String)
Dim options As New BarcodeReaderOptions With {
.ExpectMultipleBarcodes = True,
.MaxParallelThreads = 4
}
Return BarcodeReader.Read(imagePath, options) _
.Select(Function(r) r.Value) _
.ToList()
End Function
Lectura desde bytes (imágenes en memoria)
Antes — Dynamsoft:
using Dynamsoft.CVR;
using Dynamsoft.Core;
using Dynamsoft.DBR;
// Requires width, height, stride, and pixel format — low-level buffer API
public string ReadFromBuffer(CaptureVisionRouter router, byte[] rawPixels, int width, int height)
{
var imageData = new ImageData
{
Bytes = rawPixels,
Width = width,
Height = height,
Stride = width * 3, // assuming 24bpp RGB
Format = EnumImagePixelFormat.IPF_RGB_888
};
CapturedResult result = router.Capture(imageData, PresetTemplate.PT_READ_BARCODES);
return result.GetDecodedBarcodesResult()?.GetItems()?.FirstOrDefault()?.GetText();
}
using Dynamsoft.CVR;
using Dynamsoft.Core;
using Dynamsoft.DBR;
// Requires width, height, stride, and pixel format — low-level buffer API
public string ReadFromBuffer(CaptureVisionRouter router, byte[] rawPixels, int width, int height)
{
var imageData = new ImageData
{
Bytes = rawPixels,
Width = width,
Height = height,
Stride = width * 3, // assuming 24bpp RGB
Format = EnumImagePixelFormat.IPF_RGB_888
};
CapturedResult result = router.Capture(imageData, PresetTemplate.PT_READ_BARCODES);
return result.GetDecodedBarcodesResult()?.GetItems()?.FirstOrDefault()?.GetText();
}
Imports Dynamsoft.CVR
Imports Dynamsoft.Core
Imports Dynamsoft.DBR
' Requires width, height, stride, and pixel format — low-level buffer API
Public Function ReadFromBuffer(router As CaptureVisionRouter, rawPixels As Byte(), width As Integer, height As Integer) As String
Dim imageData As New ImageData With {
.Bytes = rawPixels,
.Width = width,
.Height = height,
.Stride = width * 3, ' assuming 24bpp RGB
.Format = EnumImagePixelFormat.IPF_RGB_888
}
Dim result As CapturedResult = router.Capture(imageData, PresetTemplate.PT_READ_BARCODES)
Return result.GetDecodedBarcodesResult()?.GetItems()?.FirstOrDefault()?.GetText()
End Function
Después — IronBarcode:
using IronBarCode;
// Pass PNG/JPEG/BMP bytes directly — no pixel format or stride calculation
public string ReadFromImageBytes(byte[] imageBytes)
{
return BarcodeReader.Read(imageBytes)?.FirstOrDefault()?.Value;
}
using IronBarCode;
// Pass PNG/JPEG/BMP bytes directly — no pixel format or stride calculation
public string ReadFromImageBytes(byte[] imageBytes)
{
return BarcodeReader.Read(imageBytes)?.FirstOrDefault()?.Value;
}
Imports IronBarCode
Public Function ReadFromImageBytes(imageBytes As Byte()) As String
Return BarcodeReader.Read(imageBytes)?.FirstOrDefault()?.Value
End Function
Si su aplicación convertía previamente los bytes de la imagen en un búfer de píxeles sin procesar para Dynamsoft, puede pasar los bytes de la imagen codificada original (PNG, JPEG, BMP) directamente a IronBarcode sin decodificarlos primero a píxeles sin procesar.
Lectura de códigos de barras PDF: Eliminar el bucle de renderizado
Esta suele ser la mayor reducción de código en la migración. Elimine todo el bucle de renderizado de PdfiumViewer y reemplácelo con una sola llamada.
Antes — Dynamsoft con PdfiumViewer:
// Requires: Dynamsoft.DotNet.BarcodeReader.Bundle + PdfiumViewer + PdfiumViewer.Native.*
using Dynamsoft.CVR;
using Dynamsoft.DBR;
using PdfiumViewer;
using System.Drawing.Imaging;
public List<string> ReadBarcodesFromPdf(CaptureVisionRouter router, string pdfPath)
{
var allBarcodes = new List<string>();
using (var pdfDoc = PdfDocument.Load(pdfPath))
{
for (int page = 0; page < pdfDoc.PageCount; page++)
{
using var image = pdfDoc.Render(page, 300, 300, true);
using var ms = new MemoryStream();
image.Save(ms, ImageFormat.Png);
CapturedResult result = router.Capture(ms.ToArray(),
PresetTemplate.PT_READ_BARCODES);
var items = result.GetDecodedBarcodesResult()?.GetItems();
if (items != null)
{
foreach (var item in items)
allBarcodes.Add(item.GetText());
}
}
}
return allBarcodes;
}
// Requires: Dynamsoft.DotNet.BarcodeReader.Bundle + PdfiumViewer + PdfiumViewer.Native.*
using Dynamsoft.CVR;
using Dynamsoft.DBR;
using PdfiumViewer;
using System.Drawing.Imaging;
public List<string> ReadBarcodesFromPdf(CaptureVisionRouter router, string pdfPath)
{
var allBarcodes = new List<string>();
using (var pdfDoc = PdfDocument.Load(pdfPath))
{
for (int page = 0; page < pdfDoc.PageCount; page++)
{
using var image = pdfDoc.Render(page, 300, 300, true);
using var ms = new MemoryStream();
image.Save(ms, ImageFormat.Png);
CapturedResult result = router.Capture(ms.ToArray(),
PresetTemplate.PT_READ_BARCODES);
var items = result.GetDecodedBarcodesResult()?.GetItems();
if (items != null)
{
foreach (var item in items)
allBarcodes.Add(item.GetText());
}
}
}
return allBarcodes;
}
Imports Dynamsoft.CVR
Imports Dynamsoft.DBR
Imports PdfiumViewer
Imports System.Drawing.Imaging
Public Function ReadBarcodesFromPdf(router As CaptureVisionRouter, pdfPath As String) As List(Of String)
Dim allBarcodes As New List(Of String)()
Using pdfDoc As PdfDocument = PdfDocument.Load(pdfPath)
For page As Integer = 0 To pdfDoc.PageCount - 1
Using image = pdfDoc.Render(page, 300, 300, True)
Using ms As New MemoryStream()
image.Save(ms, ImageFormat.Png)
Dim result As CapturedResult = router.Capture(ms.ToArray(), PresetTemplate.PT_READ_BARCODES)
Dim items = result.GetDecodedBarcodesResult()?.GetItems()
If items IsNot Nothing Then
For Each item In items
allBarcodes.Add(item.GetText())
Next
End If
End Using
End Using
Next
End Using
Return allBarcodes
End Function
Después — IronBarcode:
using IronBarCode;
public List<string> ReadBarcodesFromPdf(string pdfPath)
{
return BarcodeReader.Read(pdfPath)
.Select(r => r.Value)
.ToList();
}
using IronBarCode;
public List<string> ReadBarcodesFromPdf(string pdfPath)
{
return BarcodeReader.Read(pdfPath)
.Select(r => r.Value)
.ToList();
}
Imports IronBarCode
Public Function ReadBarcodesFromPdf(pdfPath As String) As List(Of String)
Return BarcodeReader.Read(pdfPath) _
.Select(Function(r) r.Value) _
.ToList()
End Function
El bucle de página, el PdfDocument, el paso de renderizado a 300 DPI, el MemoryStream y la llamada Capture por página desaparecen. IronBarcode gestiona internamente las páginas PDF.
Si necesita leer un PDF con opciones (para códigos de barras densos o difíciles):
using IronBarCode;
public List<string> ReadBarcodesFromPdfAccurate(string pdfPath)
{
var options = new BarcodeReaderOptions
{
Speed = ReadingSpeed.Balanced,
ExpectMultipleBarcodes = true
};
return BarcodeReader.Read(pdfPath, options)
.Select(r => r.Value)
.ToList();
}
using IronBarCode;
public List<string> ReadBarcodesFromPdfAccurate(string pdfPath)
{
var options = new BarcodeReaderOptions
{
Speed = ReadingSpeed.Balanced,
ExpectMultipleBarcodes = true
};
return BarcodeReader.Read(pdfPath, options)
.Select(r => r.Value)
.ToList();
}
Imports IronBarCode
Public Function ReadBarcodesFromPdfAccurate(pdfPath As String) As List(Of String)
Dim options As New BarcodeReaderOptions With {
.Speed = ReadingSpeed.Balanced,
.ExpectMultipleBarcodes = True
}
Return BarcodeReader.Read(pdfPath, options) _
.Select(Function(r) r.Value) _
.ToList()
End Function
Implementación sin conexión / aislada de la red
Si su código actual incluye el patrón de licencia sin conexión, elimínelo por completo:
Antes — Licencia sin conexión de Dynamsoft:
using Dynamsoft.License;
using Dynamsoft.Core;
// Dynamsoft offline: fetch license bundle on a connected machine, persist it,
// then replay it on the offline machine via InitLicenseFromLicenseContent.
int errorCode = LicenseManager.InitLicenseFromLicenseContent(
licenseContent,
out string errorMsg);
if (errorCode != (int)EnumErrorCode.EC_OK)
throw new InvalidOperationException($"Offline license failed: {errorMsg}");
using Dynamsoft.License;
using Dynamsoft.Core;
// Dynamsoft offline: fetch license bundle on a connected machine, persist it,
// then replay it on the offline machine via InitLicenseFromLicenseContent.
int errorCode = LicenseManager.InitLicenseFromLicenseContent(
licenseContent,
out string errorMsg);
if (errorCode != (int)EnumErrorCode.EC_OK)
throw new InvalidOperationException($"Offline license failed: {errorMsg}");
Imports Dynamsoft.License
Imports Dynamsoft.Core
' Dynamsoft offline: fetch license bundle on a connected machine, persist it,
' then replay it on the offline machine via InitLicenseFromLicenseContent.
Dim errorMsg As String
Dim errorCode As Integer = LicenseManager.InitLicenseFromLicenseContent(licenseContent, errorMsg)
If errorCode <> CType(EnumErrorCode.EC_OK, Integer) Then
Throw New InvalidOperationException($"Offline license failed: {errorMsg}")
End If
Después — IronBarcode:
// Remove all of the above. Replace with:
IronBarCode.License.LicenseKey = "YOUR-LICENSE-KEY";
// Remove all of the above. Replace with:
IronBarCode.License.LicenseKey = "YOUR-LICENSE-KEY";
IronBarCode.License.LicenseKey = "YOUR-LICENSE-KEY"
No hay paquete de contenido de licencia para buscar y actualizar. No hay paso de inicialización de máquina conectada. La clave se valida localmente.
Configuración de Docker
Si anteriormente tenías reglas de egreso de red o configuración de proxy para permitir HTTPS saliente a los puntos finales de licencia de Dynamsoft:
# Before: Docker or Kubernetes egress policy
# Required: Allow outbound HTTPS to Dynamsoft licence endpoints
# After: Remove that egress rule.
# IronBarcode does not require outbound network access for license validation.
# Set license via environment variable
env:
- name: IRONBARCODE_KEY
valueFrom:
secretKeyRef:
name: ironbarcode-license
key: key
# Before: Docker or Kubernetes egress policy
# Required: Allow outbound HTTPS to Dynamsoft licence endpoints
# After: Remove that egress rule.
# IronBarcode does not require outbound network access for license validation.
# Set license via environment variable
env:
- name: IRONBARCODE_KEY
valueFrom:
secretKeyRef:
name: ironbarcode-license
key: key
Limpieza de la administración de instancias
Dynamsoft utiliza una API basada en instancias construida alrededor de CaptureVisionRouter. Si tu código crea instancias de enrutadores en clases de servicio, inicializadores de campo o registros DI, todo eso desaparece:
Antes — Gestión de instancias de Dynamsoft:
using Dynamsoft.CVR;
using Dynamsoft.DBR;
using Dynamsoft.License;
using Dynamsoft.Core;
public class BarcodeService : IDisposable
{
private readonly CaptureVisionRouter _router;
public BarcodeService()
{
int errorCode = LicenseManager.InitLicense("KEY", out string errorMsg);
if (errorCode != (int)EnumErrorCode.EC_OK)
throw new InvalidOperationException(errorMsg);
_router = new CaptureVisionRouter();
var settings = _router.GetSimplifiedSettings(PresetTemplate.PT_READ_BARCODES);
settings.BarcodeSettings.ExpectedBarcodesCount = 0;
_router.UpdateSettings(PresetTemplate.PT_READ_BARCODES, settings);
}
public string[] ReadFile(string path)
{
CapturedResult result = _router.Capture(path, PresetTemplate.PT_READ_BARCODES);
var items = result.GetDecodedBarcodesResult()?.GetItems();
return items?.Select(i => i.GetText()).ToArray() ?? Array.Empty<string>();
}
public void Dispose()
{
_router?.Dispose();
}
}
using Dynamsoft.CVR;
using Dynamsoft.DBR;
using Dynamsoft.License;
using Dynamsoft.Core;
public class BarcodeService : IDisposable
{
private readonly CaptureVisionRouter _router;
public BarcodeService()
{
int errorCode = LicenseManager.InitLicense("KEY", out string errorMsg);
if (errorCode != (int)EnumErrorCode.EC_OK)
throw new InvalidOperationException(errorMsg);
_router = new CaptureVisionRouter();
var settings = _router.GetSimplifiedSettings(PresetTemplate.PT_READ_BARCODES);
settings.BarcodeSettings.ExpectedBarcodesCount = 0;
_router.UpdateSettings(PresetTemplate.PT_READ_BARCODES, settings);
}
public string[] ReadFile(string path)
{
CapturedResult result = _router.Capture(path, PresetTemplate.PT_READ_BARCODES);
var items = result.GetDecodedBarcodesResult()?.GetItems();
return items?.Select(i => i.GetText()).ToArray() ?? Array.Empty<string>();
}
public void Dispose()
{
_router?.Dispose();
}
}
Imports Dynamsoft.CVR
Imports Dynamsoft.DBR
Imports Dynamsoft.License
Imports Dynamsoft.Core
Public Class BarcodeService
Implements IDisposable
Private ReadOnly _router As CaptureVisionRouter
Public Sub New()
Dim errorCode As Integer = LicenseManager.InitLicense("KEY", errorMsg:=Nothing)
If errorCode <> CType(EnumErrorCode.EC_OK, Integer) Then
Throw New InvalidOperationException(errorMsg)
End If
_router = New CaptureVisionRouter()
Dim settings = _router.GetSimplifiedSettings(PresetTemplate.PT_READ_BARCODES)
settings.BarcodeSettings.ExpectedBarcodesCount = 0
_router.UpdateSettings(PresetTemplate.PT_READ_BARCODES, settings)
End Sub
Public Function ReadFile(path As String) As String()
Dim result As CapturedResult = _router.Capture(path, PresetTemplate.PT_READ_BARCODES)
Dim items = result.GetDecodedBarcodesResult()?.GetItems()
Return If(items?.Select(Function(i) i.GetText()).ToArray(), Array.Empty(Of String)())
End Function
Public Sub Dispose() Implements IDisposable.Dispose
_router?.Dispose()
End Sub
End Class
Después — API estática de IronBarcode :
// NuGet: dotnet add package BarCode
using IronBarCode;
public class BarcodeService
{
// No constructor initialization — license set once at app startup
// No Dispose — no instance to clean up
public string[] ReadFile(string path)
{
var options = new BarcodeReaderOptions { ExpectMultipleBarcodes = true };
return BarcodeReader.Read(path, options)
.Select(r => r.Value)
.ToArray();
}
}
// NuGet: dotnet add package BarCode
using IronBarCode;
public class BarcodeService
{
// No constructor initialization — license set once at app startup
// No Dispose — no instance to clean up
public string[] ReadFile(string path)
{
var options = new BarcodeReaderOptions { ExpectMultipleBarcodes = true };
return BarcodeReader.Read(path, options)
.Select(r => r.Value)
.ToArray();
}
}
Imports IronBarCode
Public Class BarcodeService
' No constructor initialization — license set once at app startup
' No Dispose — no instance to clean up
Public Function ReadFile(path As String) As String()
Dim options As New BarcodeReaderOptions With {.ExpectMultipleBarcodes = True}
Return BarcodeReader.Read(path, options) _
.Select(Function(r) r.Value) _
.ToArray()
End Function
End Class
La clase pierde su constructor, su implementación de IDisposable y su campo _router. Si este servicio estaba registrado en DI como un servicio singleton o con alcance para gestionar el ciclo de vida del enrutador, ese registro puede simplificarse o el servicio puede convertirse en un conjunto de métodos estáticos.
Mapeo de velocidad de lectura frente a tiempo de espera
Dynamsoft utiliza un Timeout en milisegundos optimizado para las tasas de fotogramas de las cámaras. IronBarcode utiliza un ReadingSpeed enum:
| Configuración de Dynamsoft | Equivalente de IronBarcode |
|---|---|
settings.Timeout = 100 (pipeline de cámara) |
Speed = ReadingSpeed.Faster |
| Tiempo de espera bajo (priorizar la velocidad) | Speed = ReadingSpeed.Balanced |
| Mayor tiempo de espera (priorizar la precisión) | Speed = ReadingSpeed.Detailed |
| Máxima precisión, sin presión de tiempo. | Speed = ReadingSpeed.ExtremeDetail |
Para la mayoría de los flujos de trabajo de procesamiento de documentos donde el rendimiento es más importante que el tiempo de respuesta inferior a 100ms, ReadingSpeed.Balanced es la opción predeterminada adecuada:
var options = new BarcodeReaderOptions
{
Speed = ReadingSpeed.Balanced,
ExpectMultipleBarcodes = true,
MaxParallelThreads = 4
};
var options = new BarcodeReaderOptions
{
Speed = ReadingSpeed.Balanced,
ExpectMultipleBarcodes = true,
MaxParallelThreads = 4
};
Dim options As New BarcodeReaderOptions With {
.Speed = ReadingSpeed.Balanced,
.ExpectMultipleBarcodes = True,
.MaxParallelThreads = 4
}
Problemas comunes de migración
BarcodeResultItem.GetText() vs result.Value
El accesor cambia de un método a una propiedad:
// Before
string value = item.GetText();
// After
string value = result.Value;
// Before
string value = item.GetText();
// After
string value = result.Value;
' Before
Dim value As String = item.GetText()
' After
Dim value As String = result.Value
BarcodeResultItem.GetFormatString() vs result.Format
Dynamsoft devuelve el formato como una cadena a través de GetFormatString(). IronBarcode lo expone como un BarcodeEncoding enum en result.Format:
// Before
if (item.GetFormatString() == "QR_CODE")
Console.WriteLine("Found QR code");
// After
if (result.Format == BarcodeEncoding.QRCode)
Console.WriteLine("Found QR code");
// For logging without enum comparison — .ToString() works on both
Console.WriteLine($"Format: {result.Format}");
// Before
if (item.GetFormatString() == "QR_CODE")
Console.WriteLine("Found QR code");
// After
if (result.Format == BarcodeEncoding.QRCode)
Console.WriteLine("Found QR code");
// For logging without enum comparison — .ToString() works on both
Console.WriteLine($"Format: {result.Format}");
' Before
If item.GetFormatString() = "QR_CODE" Then
Console.WriteLine("Found QR code")
End If
' After
If result.Format = BarcodeEncoding.QRCode Then
Console.WriteLine("Found QR code")
End If
' For logging without enum comparison — .ToString() works on both
Console.WriteLine($"Format: {result.Format}")
Resultados nulos frente a colección vacía
El GetDecodedBarcodesResult() de Dynamsoft puede devolver null cuando no se encuentran códigos de barras. IronBarcode devuelve una colección vacía. Actualizar comprobaciones nulas:
// Before: null check required
CapturedResult result = router.Capture(path, PresetTemplate.PT_READ_BARCODES);
var items = result.GetDecodedBarcodesResult()?.GetItems();
if (items != null && items.Length > 0)
Process(items[0].GetText());
// After: null-safe but also correct to check Count
var results = BarcodeReader.Read(path);
if (results.Any())
Process(results.First().Value);
// Before: null check required
CapturedResult result = router.Capture(path, PresetTemplate.PT_READ_BARCODES);
var items = result.GetDecodedBarcodesResult()?.GetItems();
if (items != null && items.Length > 0)
Process(items[0].GetText());
// After: null-safe but also correct to check Count
var results = BarcodeReader.Read(path);
if (results.Any())
Process(results.First().Value);
Imports System.Linq
' Before: null check required
Dim result As CapturedResult = router.Capture(path, PresetTemplate.PT_READ_BARCODES)
Dim items = result.GetDecodedBarcodesResult()?.GetItems()
If items IsNot Nothing AndAlso items.Length > 0 Then
Process(items(0).GetText())
End If
' After: null-safe but also correct to check Count
Dim results = BarcodeReader.Read(path)
If results.Any() Then
Process(results.First().Value)
End If
SimplifiedCaptureVisionSettings to BarcodeReaderOptions
El patrón GetSimplifiedSettings / UpdateSettings se convierte en BarcodeReaderOptions pasado a Read:
// Before
var settings = router.GetSimplifiedSettings(PresetTemplate.PT_READ_BARCODES);
settings.BarcodeSettings.ExpectedBarcodesCount = 0;
settings.Timeout = 500;
router.UpdateSettings(PresetTemplate.PT_READ_BARCODES, settings);
var result = router.Capture(path, PresetTemplate.PT_READ_BARCODES);
// After
var options = new BarcodeReaderOptions
{
Speed = ReadingSpeed.Balanced,
ExpectMultipleBarcodes = true
};
var results = BarcodeReader.Read(path, options);
// Before
var settings = router.GetSimplifiedSettings(PresetTemplate.PT_READ_BARCODES);
settings.BarcodeSettings.ExpectedBarcodesCount = 0;
settings.Timeout = 500;
router.UpdateSettings(PresetTemplate.PT_READ_BARCODES, settings);
var result = router.Capture(path, PresetTemplate.PT_READ_BARCODES);
// After
var options = new BarcodeReaderOptions
{
Speed = ReadingSpeed.Balanced,
ExpectMultipleBarcodes = true
};
var results = BarcodeReader.Read(path, options);
' Before
Dim settings = router.GetSimplifiedSettings(PresetTemplate.PT_READ_BARCODES)
settings.BarcodeSettings.ExpectedBarcodesCount = 0
settings.Timeout = 500
router.UpdateSettings(PresetTemplate.PT_READ_BARCODES, settings)
Dim result = router.Capture(path, PresetTemplate.PT_READ_BARCODES)
' After
Dim options As New BarcodeReaderOptions With {
.Speed = ReadingSpeed.Balanced,
.ExpectMultipleBarcodes = True
}
Dim results = BarcodeReader.Read(path, options)
Lista de comprobación de la migración
Ejecute estas búsquedas para encontrar todas las referencias de Dynamsoft que necesitan actualizarse:
grep -r "using Dynamsoft\." --include="*.cs" .
grep -r "LicenseManager.InitLicense\|EnumErrorCode\|EC_OK" --include="*.cs" .
grep -r "new CaptureVisionRouter\|router\.Capture\|PresetTemplate" --include="*.cs" .
grep -r "BarcodeResultItem\|GetDecodedBarcodesResult\|GetFormatString" --include="*.cs" .
grep -r "GetSimplifiedSettings\|UpdateSettings\|SimplifiedCaptureVisionSettings" --include="*.cs" .
grep -r "router\.Dispose\|InitLicenseFromLicenseContent" --include="*.cs" .
grep -r "using Dynamsoft\." --include="*.cs" .
grep -r "LicenseManager.InitLicense\|EnumErrorCode\|EC_OK" --include="*.cs" .
grep -r "new CaptureVisionRouter\|router\.Capture\|PresetTemplate" --include="*.cs" .
grep -r "BarcodeResultItem\|GetDecodedBarcodesResult\|GetFormatString" --include="*.cs" .
grep -r "GetSimplifiedSettings\|UpdateSettings\|SimplifiedCaptureVisionSettings" --include="*.cs" .
grep -r "router\.Dispose\|InitLicenseFromLicenseContent" --include="*.cs" .
Analiza cada partido:
using Dynamsoft.*→using IronBarCodeLicenseManager.InitLicense(key, out errorMsg)+ comprobación de error →IronBarCode.License.LicenseKey = "key"new CaptureVisionRouter()→ eliminar (API estática, no instancia)router.Capture(path, PresetTemplate.PT_READ_BARCODES)→BarcodeReader.Read(path)router.Capture(imageData, ...)(búfer de píxeles sin procesar) →BarcodeReader.Read(imageBytes)- Bucle de renderización de PDF por página +
router.Capture(pageBytes, ...)→BarcodeReader.Read(pdfPath) BarcodeResultItem.GetText()→result.ValueBarcodeResultItem.GetFormatString()→result.FormatGetSimplifiedSettings(...)+UpdateSettings(...)→new BarcodeReaderOptions { ... }router.Dispose()→ eliminarLicenseManager.InitLicenseFromLicenseContent(...)→ eliminar completamente- Elimine los paquetes NuGet de PdfiumViewer si se agregaron únicamente para admitir el procesamiento de PDF de Dynamsoft.
- Elimina las reglas de egreso de red de Docker/Kubernetes para los puntos finales de licencia de Dynamsoft
- Establecer la variable de entorno
IRONBARCODE_KEYen la configuración de implementación
Preguntas Frecuentes
¿Por qué debería migrar de Dynamsoft Barcode Reader 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 Dynamsoft 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 cambia el código al migrar de Dynamsoft Barcode Reader 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 mantener tanto Dynamsoft Barcode Reader como IronBarcode instalados 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 Dynamsoft Barcode Reader?
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 Dynamsoft?
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 Dynamsoft Barcode Reader 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.

