Ir para o conteúdo do rodapé
VíDEOS

Como gerar imagens de código de barras em C# for .NET usando o IronBarcode

Migrating from Dynamsoft Barcode Reader to IronBarcode

A maioria dos desenvolvedores que migra do Dynamsoft Barcode Reader para o IronBarcode se enquadra em um dos dois grupos: aqueles que escolheram Dynamsoft por sua reputação e depois descobriram que a API centrada na câmera não correspondia a um caso de uso de processamento de documentos, e aqueles que operam em ambientes isolados ou em Docker onde a dependência do servidor de licença causou incidentes de produção.

Se você pertence ao primeiro grupo, a migração remove a biblioteca externa de renderização de PDF, o loop de renderização por página e o padrão de licenciamento por código de erro. Se você está no segundo grupo, a migração remove a chamada de rede InitLicense, o pacote de conteúdo da licença offline e o ciclo de atualização, e a política de rede de saída da sua configuração Docker ou VPC. De qualquer forma, a base de código fica mais curta após essa migração.

Este guia é honesto sobre o que você perde: se seu aplicativo processa quadros de câmera em tempo real, o pipeline Capture Vision do Dynamsoft é ajustado para esse tipo de carga de trabalho e o IronBarcode não é o substituto adequado. Este guia de migração destina-se ao processamento de arquivos no servidor, fluxos de trabalho de documentos e ambientes onde o acesso ao servidor de licenças representa um problema.

Passo 1: Trocar os pacotes NuGet

dotnet remove package Dynamsoft.DotNet.BarcodeReader.Bundle
dotnet add package BarCode
dotnet remove package Dynamsoft.DotNet.BarcodeReader.Bundle
dotnet add package BarCode
SHELL

Se o seu projeto também tiver uma biblioteca de renderização de PDF adicionada especificamente para o Dynamsoft (PdfiumViewer é a mais comum), ela também pode ser removida:

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

Etapa 2: Substituir a inicialização da licença

É aqui que ocorre a simplificação mais imediata. O padrão Dynamsoft exige uma verificação de código de erro e tratamento de exceções em cada inicialização:

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

Depois — 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"
$vbLabelText   $csharpLabel

Em uma aplicação ASP.NET Core, adicione isto 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")
$vbLabelText   $csharpLabel

Em um ambiente Docker ou Kubernetes, defina a variável de ambiente IRONBARCODE_KEY em seu manifesto de implantação. Nenhuma regra de rede de saída é necessária.

Etapa 3: Substitua as importações de namespace

Localizar e substituir em todos os arquivos de origem:

grep -r "using Dynamsoft\." --include="*.cs" .
grep -r "using Dynamsoft\." --include="*.cs" .
SHELL

Substitua cada ocorrência:

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

Exemplos de migração de código

Leitura básica de arquivos

A operação mais fundamental — ler um código de barras a partir de um arquivo de imagem.

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

Depois — 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
$vbLabelText   $csharpLabel

A instância do roteador desapareceu. BarcodeReader.Read é estático. BarcodeResultItem.GetText() torna-se .Value. A verificação nula em results é mais limpa com LINQ.

Leitura de múltiplos 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
$vbLabelText   $csharpLabel

Depois — 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
$vbLabelText   $csharpLabel

Leitura de bytes (imagens na memória)

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

Depois — 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
$vbLabelText   $csharpLabel

Se o seu aplicativo anteriormente convertia bytes de imagem em um buffer de pixels brutos para o Dynamsoft, você pode passar os bytes de imagem codificados originais (PNG, JPEG, BMP) diretamente para o IronBarcode sem precisar decodificá-los para pixels brutos primeiro.

Leitura de código de barras em PDF — Remova o loop de renderização

Essa é normalmente a maior redução de código na migração. Remova todo o loop de renderização do PdfiumViewer e substitua-o por uma única chamada.

Antes — Dynamsoft com 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
$vbLabelText   $csharpLabel

Depois — 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
$vbLabelText   $csharpLabel

O loop de páginas, o PdfDocument, o passo de renderização de 300 DPI, o MemoryStream, e a chamada Capture por página desaparecem. O IronBarcode processa páginas PDF internamente.

Se você precisar ler um PDF com opções (para códigos de barras densos ou complexos):

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

Implantação offline/isolada da internet

Se o seu código atual inclui o padrão de licenciamento offline, remova-o completamente:

Antes — Licença offline da 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
$vbLabelText   $csharpLabel

Depois — 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"
$vbLabelText   $csharpLabel

Nenhum pacote de conteúdo de licença para buscar e atualizar. Nenhum passo de bootstrap de máquina conectada. A chave valida localmente.

Configuração do Docker

Se você anteriormente tinha regras de egressão de rede ou configuração de proxy para permitir HTTPS de saída para os pontos de licença do 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
YAML

Limpeza do gerenciamento de instâncias

Dynamsoft usa uma API baseada em instância construída em torno de CaptureVisionRouter. Se seu código cria instâncias de roteador em classes de serviço, inicializadores de campo, ou registros DI, tudo isso desaparece:

Antes — Gerenciamento de instâncias do 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
$vbLabelText   $csharpLabel

Após — API estática do 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
$vbLabelText   $csharpLabel

A classe perde seu construtor, sua implementação IDisposable, e seu campo _router. Se este serviço estava registrado em DI como um serviço singleton ou com escopo para gerenciar o ciclo de vida do roteador, esse registro pode ser simplificado ou o serviço pode se tornar um conjunto de métodos estáticos.

Mapeamento de velocidade de leitura versus tempo limite

Dynamsoft usa um Timeout em milissegundos otimizado para taxas de quadros de câmera. IronBarcode usa um enum ReadingSpeed:

Configuração Dynamsoft Equivalente ao IronBarcode
settings.Timeout = 100 (caminho da câmera) Speed = ReadingSpeed.Faster
Tempo limite baixo (priorizar a velocidade) Speed = ReadingSpeed.Balanced
Tempo limite maior (priorizar a precisão) Speed = ReadingSpeed.Detailed
Máxima precisão, sem pressão de tempo. Speed = ReadingSpeed.ExtremeDetail

Para a maioria dos fluxos de trabalho de processamento de documentos onde a vazão é mais importante que o tempo de resposta inferior a 100ms, ReadingSpeed.Balanced é o padrão correto:

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

Problemas comuns de migração

BarcodeResultItem.GetText() vs result.Value

O acessador muda de um método para uma propriedade:

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

BarcodeResultItem.GetFormatString() vs result.Format

Dynamsoft retorna o formato como uma string via GetFormatString(). IronBarcode o expõe como um enum BarcodeEncoding em 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}")
$vbLabelText   $csharpLabel

Resultados nulos vs. Coleção vazia

O GetDecodedBarcodesResult() da Dynamsoft pode retornar null quando não forem encontrados códigos de barras. IronBarcode retorna uma coleção vazia. Atualizar verificações de valores nulos:

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

SimplifiedCaptureVisionSettings to BarcodeReaderOptions

O padrão GetSimplifiedSettings / UpdateSettings torna-se BarcodeReaderOptions passado para 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)
$vbLabelText   $csharpLabel

Lista de verificação para migração

Execute estas pesquisas para encontrar todas as referências do Dynamsoft que precisam ser atualizadas:

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

Analise cada partida:

  • using Dynamsoft.*using IronBarCode
  • LicenseManager.InitLicense(key, out errorMsg) + verificação de erro → IronBarCode.License.LicenseKey = "key"
  • new CaptureVisionRouter() → remover (API estática, sem instância)
  • router.Capture(path, PresetTemplate.PT_READ_BARCODES)BarcodeReader.Read(path)
  • router.Capture(imageData, ...) (buffer de pixel cru) → BarcodeReader.Read(imageBytes)
  • Loop de renderização de PDF por página + router.Capture(pageBytes, ...)BarcodeReader.Read(pdfPath)
  • BarcodeResultItem.GetText()result.Value
  • BarcodeResultItem.GetFormatString()result.Format
  • GetSimplifiedSettings(...) + UpdateSettings(...)new BarcodeReaderOptions { ... }
  • router.Dispose() → remover
  • LicenseManager.InitLicenseFromLicenseContent(...) → remover completamente
  • Remova os pacotes NuGet do PdfiumViewer se eles foram adicionados apenas para dar suporte ao processamento de PDFs da Dynamsoft.
  • Remova as regras de egressão de rede Docker/Kubernetes para os pontos de licença do Dynamsoft
  • Defina a variável de ambiente IRONBARCODE_KEY na configuração de implantação

Perguntas frequentes

Por que devo migrar do Dynamsoft Barcode Reader para o IronBarcode?

Entre os motivos comuns estão a simplificação do licenciamento (removendo a complexidade do SDK e da chave de tempo de execução), a eliminação dos limites de taxa de transferência, a obtenção de suporte nativo para PDF, a melhoria da implantação em Docker/CI/CD e a redução do código repetitivo da API em produção.

Como faço para substituir as chamadas da API do Dynamsoft pelo IronBarcode?

Substitua o código padrão de criação de instâncias e licenciamento por `IronBarCode.License.LicenseKey = "key"`. Substitua as chamadas de leitura por `BarcodeReader.Read(path)` e as chamadas de gravação por `BarcodeWriter.CreateBarcode(data, encoding)`. Os métodos estáticos não exigem gerenciamento de instâncias.

Quanta alteração de código ocorre ao migrar do Dynamsoft Barcode Reader para o IronBarcode?

A maioria das migrações resulta em menos linhas de código. O código repetitivo de licenciamento, os construtores de instância e a configuração explícita de formato são removidos. As operações principais de leitura/gravação são mapeadas para equivalentes mais curtos em IronBarcode, com objetos de resultado mais limpos.

Preciso manter o Dynamsoft Barcode Reader e o IronBarcode instalados durante a migração?

Não. A maioria das migrações são substituições diretas, e não operações paralelas. Migre uma classe de serviço por vez, substitua a referência do NuGet e atualize os padrões de instanciação e chamada de API antes de passar para a próxima classe.

Qual é o nome do pacote NuGet para IronBarcode?

O pacote é 'IronBarCode' (com B e C maiúsculos). Instale-o com 'Install-Package IronBarCode' ou 'dotnet add package IronBarCode'. A diretiva using no código é 'using IronBarCode;'.

Como o IronBarcode simplifica a implantação do Docker em comparação com o Dynamsoft Barcode Reader?

IronBarcode é um pacote NuGet sem arquivos SDK externos ou configuração de licença montada. No Docker, defina a variável de ambiente IRONBARCODE_LICENSE_KEY e o pacote cuidará da validação da licença na inicialização.

O IronBarcode detecta automaticamente todos os formatos de código de barras após a migração do Dynamsoft?

Sim. O IronBarcode detecta automaticamente a simbologia em todos os formatos suportados. A enumeração explícita de BarcodeTypes não é necessária. Se o formato já for conhecido e o desempenho for importante, o BarcodeReaderOptions permite restringir o espaço de busca como uma otimização.

O IronBarcode consegue ler códigos de barras de PDFs sem uma biblioteca separada?

Sim. O método `BarcodeReader.Read("document.pdf")` processa arquivos PDF nativamente. Os resultados incluem o número da página, o formato, o valor e a confiança de cada código de barras encontrado. Não é necessária nenhuma etapa externa de renderização de PDF.

Como o IronBarcode lida com o processamento paralelo de códigos de barras?

Os métodos estáticos do IronBarcode são sem estado e thread-safe. Use Parallel.ForEach diretamente em listas de arquivos sem gerenciamento de instâncias por thread. BarcodeReaderOptions.MaxParallelThreads controla o orçamento interno de threads.

Quais propriedades de resultado são alteradas ao migrar do Dynamsoft Barcode Reader para o IronBarcode?

Renomeações comuns: BarcodeValue torna-se Value, BarcodeType torna-se Format. Os resultados do IronBarcode também incluem Confidence e PageNumber. Uma função de busca e substituição em toda a solução lida com as renomeações no código de processamento de resultados existente.

Como configuro o licenciamento do IronBarcode em um pipeline de CI/CD?

Armazene IRONBARCODE_LICENSE_KEY como um segredo de pipeline e atribua IronBarCode.License.LicenseKey no código de inicialização do aplicativo. Um único segredo abrange todos os ambientes, incluindo desenvolvimento, teste, homologação e produção.

O IronBarcode suporta a geração de códigos QR com estilos personalizados?

Sim. O método QRCodeWriter.CreateQrCode() suporta cores personalizadas através do método ChangeBarCodeColor(), incorporação de logotipo através do método AddBrandLogo(), níveis configuráveis de correção de erros e múltiplos formatos de saída, incluindo PNG, JPG, PDF e fluxo de dados.

Curtis Chau
Redator Técnico

Curtis Chau é bacharel em Ciência da Computação (Universidade Carleton) e se especializa em desenvolvimento front-end, com experiência em Node.js, TypeScript, JavaScript e React. Apaixonado por criar interfaces de usuário intuitivas e esteticamente agradáveis, Curtis gosta de trabalhar com frameworks modernos e criar manuais ...

Leia mais

Equipe de Suporte Iron

Estamos online 24 horas por dia, 5 dias por semana.
Bater papo
E-mail
Liga para mim