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

Como personalizar e adicionar logotipos a códigos QR em C#

Migrating fromAccusoft BarcodeXpressto IronBarcode

A maior parte do trabalho nesta migração consiste em exclusão. O sistema de licenciamento de duas chaves — SetSolutionName, SetSolutionKey e SetOEMLicenseKey para runtime — desaparece totalmente. As operações reais de código de barras (ler uma imagem, gravar um código de barras em um arquivo) são traduzidas para equivalentes IronBarcode mais curtos. Se sua base de código tiver uma classe BarcodeService que envolve o BarcodeXpress, o código de licenciamento muitas vezes é uma grande fração disso. Após a migração, essa classe encolhe.

Por que migrar do Accusoft BarcodeXpress?

As equipes que migraram do BarcodeXpress relatam os seguintes fatores desencadeantes:

Modo de Avaliação Bloqueia a Comparação Precisa: Sem uma chave OEM/tempo de execução válida, BarcodeXpress estampa os resultados decodificados com a string literal " UNLICENSED accusoft.com " e aplica a mesma estampa a códigos de barras 2D gerados. Testes de precisão antes da compra em documentos reais produzem essa saída com marca d'água, então você não pode verificar se a biblioteca lê seus tipos de digitalização real corretamente antes de se comprometer com uma compra.

Licenciamento de Duas Chaves Aumenta a Sobrecarga Operacional: O BarcodeXpress separa a licença SDK (SetSolutionName + SetSolutionKey) da licença OEM/runtime (SetOEMLicenseKey). Pipelines de CI/CD, contêineres Docker e orquestradores de contêineres precisam que ambos os sistemas principais sejam gerenciados como segredos separados. Uma chave de execução ausente ou inválida retorna para saída com marca d'água em vez de gerar um erro, criando um modo de falha que pode passar em testes automatizados se as afirmações verificarem apenas resultados não nulos.

Mínimo de cinco licenças de tempo de execução para qualquer implantação em produção: Mesmo uma implantação em um único servidor exige a compra de pelo menos cinco licenças de tempo de execução. Equipes que utilizam um servidor de produção e um servidor de teste pagam no mínimo dez licenças de tempo de execução, independentemente do uso real.

Limite de 40 PPM na Edição Padrão: A Edição Padrão limita o processamento a 40 páginas por minuto. Um lote de 100.000 documentos leva aproximadamente 41 horas nesse ritmo. Para remover o limite, é necessário atualizar para a Edição Professional , que tem um custo mais elevado por licença de desenvolvedor, além das licenças de tempo de execução já adquiridas.

Sem suporte nativo para PDF: os arquivos PDF precisam ser convertidos em imagens usando uma biblioteca separada antes que o BarcodeXpress possa lê-los. Essa dependência externa adiciona um segundo custo de licenciamento, uma etapa de conversão e pressão adicional na memória devido ao armazenamento das imagens renderizadas da página.

Segurança de Threads Exige Isolamento de Instância: O objeto reader do BarcodeXpress é stateful e não é seguro para acesso concorrente. Processamento em lote paralelo requer uma instância BarcodeXpress completamente inicializada por thread, com a inicialização completa da licença de duas camadas repetida em cada contexto de thread.

O problema fundamental

BarcodeXpress requer uma inicialização em várias etapas, um carregamento de Bitmap e uma configuração de BarcodeType[] antes que qualquer código de barras possa ser lido:

using var bitmap = new Bitmap(imagePath);
var barcodeXpress = new BarcodeXpress(".");
barcodeXpress.Licensing.SetSolutionName("AcmeCorp");
barcodeXpress.Licensing.SetSolutionKey(1, 2, 3, 4);
barcodeXpress.Licensing.SetOEMLicenseKey("2.0.OEMLicenseStringFromAccusoft...");

barcodeXpress.reader.BarcodeTypes = new[]
{
    BarcodeType.Code128Barcode,
    BarcodeType.DataMatrixBarcode,
    BarcodeType.QRCodeBarcode
};

Result[] results = barcodeXpress.reader.Analyze(bitmap);
var value = results.FirstOrDefault()?.BarcodeValue;
using var bitmap = new Bitmap(imagePath);
var barcodeXpress = new BarcodeXpress(".");
barcodeXpress.Licensing.SetSolutionName("AcmeCorp");
barcodeXpress.Licensing.SetSolutionKey(1, 2, 3, 4);
barcodeXpress.Licensing.SetOEMLicenseKey("2.0.OEMLicenseStringFromAccusoft...");

barcodeXpress.reader.BarcodeTypes = new[]
{
    BarcodeType.Code128Barcode,
    BarcodeType.DataMatrixBarcode,
    BarcodeType.QRCodeBarcode
};

Result[] results = barcodeXpress.reader.Analyze(bitmap);
var value = results.FirstOrDefault()?.BarcodeValue;
Imports System.Drawing
Imports Accusoft.BarcodeXpressSdk

Using bitmap As New Bitmap(imagePath)
    Dim barcodeXpress = New BarcodeXpress(".")
    barcodeXpress.Licensing.SetSolutionName("AcmeCorp")
    barcodeXpress.Licensing.SetSolutionKey(1, 2, 3, 4)
    barcodeXpress.Licensing.SetOEMLicenseKey("2.0.OEMLicenseStringFromAccusoft...")

    barcodeXpress.Reader.BarcodeTypes = New BarcodeType() {
        BarcodeType.Code128Barcode,
        BarcodeType.DataMatrixBarcode,
        BarcodeType.QRCodeBarcode
    }

    Dim results As Result() = barcodeXpress.Reader.Analyze(bitmap)
    Dim value = results.FirstOrDefault()?.BarcodeValue
End Using
$vbLabelText   $csharpLabel

IronBarcode substitui todo esse bloco por uma única chamada estática:

var value = BarcodeReader.Read(imagePath).First().Value;
var value = BarcodeReader.Read(imagePath).First().Value;
Dim value = BarcodeReader.Read(imagePath).First().Value
$vbLabelText   $csharpLabel

IronBarcode vs Accusoft BarcodeXpress: Comparação de Recursos

Recurso Accusoft BarcodeXpress IronBarcode
Modelo de licença Chave SDK + chave OEM/tempo de execução (compras separadas) Chave perpétua única
Licenças mínimas de tempo de execução 5 (mesmo para 1 servidor) Não existe o conceito de licença de tempo de execução.
Modo de avaliação Valores decodificados e códigos de barras 2D gerados estampilados com " UNLICENSED accusoft.com " Valores totais retornados; A marca d'água só estará presente no resultado gerado.
Limite de capacidade 40 PPM (Edição Padrão) Sem limite em nenhum nível.
Detecção automática de formato Manual — deve-se atribuir um array BarcodeType[] a BarcodeTypes Automático em todos os formatos suportados.
Suporte a PDF Requer biblioteca externa para renderizar páginas para Bitmaps Nativo — BarcodeReader.Read("doc.pdf")
Estilo da API Baseado em instância; Entrada de Bitmap; configuração de propriedade/método Métodos de fábrica estáticos, API fluente
Segurança da rosca É necessário ter uma instância por thread. Métodos estáticos sem estado — seguro para threads
Configuração de licença do Docker Montagem do arquivo de licença ou servidor de licenças Variável de ambiente única
Segredos de CI/CD necessários Par de chaves SDK + chave OEM/tempo de execução Um segredo
.NET Framework / .NET Core Pacotes separados: Accusoft.BarcodeXpress.Net e Accusoft.BarcodeXpress.NetCore Pacote único IronBarcode (.NET Framework 4.6.2+, .NET Core 3.1+, .NET 5–8)
Linux/macOS Sim (via pacote .NetCore) Sim — Windows x64/x86, Linux x64, macOS x64/ARM
Código QR com logotipo Sobreposição manual de GDI+ necessária AddBrandLogo("logo.png") embutido
Ponto de entrada de preços $1,960+ SDK + no mínimo 5 licenças de execução Licença perpétua de US$ 749 (Lite, 1 desenvolvedor)
Licença perpétua Não é padrão — entre em contato com o departamento de vendas. Sim, todos os níveis.

Guia rápido: Migração doAccusoft BarcodeXpresspara o IronBarcode

Passo 1: Substitua o pacote NuGet

dotnet remove package Accusoft.BarcodeXpress.NetCore
dotnet add package IronBarcode
dotnet remove package Accusoft.BarcodeXpress.NetCore
dotnet add package IronBarcode
SHELL

Etapa 2: Atualizar Namespaces

// Remove
using Accusoft.BarcodeXpressSdk;

// Add
using IronBarCode;
// Remove
using Accusoft.BarcodeXpressSdk;

// Add
using IronBarCode;
Imports IronBarCode
$vbLabelText   $csharpLabel

Etapa 3: Inicializar a licença

Adicione a inicialização da licença uma vez no início da aplicação em Program.cs, Startup.cs, ou na configuração da sua injeção de dependências:

// Add once at application startup
IronBarCode.License.LicenseKey = "YOUR-LICENSE-KEY";
// Add once at application startup
IronBarCode.License.LicenseKey = "YOUR-LICENSE-KEY";
' Add once at application startup
IronBarCode.License.LicenseKey = "YOUR-LICENSE-KEY"
$vbLabelText   $csharpLabel

Em produção, leia a chave de uma variável de ambiente ou do seu gerenciador de segredos:

IronBarCode.License.LicenseKey =
    Environment.GetEnvironmentVariable("IRONBARCODE_LICENSE")
    ?? throw new InvalidOperationException("IronBarcode license key not configured");
IronBarCode.License.LicenseKey =
    Environment.GetEnvironmentVariable("IRONBARCODE_LICENSE")
    ?? throw new InvalidOperationException("IronBarcode license key not configured");
Imports IronBarCode
Imports System

License.LicenseKey = If(Environment.GetEnvironmentVariable("IRONBARCODE_LICENSE"), Throw New InvalidOperationException("IronBarcode license key not configured"))
$vbLabelText   $csharpLabel

Não há SetSolutionKey, não há SetOEMLicenseKey, não há ativação runtime por servidor. Essa é a configuração completa da licença.

Exemplos de migração de código

Inicialização da licença

Abordagem BarcodeXpress:

using Accusoft.BarcodeXpressSdk;

public class BarcodeService
{
    private readonly BarcodeXpress _barcodeXpress;

    public BarcodeService()
    {
        // Constructor takes the path containing the Barcode Xpress runtime files.
        _barcodeXpress = new BarcodeXpress(".");

        // SDK license
        _barcodeXpress.Licensing.SetSolutionName("AcmeCorp");
        _barcodeXpress.Licensing.SetSolutionKey(1, 2, 3, 4);

        // OEM/runtime license — separate purchase, minimum 5 licenses required.
        // Without this call, decoded values and generated 2D barcodes are
        // stamped with " UNLICENSED accusoft.com ".
        _barcodeXpress.Licensing.SetOEMLicenseKey(
            "2.0.OEMLicenseStringFromAccusoft...");
    }
}
using Accusoft.BarcodeXpressSdk;

public class BarcodeService
{
    private readonly BarcodeXpress _barcodeXpress;

    public BarcodeService()
    {
        // Constructor takes the path containing the Barcode Xpress runtime files.
        _barcodeXpress = new BarcodeXpress(".");

        // SDK license
        _barcodeXpress.Licensing.SetSolutionName("AcmeCorp");
        _barcodeXpress.Licensing.SetSolutionKey(1, 2, 3, 4);

        // OEM/runtime license — separate purchase, minimum 5 licenses required.
        // Without this call, decoded values and generated 2D barcodes are
        // stamped with " UNLICENSED accusoft.com ".
        _barcodeXpress.Licensing.SetOEMLicenseKey(
            "2.0.OEMLicenseStringFromAccusoft...");
    }
}
Imports Accusoft.BarcodeXpressSdk

Public Class BarcodeService
    Private ReadOnly _barcodeXpress As BarcodeXpress

    Public Sub New()
        ' Constructor takes the path containing the Barcode Xpress runtime files.
        _barcodeXpress = New BarcodeXpress(".")

        ' SDK license
        _barcodeXpress.Licensing.SetSolutionName("AcmeCorp")
        _barcodeXpress.Licensing.SetSolutionKey(1, 2, 3, 4)

        ' OEM/runtime license — separate purchase, minimum 5 licenses required.
        ' Without this call, decoded values and generated 2D barcodes are
        ' stamped with " UNLICENSED accusoft.com ".
        _barcodeXpress.Licensing.SetOEMLicenseKey("2.0.OEMLicenseStringFromAccusoft...")
    End Sub
End Class
$vbLabelText   $csharpLabel

Abordagem do IronBarcode:

using IronBarCode;

// In Program.cs
IronBarCode.License.LicenseKey = Environment.GetEnvironmentVariable("IRONBARCODE_LICENSE");

// BarcodeService no longer needs a constructor or any license management
public class BarcodeService
{
    // Ready to use — no initialization needed
}
using IronBarCode;

// In Program.cs
IronBarCode.License.LicenseKey = Environment.GetEnvironmentVariable("IRONBARCODE_LICENSE");

// BarcodeService no longer needs a constructor or any license management
public class BarcodeService
{
    // Ready to use — no initialization needed
}
Imports IronBarCode

' In Program.vb
IronBarCode.License.LicenseKey = Environment.GetEnvironmentVariable("IRONBARCODE_LICENSE")

' BarcodeService no longer needs a constructor or any license management
Public Class BarcodeService
    ' Ready to use — no initialization needed
End Class
$vbLabelText   $csharpLabel

O construtor do BarcodeXpress existe apenas para gerenciar dois sistemas de chave de licença e o caminho de execução.IronBarcode substitui isso com uma linha no início da aplicação. A classe BarcodeService não requer nenhum construtor.

Leitura de Código de Barras

Abordagem BarcodeXpress:

using System.Drawing;
using Accusoft.BarcodeXpressSdk;

public string ReadFirstBarcode(string imagePath)
{
    // Analyze takes a System.Drawing.Bitmap; the SDK does not read PDFs directly.
    using var bitmap = new Bitmap(imagePath);

    _barcodeXpress.reader.BarcodeTypes = new[]
    {
        BarcodeType.Code128Barcode,
        BarcodeType.DataMatrixBarcode,
        BarcodeType.QRCodeBarcode
    };

    Result[] results = _barcodeXpress.reader.Analyze(bitmap);

    return results.FirstOrDefault()?.BarcodeValue;
}
using System.Drawing;
using Accusoft.BarcodeXpressSdk;

public string ReadFirstBarcode(string imagePath)
{
    // Analyze takes a System.Drawing.Bitmap; the SDK does not read PDFs directly.
    using var bitmap = new Bitmap(imagePath);

    _barcodeXpress.reader.BarcodeTypes = new[]
    {
        BarcodeType.Code128Barcode,
        BarcodeType.DataMatrixBarcode,
        BarcodeType.QRCodeBarcode
    };

    Result[] results = _barcodeXpress.reader.Analyze(bitmap);

    return results.FirstOrDefault()?.BarcodeValue;
}
Imports System.Drawing
Imports Accusoft.BarcodeXpressSdk

Public Function ReadFirstBarcode(imagePath As String) As String
    ' Analyze takes a System.Drawing.Bitmap; the SDK does not read PDFs directly.
    Using bitmap As New Bitmap(imagePath)
        _barcodeXpress.reader.BarcodeTypes = New BarcodeType() {
            BarcodeType.Code128Barcode,
            BarcodeType.DataMatrixBarcode,
            BarcodeType.QRCodeBarcode
        }

        Dim results As Result() = _barcodeXpress.reader.Analyze(bitmap)

        Return results.FirstOrDefault()?.BarcodeValue
    End Using
End Function
$vbLabelText   $csharpLabel

Abordagem do IronBarcode:

using IronBarCode;

public string ReadFirstBarcode(string imagePath)
{
    var results = BarcodeReader.Read(imagePath);
    return results.First().Value;
}
using IronBarCode;

public string ReadFirstBarcode(string imagePath)
{
    var results = BarcodeReader.Read(imagePath);
    return results.First().Value;
}
Imports IronBarCode

Public Function ReadFirstBarcode(imagePath As String) As String
    Dim results = BarcodeReader.Read(imagePath)
    Return results.First().Value
End Function
$vbLabelText   $csharpLabel

O filtro de array BarcodeTypes e a etapa de carregamento new Bitmap(...) ambos desaparecem.IronBarcode detecta automaticamente o formato em todas as simbologias suportadas e aceita um caminho de arquivo diretamente. Se um fornecedor mudar do Code 128 para o DataMatrix, o IronBarcode continuará funcionando sem qualquer alteração de código. Os nomes das propriedades de resultado também mudam: BarcodeValue torna-se Value, e BarcodeType torna-se Format. Uma função de busca e substituição em toda a solução lida com ambas as renomeações.

Leitura de múltiplos códigos de barras a partir de uma única imagem

Abordagem BarcodeXpress:

using System.Drawing;
using Accusoft.BarcodeXpressSdk;

public IReadOnlyList<string> ReadAllBarcodes(string imagePath)
{
    using var bitmap = new Bitmap(imagePath);
    _barcodeXpress.reader.BarcodeTypes = new[]
    {
        BarcodeType.Code128Barcode,
        BarcodeType.QRCodeBarcode
    };

    Result[] results = _barcodeXpress.reader.Analyze(bitmap);
    return results.Select(r => r.BarcodeValue).ToList();
}
using System.Drawing;
using Accusoft.BarcodeXpressSdk;

public IReadOnlyList<string> ReadAllBarcodes(string imagePath)
{
    using var bitmap = new Bitmap(imagePath);
    _barcodeXpress.reader.BarcodeTypes = new[]
    {
        BarcodeType.Code128Barcode,
        BarcodeType.QRCodeBarcode
    };

    Result[] results = _barcodeXpress.reader.Analyze(bitmap);
    return results.Select(r => r.BarcodeValue).ToList();
}
Imports System.Drawing
Imports Accusoft.BarcodeXpressSdk

Public Function ReadAllBarcodes(imagePath As String) As IReadOnlyList(Of String)
    Using bitmap As New Bitmap(imagePath)
        _barcodeXpress.reader.BarcodeTypes = New BarcodeType() {
            BarcodeType.Code128Barcode,
            BarcodeType.QRCodeBarcode
        }

        Dim results As Result() = _barcodeXpress.reader.Analyze(bitmap)
        Return results.Select(Function(r) r.BarcodeValue).ToList()
    End Using
End Function
$vbLabelText   $csharpLabel

Abordagem do IronBarcode:

using IronBarCode;

public IReadOnlyList<string> ReadAllBarcodes(string imagePath)
{
    var options = new BarcodeReaderOptions { ExpectMultipleBarcodes = true };
    var results = BarcodeReader.Read(imagePath, options);
    return results.Select(r => r.Value).ToList();
}
using IronBarCode;

public IReadOnlyList<string> ReadAllBarcodes(string imagePath)
{
    var options = new BarcodeReaderOptions { ExpectMultipleBarcodes = true };
    var results = BarcodeReader.Read(imagePath, options);
    return results.Select(r => r.Value).ToList();
}
Imports IronBarCode

Public Function ReadAllBarcodes(imagePath As String) As IReadOnlyList(Of String)
    Dim options As New BarcodeReaderOptions With {.ExpectMultipleBarcodes = True}
    Dim results = BarcodeReader.Read(imagePath, options)
    Return results.Select(Function(r) r.Value).ToList()
End Function
$vbLabelText   $csharpLabel

ExpectMultipleBarcodes instrui o IronBarcode a continuar escaneando após a primeira correspondência, o que é útil para documentos com vários códigos em diferentes regiões. Para obter mais detalhes sobre as opções de leitura, consulte a documentação de leitura do IronBarcode .

Processamento em lote

BarcodeXpress é baseado em instância e seu objeto reader é stateful, portanto, o processamento em lote paralelo requer uma instância por thread com a inicialização completa da licença de duas camadas repetida por thread. Os métodos estáticos do IronBarcode são sem estado, então Parallel.ForEach não precisa de gerenciamento de instância.

Abordagem BarcodeXpress:

using System.Collections.Generic;
using System.Drawing;
using Accusoft.BarcodeXpressSdk;

public Dictionary<string, string> ProcessBatch(IEnumerable<string> imagePaths)
{
    var results = new Dictionary<string, string>();

    foreach (var path in imagePaths)
    {
        using var bitmap = new Bitmap(path);
        _barcodeXpress.reader.BarcodeTypes = new[]
        {
            BarcodeType.Code128Barcode,
            BarcodeType.QRCodeBarcode
        };

        Result[] barcodes = _barcodeXpress.reader.Analyze(bitmap);
        if (barcodes.Length > 0)
            results[path] = barcodes[0].BarcodeValue;
    }

    return results;
}
using System.Collections.Generic;
using System.Drawing;
using Accusoft.BarcodeXpressSdk;

public Dictionary<string, string> ProcessBatch(IEnumerable<string> imagePaths)
{
    var results = new Dictionary<string, string>();

    foreach (var path in imagePaths)
    {
        using var bitmap = new Bitmap(path);
        _barcodeXpress.reader.BarcodeTypes = new[]
        {
            BarcodeType.Code128Barcode,
            BarcodeType.QRCodeBarcode
        };

        Result[] barcodes = _barcodeXpress.reader.Analyze(bitmap);
        if (barcodes.Length > 0)
            results[path] = barcodes[0].BarcodeValue;
    }

    return results;
}
Imports System.Collections.Generic
Imports System.Drawing
Imports Accusoft.BarcodeXpressSdk

Public Function ProcessBatch(imagePaths As IEnumerable(Of String)) As Dictionary(Of String, String)
    Dim results As New Dictionary(Of String, String)()

    For Each path In imagePaths
        Using bitmap As New Bitmap(path)
            _barcodeXpress.reader.BarcodeTypes = New BarcodeType() {
                BarcodeType.Code128Barcode,
                BarcodeType.QRCodeBarcode
            }

            Dim barcodes As Result() = _barcodeXpress.reader.Analyze(bitmap)
            If barcodes.Length > 0 Then
                results(path) = barcodes(0).BarcodeValue
            End If
        End Using
    Next

    Return results
End Function
$vbLabelText   $csharpLabel

Abordagem do IronBarcode:

using IronBarCode;
using System.Collections.Concurrent;
using System.Threading.Tasks;

public Dictionary<string, string> ProcessBatch(string[] imagePaths)
{
    var results = new ConcurrentDictionary<string, string>();

    Parallel.ForEach(imagePaths, file =>
    {
        var r = BarcodeReader.Read(file);
        var first = r.FirstOrDefault();
        if (first != null)
            results[file] = first.Value;
    });

    return new Dictionary<string, string>(results);
}
using IronBarCode;
using System.Collections.Concurrent;
using System.Threading.Tasks;

public Dictionary<string, string> ProcessBatch(string[] imagePaths)
{
    var results = new ConcurrentDictionary<string, string>();

    Parallel.ForEach(imagePaths, file =>
    {
        var r = BarcodeReader.Read(file);
        var first = r.FirstOrDefault();
        if (first != null)
            results[file] = first.Value;
    });

    return new Dictionary<string, string>(results);
}
Imports IronBarCode
Imports System.Collections.Concurrent
Imports System.Threading.Tasks

Public Function ProcessBatch(imagePaths As String()) As Dictionary(Of String, String)
    Dim results = New ConcurrentDictionary(Of String, String)()

    Parallel.ForEach(imagePaths, Sub(file)
        Dim r = BarcodeReader.Read(file)
        Dim first = r.FirstOrDefault()
        If first IsNot Nothing Then
            results(file) = first.Value
        End If
    End Sub)

    Return New Dictionary(Of String, String)(results)
End Function
$vbLabelText   $csharpLabel

Se o limite de 40 páginas por minuto da Edição Padrão do BarcodeXpress fez com que você adicionasse código para lidar com o limite de taxa — como pausas entre grupos de 40 páginas, contagem de páginas por minuto ou adição de atrasos — remova esse código completamente.IronBarcode não tem limite de capacidade de processamento.

Adicionando suporte a PDF

O BarcodeXpress não lê códigos de barras diretamente de arquivos PDF. A solução alternativa típica envolve adicionar uma biblioteca de renderização de PDF separada, renderizar cada página em uma imagem na memória e, em seguida, passar essas imagens para o leitor de código de barras uma de cada vez.

Abordagem BarcodeXpress:

// Requires a separate PDF library (not shown — varies by team choice)
// Pattern: render each PDF page to a Bitmap, then pass it to Analyze.
foreach (Bitmap pageBitmap in pdfRenderer.RenderPages("document.pdf"))
{
    using (pageBitmap)
    {
        _barcodeXpress.reader.BarcodeTypes = Enum.GetValues(typeof(BarcodeType));
        Result[] barcodes = _barcodeXpress.reader.Analyze(pageBitmap);
        // ... collect results
    }
}
// Requires a separate PDF library (not shown — varies by team choice)
// Pattern: render each PDF page to a Bitmap, then pass it to Analyze.
foreach (Bitmap pageBitmap in pdfRenderer.RenderPages("document.pdf"))
{
    using (pageBitmap)
    {
        _barcodeXpress.reader.BarcodeTypes = Enum.GetValues(typeof(BarcodeType));
        Result[] barcodes = _barcodeXpress.reader.Analyze(pageBitmap);
        // ... collect results
    }
}
Imports System
Imports System.Drawing

' Requires a separate PDF library (not shown — varies by team choice)
' Pattern: render each PDF page to a Bitmap, then pass it to Analyze.
For Each pageBitmap As Bitmap In pdfRenderer.RenderPages("document.pdf")
    Using pageBitmap
        _barcodeXpress.reader.BarcodeTypes = [Enum].GetValues(GetType(BarcodeType))
        Dim barcodes As Result() = _barcodeXpress.reader.Analyze(pageBitmap)
        ' ... collect results
    End Using
Next
$vbLabelText   $csharpLabel

Abordagem do IronBarcode:

using IronBarCode;

// One call — no rendering step, no external dependency
var results = BarcodeReader.Read("document.pdf");

foreach (var barcode in results)
{
    Console.WriteLine($"Page {barcode.PageNumber}: [{barcode.Format}] {barcode.Value}");
}
using IronBarCode;

// One call — no rendering step, no external dependency
var results = BarcodeReader.Read("document.pdf");

foreach (var barcode in results)
{
    Console.WriteLine($"Page {barcode.PageNumber}: [{barcode.Format}] {barcode.Value}");
}
Imports IronBarCode

' One call — no rendering step, no external dependency
Dim results = BarcodeReader.Read("document.pdf")

For Each barcode In results
    Console.WriteLine($"Page {barcode.PageNumber}: [{barcode.Format}] {barcode.Value}")
Next
$vbLabelText   $csharpLabel

Se Aspose.PDF, PdfiumViewer, itext7, ou qualquer outra biblioteca PDF foi adicionada apenas para suportar o fluxo de trabalho de leitura do BarcodeXpress, ela pode ser removida após a migração. Veja o guia de leitura de PDF do IronBarcode para opções adicionais, incluindo seleção de intervalo de páginas.

Geração de código de barras

Abordagem BarcodeXpress:

using System.Drawing;
using Accusoft.BarcodeXpressSdk;

public void GenerateBarcode(string data, string outputPath)
{
    _barcodeXpress.writer.BarcodeType = BarcodeType.Code128Barcode;
    _barcodeXpress.writer.BarcodeValue = data;

    // CreateBitmap returns a System.Drawing.Bitmap; persist via Bitmap.Save.
    using Bitmap bitmap = _barcodeXpress.writer.CreateBitmap();
    bitmap.Save(outputPath);
}
using System.Drawing;
using Accusoft.BarcodeXpressSdk;

public void GenerateBarcode(string data, string outputPath)
{
    _barcodeXpress.writer.BarcodeType = BarcodeType.Code128Barcode;
    _barcodeXpress.writer.BarcodeValue = data;

    // CreateBitmap returns a System.Drawing.Bitmap; persist via Bitmap.Save.
    using Bitmap bitmap = _barcodeXpress.writer.CreateBitmap();
    bitmap.Save(outputPath);
}
Imports System.Drawing
Imports Accusoft.BarcodeXpressSdk

Public Sub GenerateBarcode(data As String, outputPath As String)
    _barcodeXpress.writer.BarcodeType = BarcodeType.Code128Barcode
    _barcodeXpress.writer.BarcodeValue = data

    ' CreateBitmap returns a System.Drawing.Bitmap; persist via Bitmap.Save.
    Using bitmap As Bitmap = _barcodeXpress.writer.CreateBitmap()
        bitmap.Save(outputPath)
    End Using
End Sub
$vbLabelText   $csharpLabel

Abordagem do IronBarcode:

using IronBarCode;

public void GenerateBarcode(string data, string outputPath)
{
    BarcodeWriter.CreateBarcode(data, BarcodeEncoding.Code128)
        .ResizeTo(400, 100)
        .SaveAsPng(outputPath);
}
using IronBarCode;

public void GenerateBarcode(string data, string outputPath)
{
    BarcodeWriter.CreateBarcode(data, BarcodeEncoding.Code128)
        .ResizeTo(400, 100)
        .SaveAsPng(outputPath);
}
Imports IronBarCode

Public Sub GenerateBarcode(data As String, outputPath As String)
    BarcodeWriter.CreateBarcode(data, BarcodeEncoding.Code128) _
        .ResizeTo(400, 100) _
        .SaveAsPng(outputPath)
End Sub
$vbLabelText   $csharpLabel

A cadeia fluente substitui as atribuições de propriedades, a chamada CreateBitmap e a etapa Bitmap.Save. Para obter o código de barras como dados binários para armazenar em um banco de dados ou retornar de uma API:

byte[] pngBytes = BarcodeWriter.CreateBarcode(data, BarcodeEncoding.Code128)
    .ToPngBinaryData();
byte[] pngBytes = BarcodeWriter.CreateBarcode(data, BarcodeEncoding.Code128)
    .ToPngBinaryData();
Dim pngBytes As Byte() = BarcodeWriter.CreateBarcode(data, BarcodeEncoding.Code128).ToPngBinaryData()
$vbLabelText   $csharpLabel

Geração de código QR

Abordagem BarcodeXpress:

_barcodeXpress.writer.BarcodeType = BarcodeType.QRCodeBarcode;
_barcodeXpress.writer.BarcodeValue = data;

using Bitmap bitmap = _barcodeXpress.writer.CreateBitmap();
bitmap.Save("qr.png");
// Logo overlay required manual GDI+ drawing on the returned Bitmap
_barcodeXpress.writer.BarcodeType = BarcodeType.QRCodeBarcode;
_barcodeXpress.writer.BarcodeValue = data;

using Bitmap bitmap = _barcodeXpress.writer.CreateBitmap();
bitmap.Save("qr.png");
// Logo overlay required manual GDI+ drawing on the returned Bitmap
Imports System.Drawing

_barcodeXpress.writer.BarcodeType = BarcodeType.QRCodeBarcode
_barcodeXpress.writer.BarcodeValue = data

Using bitmap As Bitmap = _barcodeXpress.writer.CreateBitmap()
    bitmap.Save("qr.png")
    ' Logo overlay required manual GDI+ drawing on the returned Bitmap
End Using
$vbLabelText   $csharpLabel

Abordagem do IronBarcode:

using IronBarCode;
using IronSoftware.Drawing;

// Simple QR
QRCodeWriter.CreateQrCode("https://example.com", 500)
    .SaveAsPng("qr.png");

// With branded logo
QRCodeWriter.CreateQrCode("https://example.com", 500)
    .AddBrandLogo("logo.png")
    .SaveAsPng("qr-branded.png");

// With high error correction (for logo overlays)
QRCodeWriter.CreateQrCode(
    "https://example.com",
    500,
    QRCodeWriter.QrErrorCorrectionLevel.Highest)
    .AddBrandLogo("logo.png")
    .SaveAsPng("qr-branded-high-ecc.png");

// Colored QR code
QRCodeWriter.CreateQrCode("https://example.com", 300)
    .ChangeBarCodeColor(Color.DarkBlue)
    .SaveAsPng("qr-colored.png");
using IronBarCode;
using IronSoftware.Drawing;

// Simple QR
QRCodeWriter.CreateQrCode("https://example.com", 500)
    .SaveAsPng("qr.png");

// With branded logo
QRCodeWriter.CreateQrCode("https://example.com", 500)
    .AddBrandLogo("logo.png")
    .SaveAsPng("qr-branded.png");

// With high error correction (for logo overlays)
QRCodeWriter.CreateQrCode(
    "https://example.com",
    500,
    QRCodeWriter.QrErrorCorrectionLevel.Highest)
    .AddBrandLogo("logo.png")
    .SaveAsPng("qr-branded-high-ecc.png");

// Colored QR code
QRCodeWriter.CreateQrCode("https://example.com", 300)
    .ChangeBarCodeColor(Color.DarkBlue)
    .SaveAsPng("qr-colored.png");
Imports IronBarCode
Imports IronSoftware.Drawing

' Simple QR
QRCodeWriter.CreateQrCode("https://example.com", 500) _
    .SaveAsPng("qr.png")

' With branded logo
QRCodeWriter.CreateQrCode("https://example.com", 500) _
    .AddBrandLogo("logo.png") _
    .SaveAsPng("qr-branded.png")

' With high error correction (for logo overlays)
QRCodeWriter.CreateQrCode( _
    "https://example.com", _
    500, _
    QRCodeWriter.QrErrorCorrectionLevel.Highest) _
    .AddBrandLogo("logo.png") _
    .SaveAsPng("qr-branded-high-ecc.png")

' Colored QR code
QRCodeWriter.CreateQrCode("https://example.com", 300) _
    .ChangeBarCodeColor(Color.DarkBlue) _
    .SaveAsPng("qr-colored.png")
$vbLabelText   $csharpLabel

A incorporação de logotipos, o nível de correção de erros e a personalização de cores são recursos integrados à API fluente. Para qualquer uma dessas funcionalidades, o BarcodeXpress requer desenho GDI+ manual após a gravação inicial do arquivo. Para mais opções de QR code, veja o guia de geração de QR code.

Referência de mapeamento da APIAccusoft BarcodeXpresspara IronBarcode

Accusoft BarcodeXpress IronBarcode
new BarcodeXpress(".") Métodos estáticos — nenhuma instância é necessária
Licensing.SetSolutionName("...") IronBarCode.License.LicenseKey = "key"
Licensing.SetSolutionKey(a, b, c, d) (removed — not needed)
Licensing.SetOEMLicenseKey(string) (removed — no OEM/runtime key concept)
new Bitmap(path) + reader.Analyze(bitmap) BarcodeReader.Read(path)
reader.BarcodeTypes = new[] { BarcodeType.Code128Barcode, ... } (removed — auto-detection handles all formats)
result.BarcodeValue result.Value
result.BarcodeType result.Format
writer.BarcodeType = BarcodeType.Code128Barcode BarcodeWriter.CreateBarcode("data", BarcodeEncoding.Code128)
writer.BarcodeValue = "data" (first argument to CreateBarcode)
writer.CreateBitmap() + bitmap.Save(path) .SaveAsPng(path)
writer.BarcodeType = BarcodeType.QRCodeBarcode QRCodeWriter.CreateQrCode(data, size)
Limite padrão de 40 PPM Sem limite de taxa de transferência em nenhum nível.

Problemas e soluções comuns em migrações

Problema 1: Erros de compilação do nome da propriedade

BarcodeXpress: Objetos de resultado expõem BarcodeValue e BarcodeType, que não existem no IronBarcode.

Solução: Execute uma operação de busca e substituição em toda a solução antes de compilá-la:

grep -r "\.BarcodeValue" --include="*.cs" .
grep -r "\.BarcodeType" --include="*.cs" .
grep -r "\.BarcodeValue" --include="*.cs" .
grep -r "\.BarcodeType" --include="*.cs" .
SHELL

Substitua result.BarcodeValue por result.Value e result.BarcodeType por result.Format em todos os arquivos encontrados.

Problema 2: Chamadas de Configuração de Licença Órfãs

BarcodeXpress: Chamadas SetSolutionName, SetSolutionKey, e SetOEMLicenseKey — além de quaisquer assertivas personalizadas que detectam a marca d'água " UNLICENSED accusoft.com " na saída decodificada — existem em muitas bases de código como defesas contra o modo de falha de saída com marca d'água.

Solução: Localize e exclua todos esses locais de chamada —IronBarcode não tem estado equivalente. A chave de licença é válida ou não, e se não for, os limites de teste se aplicam uniformemente em vez de degradar valores decodificados individuais:

grep -r "SetOEMLicenseKey" --include="*.cs" .
grep -r "SetSolutionName" --include="*.cs" .
grep -r "SetSolutionKey" --include="*.cs" .
grep -r "UNLICENSED accusoft" --include="*.cs" .
grep -r "SetOEMLicenseKey" --include="*.cs" .
grep -r "SetSolutionName" --include="*.cs" .
grep -r "SetSolutionKey" --include="*.cs" .
grep -r "UNLICENSED accusoft" --include="*.cs" .
SHELL

Todos esses locais de chamadas podem ser excluídos.

Problema 3: Montagem do arquivo de licença do Docker em variável de ambiente

BarcodeXpress: Implantações Docker tipicamente montam um arquivo de configuração de licença do BarcodeXpress no contêiner em um caminho conhecido usando uma instrução COPY ou montagem de volume.

Solução: Remova a cópia do arquivo de configuração e substitua-a por uma variável de ambiente:

# Remove this
COPY accusoft-license.lic /app/license/

# Add this
ENV IRONBARCODE_LICENSE=YOUR-LICENSE-KEY

Na inicialização do aplicativo:

IronBarCode.License.LicenseKey =
    Environment.GetEnvironmentVariable("IRONBARCODE_LICENSE");
IronBarCode.License.LicenseKey =
    Environment.GetEnvironmentVariable("IRONBARCODE_LICENSE");
Imports System

IronBarCode.License.LicenseKey = Environment.GetEnvironmentVariable("IRONBARCODE_LICENSE")
$vbLabelText   $csharpLabel

No Kubernetes, a chave de licença se torna uma referência secreta na especificação do pod:

env:
  - name: IRONBARCODE_LICENSE
    valueFrom:
      secretKeyRef:
        name: ironbarcode-secrets
        key: license-key
env:
  - name: IRONBARCODE_LICENSE
    valueFrom:
      secretKeyRef:
        name: ironbarcode-secrets
        key: license-key
YAML

Problema 4: Código de tratamento de limite de taxa

BarcodeXpress: Equipes que processam grandes lotes com limite inferior a 40 PPM (ppm) na Edição Padrão frequentemente adicionavam código para pausar entre grupos de documentos, rastrear contadores por minuto ou introduzir atrasos para se manterem dentro do limite.

Solução: Remova todo o código que limita a taxa de transferência. Localize-o com:

grep -r "40\|PPM\|pagesPerMinute\|minuteStart" --include="*.cs" .
grep -r "40\|PPM\|pagesPerMinute\|minuteStart" --include="*.cs" .
SHELL

IronBarcode não tem limite de capacidade — processe na velocidade que sua infraestrutura suportar.

Problema 5: Segurança de Threads — Remoção do Pool de Instâncias

BarcodeXpress: Bases de código que suportam processamento simultâneo frequentemente mantêm um pool de instâncias BarcodeXpress ou usam um padrão ThreadLocal<BarcodeXpress> para isolar o leitor stateful por thread.

Solução: Remova completamente a lógica de agrupamento. Os BarcodeReader.Read e BarcodeWriter.CreateBarcode do IronBarcode são métodos estáticos sem estado. Chamadas simultâneas provenientes de qualquer número de threads não interferem umas com as outras.

Lista de verificação para migração do Accusoft BarcodeXpress

Tarefas pré-migração

Antes de fazer qualquer alteração no código, faça uma auditoria da base de código para identificar todos os usos do BarcodeXpress:

grep -r "BarcodeXpress" --include="*.cs" .
grep -r "Accusoft" --include="*.cs" .
grep -r "SetSolutionName" --include="*.cs" .
grep -r "SetSolutionKey" --include="*.cs" .
grep -r "SetOEMLicenseKey" --include="*.cs" .
grep -r "reader\.Analyze" --include="*.cs" .
grep -r "writer\.CreateBitmap" --include="*.cs" .
grep -r "\.BarcodeValue" --include="*.cs" .
grep -r "\.BarcodeType" --include="*.cs" .
grep -r "BarcodeType\." --include="*.cs" .
grep -r "BarcodeXpress" --include="*.cs" .
grep -r "Accusoft" --include="*.cs" .
grep -r "SetSolutionName" --include="*.cs" .
grep -r "SetSolutionKey" --include="*.cs" .
grep -r "SetOEMLicenseKey" --include="*.cs" .
grep -r "reader\.Analyze" --include="*.cs" .
grep -r "writer\.CreateBitmap" --include="*.cs" .
grep -r "\.BarcodeValue" --include="*.cs" .
grep -r "\.BarcodeType" --include="*.cs" .
grep -r "BarcodeType\." --include="*.cs" .
SHELL
  • Nota quais formatos de código de barras estão explicitamente listados em atribuições BarcodeTypes — todos se tornam auto-detectados no IronBarcode
  • Identifique qualquer código de tratamento de limite de taxa que possa ser removido.
  • Identifique quaisquer bibliotecas de renderização de PDF adicionadas exclusivamente para suportar a leitura do BarcodeXpress — estas também podem ser removidas. Obtenha sua chave de licença do IronBarcode e adicione-a ao seu gerenciador de segredos.

Tarefas de atualização de código

  1. Remova Accusoft.BarcodeXpress.NetCore de todos os arquivos .csproj
  2. Adicione IronBarcode a todos os arquivos .csproj que precisam de funcionalidade de código de barras
  3. Substitua using Accusoft.BarcodeXpressSdk; por using IronBarCode; em todos os arquivos
  4. Adicione IronBarCode.License.LicenseKey = ... ao início da aplicação
  5. Exclua todas as chamadas de construtor e campos de instância BarcodeXpress
  6. Exclua todas as chamadas SetSolutionName, SetSolutionKey e SetOEMLicenseKey
  7. Excluir quaisquer afirmações personalizadas que digitalizem a saída decodificada em busca da marca d'água " UNLICENSED accusoft.com "
  8. Substituanew Bitmap(path) + reader.Analyze(bitmap)por BarcodeReader.Read(path)
  9. Remova todas as atribuições reader.BarcodeTypes = ...
  10. Substitua result.BarcodeValue por result.Value
  11. Substitua result.BarcodeType por result.Format
  12. Substituawriter.CreateBitmap() + bitmap.Save(path)por BarcodeWriter.CreateBarcode(data, encoding).SaveAsPng(path)
  13. Remover o código de limitação de taxa
  14. Remova o código intermediário de renderização de PDF, se presente.
  15. Remova o pooling de instâncias ou padrões ThreadLocal para instâncias BarcodeXpress
  16. Remova as montagens de arquivos de licença dos arquivos Dockerfile e docker-compose.
  17. Adicione a variável de ambiente IRONBARCODE_LICENSE às configurações Docker e do contêiner
  18. Atualizar segredos do Kubernetes e especificações de pods
  19. Atualize os segredos do pipeline CI/CD — remova ACCUSOFT_SOLUTION_KEY e ACCUSOFT_RUNTIME_KEY; adicione IRONBARCODE_LICENSE

Testes pós-migração

  • Compile a solução — corrija quaisquer erros de compilação restantes decorrentes de propriedades renomeadas.
  • Executar testes unitários em todas as operações de leitura de código de barras.
  • Executar testes unitários em todas as operações de geração de código de barras.
  • Teste com entradas em PDF, se aplicável.
  • Execute um teste de processamento em lote para confirmar que não há limitação de taxa de transferência.
  • Implante em um ambiente de teste e verifique se a chave de licença é resolvida corretamente a partir da variável de ambiente.

Principais benefícios da migração para o IronBarcode

Eliminação da Complexidade do Licenciamento de Duas Chaves: O setup SetSolutionName, SetSolutionKey, e SetOEMLicenseKey desaparece completamente. Uma chave cobre todos os ambientes do desenvolvimento à produção, e o modo de teste retorna valores decodificados completos (em vez de estampar cada um com " UNLICENSED accusoft.com ") para que a comparação de desempenho em documentos reais antes da compra seja possível.

Sem necessidade de compra mínima de licenças de tempo de execução: O BarcodeXpress requer um mínimo de cinco licenças de tempo de execução para qualquer implementação em produção. A IronBarcode não possui o conceito de licença de tempo de execução — a chave perpétua única cobre qualquer número de implantações em produção dentro de seu nível.

Taxa de transferência sem limite: o limite de 40 PPM da Edição Padrão e qualquer código de limitação de taxa escrito para se manter dentro desse limite podem ser removidos. O IronBarcode processa os dados na velocidade que o hardware e a rede subjacentes permitirem, sem limite imposto por software em nenhum nível de preço.

Leitura PDF Nativa: BarcodeReader.Read("document.pdf") processa arquivos PDF diretamente, retornando resultados por página com número da página, formato, valor e pontuação de confiança. Qualquer biblioteca de renderização de PDF adicionada exclusivamente para dar suporte ao BarcodeXpress pode ser removida, reduzindo dependências e custos de licenciamento.

Segurança de Threads Sem Estado: BarcodeReader.Read e BarcodeWriter.CreateBarcode são métodos estáticos sem estado. Pools de instâncias, padrões ThreadLocal e blocos de inicialização por thread podem todos ser removidos. O processamento simultâneo com Parallel.ForEach não requer mudanças estruturais além de remover os workarounds de threading.

Implantação simplificada de contêineres: as implantações de Docker e Kubernetes usam uma única variável de ambiente para configuração de licença. A distribuição de arquivos de licença, a infraestrutura do servidor de licenças e a montagem de arquivos de configuração foram todas eliminadas.

Perguntas frequentes

Por que devo migrar do Accusoft BarcodeXpress 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 Accusoft BarcodeXpress 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 Accusoft BarcodeXpress 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 Accusoft BarcodeXpress 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 implementação do Docker em comparação com o Accusoft BarcodeXpress?

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 Accusoft BarcodeXpress?

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 Accusoft BarcodeXpress 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