IRONSOFTWAREHOME
VÍDEOS

Migrando do TesseractOcrMaui para o IronOCR

Kannaopat Udonpant
Kannapat Udonpant
Updated: 1 de agosto de 2026

Este guia descreve uma migração completa doTesseractOcrMauipara o IronOCR , com exemplos práticos de código antes e depois para cada etapa. Ele é voltado para desenvolvedores que já decidiram ir além das limitações da plataforma MAUI e precisam de um caminho sistemático para uma biblioteca que funcione de forma idêntica em aplicativos móveis, APIs do lado do servidor, processos em segundo plano e funções na nuvem. Não é necessário ler o artigo comparativo previamente.

Por que migrar do TesseractOcrMaui?

OTesseractOcrMauifoi desenvolvido para resolver uma lacuna real: os wrappers .NET Tesseract existentes não conseguiam resolver a interoperabilidade com plataformas móveis por conta própria. Para um protótipo MAUI puro, sem necessidade de servidores, ele preenche essa lacuna. Os problemas surgem no momento em que o produto cresce além desse escopo limitado.

**As estruturas de destino apenas para MAUI impedem o compartilhamento de código.**TesseractOcrMauienvia destinos para net8.0-ios, net8.0-android e net8.0-windows — todos os apelidos de plataforma MAUI. O pacote não contém net8.0, nem netstandard2.1, nenhum alvo compatível com servidor. Fazer referência a ele a partir de uma biblioteca de classes, um projetoASP.NET Coreou uma Função do Azure gera um erro de compilação. Não há solução alternativa: o pacote é arquiteturalmente incapaz de ser executado fora de um host MAUI. Sempre que o requisito de OCR surge em um contexto não-MAUI, uma segunda biblioteca precisa ser introduzida e mantida em paralelo.

Acoplamento de injeção de dependência obrigatória do MAUI. A chamada AddTesseractOcr() em MauiProgram.cs conecta ITesseract ao provedor de serviços MAUI. Não existe método de fábrica, ponto de entrada estático ou construtor fora desse grafo de injeção de dependência. Isso significa que a lógica de OCR não pode ser extraída em uma biblioteca de classes portátil — toda classe que toma ITesseract em seu construtor está bloqueada ao host do aplicativo MAUI por toda sua vida útil.

Não é possível inserir arquivos PDF em nenhum nível. Os documentos PDF são o formato mais comum para contratos digitalizados, faturas e documentos de identidade.TesseractOcrMauilança NotSupportedException em qualquer entrada de PDF. O processamento de um PDF requer a adição de uma biblioteca de renderização de PDF separada, a extração de imagens página por página, o gerenciamento de arquivos temporários no cache do dispositivo e a limpeza desses arquivos após cada chamada. Isso representa mais de 100 linhas de código de infraestrutura antes que uma única chamada de OCR seja executada — e ainda funciona apenas no MAUI.

Sem pré-processamento integrado para imagens do mundo real. As câmeras de dispositivos móveis produzem imagens com rotação, ruído do sensor e DPI inconsistente entre os modelos de aparelhos. OTesseractOcrMauienvia imagens diretamente para o mecanismo Tesseract sem nenhum pré-processamento. Equipes que precisam de maior precisão devem adicionar SkiaSharp ou ImageSharp, implementar algoritmos de correção de distorção e redução de ruído manualmente, escrever um sistema de gerenciamento de arquivos temporários e testar tudo em variantes de dispositivos iOS e Android. A maioria ignora essa parte. A precisão nas capturas de imagens reais feitas com dispositivos móveis fica prejudicada como consequência.

Risco de manutenção por um único desenvolvedor em uma dependência de produção. OTesseractOcrMauié mantido por um único desenvolvedor. Não há empresa por trás disso, nenhum SLA, nenhum compromisso com patches de segurança e nenhum caminho de escalonamento além de uma ocorrência no GitHub . Para aplicações de produção em setores regulamentados — finanças, saúde, direito — uma biblioteca mantida por voluntários com aproximadamente 33.900 downloads do NuGet não é uma dependência aceitável.

O problema fundamental

OTesseractOcrMauisó compila dentro de um projeto MAUI. Não momento em que outro tipo de projeto precisar de OCR, a arquitetura entra em colapso:

// TesseractOcrMaui: wired to MAUI host — cannot escape to a shared library
// This code compiles only inside a .NET MAUI application
public class OcrService
{
    private readonly ITesseract _tesseract; // resolved from MAUI DI — no other source exists

    public OcrService(ITesseract tesseract) { _tesseract = tesseract; }

    public async Task<string> ReadAsync(string imagePath)
    {
        await _tesseract.InitAsync("eng"); // traineddata must be bundled as MauiAsset
        var result = await _tesseract.RecognizeTextAsync(imagePath);
        return result.Success ? result.RecognizedText : string.Empty;
    }
    // Cannot reference this class from ASP.NET Core, Azure Functions, or Docker
}
C#
// IronOCR: plain instantiable class — compiles in any .NET project type
public class OcrService
{
    private readonly IronTesseract _ocr = new IronTesseract(); // no DI, no MAUI host

    public string Read(string imagePath)
    {
        using var input = new OcrInput();
        input.LoadImage(imagePath);
        return _ocr.Read(input).Text;
    }
    // Place this in a netstandard2.1 library — reference from MAUI, API, and Functions together
}
C#

##IronOCR vs TesseractOcrMaui: Comparação de Recursos

A tabela abaixo aborda as diferenças de capacidade relevantes para as equipes que avaliam essa migração.

RecursoTesseractOcrMauiIronOCR
.NET MAUI (iOS)SimSim (IronOcr.iOS)
.NET MAUI (Android)SimSim (IronOcr.Android)
.NET MAUI (Windows)SimSim
ASP.NET CoreNãoSim
Azure FunctionsNãoSim
AWS LambdaNãoSim
Docker / contêineres LinuxNãoSim
Aplicativos de consoleNãoSim
WPF / WinFormsNãoSim
Biblioteca de classes .NET compartilhadaNãoSim
Entrada de PDF (nativa)NãoSim
Entrada de PDF protegida por senhaNãoSim
Entrada de fluxoNãoSim
Entrada de matriz de bytesNãoSim
Entrada TIFF de várias páginasNãoSim
Saída em PDF pesquisávelNãoSim
Exportação hOCRNãoSim
Desvio automáticoNãoSim
Redução automática de ruídoNãoSim
Aprimoramento de contrasteNãoSim
BinarizaçãoNãoSim
OCR baseado em regiãoNãoSim
Leitura de código de barras durante OCRNãoSim
Coordenadas ao nível da palavraNãoSim
Simultaneidade multilíngueNãoSim
Idiomas suportadosdados treinados agrupados manualmenteMais de 125 pacotes NuGet
Segurança da roscaManualEmbutido
Suporte comercialNenhum (desenvolvedor único)Sim (Iron Software)
LicenciamentoApache 2.0 (gratuito)Perpétuo de $999
Downloads do NuGet~33.900Mais de 5,3 milhões

Guia rápido: Migração doTesseractOcrMauipara o IronOCR

Passo 1: Substitua o pacote NuGet

Remova oTesseractOcrMauido projeto MAUI:

dotnet remove package TesseractOcrMaui
SHELL

Instale o IronOCR. Para projetos MAUI, adicione os pacotes específicos da plataforma juntamente com o pacote principal:

dotnet add package IronOcr, IronOcr.Android, IronOcr.iOS

Para projetos do lado do servidor (ASP.NET Core, Azure Functions, console):

dotnet add package IronOcr

A página do pacote NuGet IronOCR lista todos os pacotes disponíveis para cada plataforma.

Etapa 2: Atualizar Namespaces

Substitua namespacesTesseractOcrMauipelo namespace IronOCR:

// Before (TesseractOcrMaui)
using TesseractOcrMaui;
using TesseractOcrMaui.Results;
using Microsoft.Maui.Storage;

// After (IronOCR)
using IronOcr;
C#

Etapa 3: Inicializar a licença

Adicionar inicialização de licença na inicialização do aplicativo. Em um aplicativo MAUI, isso vai em MauiProgram.cs; no ASP.NET Core, vai em Program.cs:

IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";

Exemplos de migração de código

Substituindo o registro de injeção de dependência do MAUI

OTesseractOcrMauiexige o registro do mecanismo OCR por meio do provedor de serviços MAUI. Remover esse registro é o primeiro passo arquitetônico, pois é ele que vincula todo o código OCR subsequente ao host MAUI.

Abordagem TesseractOcrMaui:

// MauiProgram.cs — OCR engine registered here; nowhere else resolves it
public static class MauiProgram
{
    public static MauiApp CreateMauiApp()
    {
        var builder = MauiApp.CreateBuilder();
        builder.UseMauiApp<App>();

        // Binds OCR to MAUI DI — no standalone path exists after this
        builder.Services.AddTesseractOcr();

        return builder.Build();
    }
}

// Any class that needs OCR must receive ITesseract from the MAUI container
public class InvoicePageViewModel
{
    private readonly ITesseract _tesseract;

    public InvoicePageViewModel(ITesseract tesseract)
    {
        _tesseract = tesseract; // fails to construct outside MAUI host
    }

    public async Task<string> ScanInvoiceAsync(string imagePath)
    {
        await _tesseract.InitAsync("eng");
        var result = await _tesseract.RecognizeTextAsync(imagePath);
        return result.RecognizedText ?? string.Empty;
    }
}
C#

Abordagem IronOCR:

// MauiProgram.cs — license only; no DI registration needed
public static class MauiProgram
{
    public static MauiApp CreateMauiApp()
    {
        var builder = MauiApp.CreateBuilder();
        builder.UseMauiApp<App>();

        // One-line initialization — works for all project types
        IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";

        return builder.Build();
    }
}

// Não constructor injection needed — IronTesseract instantiates directly
public class InvoicePageViewModel
{
    public string ScanInvoice(string imagePath)
    {
        var ocr = new IronTesseract();
        using var input = new OcrInput();
        input.LoadImage(imagePath);
        return ocr.Read(input).Text;
    }
}
C#

Remover AddTesseractOcr() elimina o acoplamento de ID do MAUI. A classe IronTesseract tem um construtor público sem parâmetros e não carrega nenhuma dependência de plataforma — pode ser instanciada em qualquer lugar. Consulte o guia de configuração do IronTesseract para obter opções de inicialização, incluindo o modo do mecanismo e a configuração do idioma.

Movendo a lógica de OCR para uma biblioteca de classes compartilhada

Com o TesseractOcrMaui, compartilhar a lógica de OCR entre diferentes tipos de projeto é estruturalmente impossível. Com IronOCR, o caminho de migração é direto: extraia o serviço em uma biblioteca de classes .NET Standard 2.1 ou net8.0 e o referencie de todos os projetos na solução.

Abordagem TesseractOcrMaui:

// This service CANNOT be extracted to a shared library.
// It compiles only in a project that references TesseractOcrMaui,
// which only has MAUI platform targets.
//
// Result: every non-MAUI project must use a different OCR library,
// duplicating language config, error handling, and accuracy tuning.

public class DocumentOcrService
{
    private readonly ITesseract _tesseract; // MAUI DI only

    public DocumentOcrService(ITesseract tesseract)
    {
        _tesseract = tesseract;
    }

    public async Task<string> ProcessDocumentAsync(string imagePath)
    {
        await _tesseract.InitAsync("eng");
        var result = await _tesseract.RecognizeTextAsync(imagePath);
        return result.Success ? result.RecognizedText : string.Empty;
    }
    // Server team writes their own version using a different library
    // Two codebases, two accuracy profiles, two maintenance tracks
}
C#

Abordagem IronOCR:

// Place this in: MyCompany.OcrCore (net8.0 or netstandard2.1 class library)
// Reference from: MyCompany.MauiApp, MyCompany.Api, MyCompany.BatchWorker

using IronOcr;

namespace MyCompany.OcrCore
{
    public class DocumentOcrService
    {
        private readonly IronTesseract _ocr;

        public DocumentOcrService()
        {
            _ocr = new IronTesseract();
        }

        public string ProcessDocument(string imagePath)
        {
            using var input = new OcrInput();
            input.LoadImage(imagePath);
            input.Deskew();
            input.DeNoise();
            return _ocr.Read(input).Text;
        }

        public string ProcessDocumentFromBytes(byte[] imageData)
        {
            using var input = new OcrInput();
            input.LoadImage(imageData);
            input.Deskew();
            input.DeNoise();
            return _ocr.Read(input).Text;
        }

        public string ProcessDocumentFromStream(Stream imageStream)
        {
            using var input = new OcrInput();
            input.LoadImage(imageStream);
            return _ocr.Read(input).Text;
        }
    }
}
C#

Uma biblioteca de classes, um conjunto de testes, um perfil de precisão. O aplicativo MAUI chama ProcessDocument(photoPath), a APIASP.NET Corechama ProcessDocumentFromBytes(uploadedBytes), e a Função do Azure chama ProcessDocumentFromStream(blobStream) — todas apoiadas pela mesma implementação. O guia de entrada de fluxo e o guia de entrada de imagem documentam todas as variantes de carregamento OcrInput.

Habilitando OCR do lado do servidor no ASP.NET Core

TesseractOcrMaui não pode ser referenciado a partir de um projetoASP.NET Core. As equipes que adicionam um endpoint para upload de documentos são obrigadas a recorrer a uma biblioteca completamente diferente. O IronOCR funciona noASP.NET Coresem qualquer alteração de configuração além da chave de licença.

Abordagem TesseractOcrMaui:

//ASP.NET CoreWeb API —TesseractOcrMauiCANNOT be used here.
// The package has no net8.0 or netstandard target.
// Referencing it produces: "The given project does not support targeting net8.0-ios/android/windows."
//
// Team is forced to add a second OCR library — Tesseract charlesw wrapper,
// a cloud API, or another solution — creating a split codebase.

[ApiController]
[Route("api/[controller]")]
public class DocumentsController : ControllerBase
{
    // Cannot inject ITesseract here — no MAUI host, no MAUI DI container
    // Must use a completely different OCR library for server-side processing
}
C#

Abordagem IronOCR:

//ASP.NET Core—IronOCR works without modification
using IronOcr;
using Microsoft.AspNetCore.Mvc;

[ApiController]
[Route("api/[controller]")]
public class DocumentsController : ControllerBase
{
    [HttpPost("extract-text")]
    public async Task<IActionResult> ExtractText(IFormFile file)
    {
        if (file == null || file.Length == 0)
            return BadRequest("No file uploaded.");

        var ocr = new IronTesseract();
        using var input = new OcrInput();

        // Load directly from the upload stream — no temp files
        using var stream = file.OpenReadStream();

        if (file.ContentType == "application/pdf")
            input.LoadPdf(stream);
        else
            input.LoadImage(stream);

        input.Deskew();
        input.DeNoise();

        var result = ocr.Read(input);

        return Ok(new
        {
            text = result.Text,
            confidence = result.Confidence,
            pageCount = result.Pages.Count()
        });
    }

    [HttpPost("extract-text-batch")]
    public async Task<IActionResult> ExtractTextBatch(List<IFormFile> files)
    {
        var results = new List<object>();

        // Thread-safe: create one IronTesseract per thread
        await Parallel.ForEachAsync(files, async (file, ct) =>
        {
            var ocr = new IronTesseract();
            using var input = new OcrInput();
            using var stream = file.OpenReadStream();
            input.LoadImage(stream);
            var result = ocr.Read(input);

            lock (results)
            {
                results.Add(new { file = file.FileName, text = result.Text });
            }
        });

        return Ok(results);
    }
}
C#

O mesmo código é implantado sem alterações no IIS, no Kestrel ou em um contêiner Docker do Linux. O guia de OCR do ASP.NET aborda a configuração do middleware e o guia de implantação do Docker documenta a configuração do contêiner Linux.

Eliminação do código de manipulador específico da plataforma

A arquitetura do TesseractOcrMaui, que utiliza apenas o MAUI como alvo, força os desenvolvedores a escreverem código específico para cada plataforma ao tentarem integrar o OCR em soluções com múltiplos alvos. O IronOCR elimina a necessidade de condicionais de plataforma, pois o mesmo pacote é resolvido corretamente em todos os destinos.

Abordagem TesseractOcrMaui:

// Attempting to share OCR logic across MAUI and non-MAUI targets
// requires platform-conditional compilation — a maintenance hazard

#if ANDROID || IOS || WINDOWS
// Only compile this block in MAUI targets
// Non-MAUI targets cannot referenceTesseractOcrMauiat all
using TesseractOcrMaui;

public class PlatformOcrHandler
{
    private readonly ITesseract _tesseract;

    public PlatformOcrHandler(ITesseract tesseract)
    {
        _tesseract = tesseract;
    }

    public async Task<string> ProcessAsync(string imagePath)
    {
        await _tesseract.InitAsync("eng");
        var r = await _tesseract.RecognizeTextAsync(imagePath);
        return r.RecognizedText ?? string.Empty;
    }
}
#else
// Server targets need a completely different implementation
public class PlatformOcrHandler
{
    public string ProcessAsync(string imagePath)
    {
        // Duplicate logic using a different library
        throw new PlatformNotSupportedException("Use server OCR library here");
    }
}
#endif
C#

Abordagem IronOCR:

// One implementation — no conditional compilation, no duplicate logic
using IronOcr;

public class PlatformOcrHandler
{
    // This class compiles identically for:
    // net8.0-android, net8.0-ios, net8.0-windows (MAUI targets)
    // net8.0 (server targets)
    // netstandard2.1 (shared library targets)

    public string Process(string imagePath)
    {
        var ocr = new IronTesseract();
        using var input = new OcrInput();
        input.LoadImage(imagePath);
        input.Deskew();
        return ocr.Read(input).Text;
    }
}

// Multi-target .csproj — no conditional package references needed
// <TargetFrameworks>net8.0;net8.0-android;net8.0-ios</TargetFrameworks>
// IronOcr resolves correctly for all three targets from one package reference
C#

As condicionais da plataforma no código de tratamento de OCR indicam uma divisão arquitetônica que se agrava com o tempo. Cada alteração na configuração da linguagem, cada ajuste de pré-processamento, cada ajuste no limite de confiança deve ser aplicado em ambas as ramificações. O IronOCR torna a divisão desnecessária. A visão geral da biblioteca .NET OCR aborda em detalhes a estrutura de projetos com múltiplos destinos.

Extração de dados estruturados com coordenadas de palavras

TesseractOcrMaui expõe apenas result.RecognizedText e uma pontuação de confiança de nível superior. Não é possível extrair palavras individuais com suas caixas delimitadoras — requisito para validação de campos de formulário, análise de documentos ou sobreposição de destaque. O IronOCR expõe um modelo de objeto de documento completo: páginas, parágrafos, linhas, palavras e caracteres, cada um com coordenadas de pixel.

Abordagem TesseractOcrMaui:

// TesseractOcrMaui: flat text string only — no structure, no coordinates
public class TesseractMauiFormParser
{
    private readonly ITesseract _tesseract;

    public TesseractMauiFormParser(ITesseract tesseract)
    {
        _tesseract = tesseract;
    }

    public async Task<Dictionary<string, string>> ParseFormAsync(string imagePath)
    {
        await _tesseract.InitAsync("eng");
        var result = await _tesseract.RecognizeTextAsync(imagePath);

        // result.RecognizedText is one flat string — no field positions
        // Parsing requires fragile line-splitting and regex heuristics
        var fields = new Dictionary<string, string>();
        var lines = result.RecognizedText?.Split('\n') ?? Array.Empty<string>();

        foreach (var line in lines)
        {
            // Hope the layout stays consistent enough to parse
            var parts = line.Split(':');
            if (parts.Length == 2)
                fields[parts[0].Trim()] = parts[1].Trim();
        }

        return fields;
        // Não way to validate against expected field positions
        // Não confidence per word — only document-level confidence
    }
}
C#

Abordagem IronOCR:

// IronOCR: full document structure with bounding boxes per word
using IronOcr;

public class IronOcrFormParser
{
    public List<WordLocation> ExtractWordsWithPositions(string imagePath)
    {
        var ocr = new IronTesseract();
        using var input = new OcrInput();
        input.LoadImage(imagePath);

        var result = ocr.Read(input);
        var wordLocations = new List<WordLocation>();

        foreach (var page in result.Pages)
        {
            foreach (var word in page.Words)
            {
                wordLocations.Add(new WordLocation
                {
                    Text = word.Text,
                    Confidence = word.Confidence,
                    X = word.X,
                    Y = word.Y,
                    Width = word.Width,
                    Height = word.Height
                });
            }
        }

        return wordLocations;
    }

    public FormData ParseStructuredForm(string imagePath)
    {
        var ocr = new IronTesseract();
        using var input = new OcrInput();
        input.LoadImage(imagePath);
        input.Deskew();

        var result = ocr.Read(input);
        var form = new FormData();

        foreach (var page in result.Pages)
        {
            foreach (var paragraph in page.Paragraphs)
            {
                // Use Y coordinate to identify form regions
                if (paragraph.Y < 200)
                    form.HeaderText += paragraph.Text + " ";
                else if (paragraph.Y > 800)
                    form.FooterText += paragraph.Text + " ";
                else
                    form.BodyLines.Add(paragraph.Text);
            }
        }

        form.OverallConfidence = result.Confidence;
        return form;
    }
}

public class WordLocation
{
    public string Text { get; set; }
    public float Confidence { get; set; }
    public int X { get; set; }
    public int Y { get; set; }
    public int Width { get; set; }
    public int Height { get; set; }
}

public class FormData
{
    public string HeaderText { get; set; } = string.Empty;
    public string FooterText { get; set; } = string.Empty;
    public List<string> BodyLines { get; set; } = new();
    public float OverallConfidence { get; set; }
}
C#

As coordenadas das palavras permitem a validação em relação a modelos de formulário conhecidos, a sinalização baseada em nível de confiança para revisão humana e a sobreposição de destaques nas interfaces de visualização de documentos. O guia de resultados estruturados documenta o modelo de objeto completo OcrResult, incluindo acesso a nível de caractere e o guia de pontuações de confiança cobre os padrões de filtragem de confiança por palavra.

Processamento em segundo plano com assincronismo nativo e rastreamento de progresso.

TesseractOcrMaui expõe uma API assíncrona (RecognizeTextAsync), mas apenas dentro do contexto do aplicativo MAUI. Tarefas em lote de longa duração precisam ser executadas em um serviço em segundo plano, Função do Azure ou processo de trabalho — nenhum dos quais oTesseractOcrMauipode utilizar. O IronOCR oferece suporte nativo assíncrono que funciona em qualquer serviço hospedado.

Abordagem TesseractOcrMaui:

// Background processing is impossible with TesseractOcrMaui.
// IHostedService runs in a server context —TesseractOcrMauihas no server target.
// The MAUI async API exists, but there is nowhere to run it outside the MAUI app host.

public class DocumentBatchWorker : BackgroundService
{
    // ITesseract cannot be injected here — no MAUI DI in a hosted service
    // Attempting to referenceTesseractOcrMauiwill fail to compile:
    // error: PackageTesseractOcrMauidoes not support target net8.0
    protected override Task ExecuteAsync(CancellationToken stoppingToken)
    {
        throw new PlatformNotSupportedException(
            "TesseractOcrMaui has no server target. Use a different OCR library.");
    }
}
C#

Abordagem IronOCR:

// IronOCR: hosted service background batch processor
using IronOcr;
using Microsoft.Extensions.Hosting;

public class DocumentBatchWorker : BackgroundService
{
    private readonly ILogger<DocumentBatchWorker> _logger;
    private readonly string _inputFolder;
    private readonly string _outputFolder;

    public DocumentBatchWorker(ILogger<DocumentBatchWorker> logger, IConfiguration config)
    {
        _logger = logger;
        _inputFolder = config["Ocr:InputFolder"];
        _outputFolder = config["Ocr:OutputFolder"];
    }

    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        while (!stoppingToken.IsCancellationRequested)
        {
            var pendingFiles = Directory.GetFiles(_inputFolder, "*.pdf")
                .Concat(Directory.GetFiles(_inputFolder, "*.jpg"))
                .ToList();

            if (pendingFiles.Count > 0)
            {
                _logger.LogInformation("Processing {Count} documents.", pendingFiles.Count);

                // Thread-safe parallel processing — one IronTesseract per thread
                await Parallel.ForEachAsync(pendingFiles,
                    new ParallelOptions { MaxDegreeOfParallelism = 4, CancellationToken = stoppingToken },
                    async (filePath, ct) =>
                    {
                        await ProcessDocumentAsync(filePath, ct);
                    });
            }

            await Task.Delay(TimeSpan.FromSeconds(30), stoppingToken);
        }
    }

    private async Task ProcessDocumentAsync(string filePath, CancellationToken ct)
    {
        try
        {
            var ocr = new IronTesseract();
            using var input = new OcrInput();

            if (Path.GetExtension(filePath).Equals(".pdf", StringComparison.OrdinalIgnoreCase))
                input.LoadPdf(filePath);
            else
                input.LoadImage(filePath);

            input.Deskew();
            input.DeNoise();

            var result = await Task.Run(() => ocr.Read(input), ct);

            // Produce searchable PDF from the same OCR pass
            var outputPath = Path.Combine(_outputFolder,
                Path.GetFileNameWithoutExtension(filePath) + "_searchable.pdf");
            result.SaveAsSearchablePdf(outputPath);

            File.Delete(filePath); // move from input queue
            _logger.LogInformation("Processed {File}: {Confidence:F1}% confidence.", filePath, result.Confidence);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Failed to process {File}.", filePath);
        }
    }
}
C#

O trabalhador se registra em Program.cs com builder.Services.AddHostedService<DocumentBatchWorker>() e roda em qualquer host .NET 8 — Serviço do Windows, unidade systemd do Linux, contêiner Docker ou Aplicativo de Contêiner do Azure. O guia assíncrono de OCR cobre padrões assíncronos e o guia de PDF pesquisável documenta as opções de saída SaveAsSearchablePdf.

Referência de mapeamento da APITesseractOcrMauipara o IronOCR

TesseractOcrMauiEquivalente de IronOCR
dotnet add package TesseractOcrMauidotnet add package IronOcr
builder.Services.AddTesseractOcr()Remover completamente — sem necessidade de cadastro
ITesseract (injetado)new IronTesseract() (instanciação direta)
_tesseract.InitAsync("eng")ocr.Language = OcrLanguage.English; (ou omitir para inglês padrão)
_tesseract.RecognizeTextAsync(imagePath)ocr.Read(input)
result.RecognizedTextresult.Text
result.SuccessBaseado em exceções; nenhuma flag booleana
result.Statuscatch (Exception ex) mensagem
result.Confidenceresult.Confidence (também por palavra)
TesseractOcrMaui.Results.RecognitionResultIronOcr.OcrResult
<MauiAsset> pacote traineddatadotnet add package IronOcr.Languages.French
Resources/Raw/tessdata/eng.traineddataRemover — os dados de idioma estão dentro do pacote NuGet
FileSystem.OpenAppPackageFileAsync() (para traineddata)Remover — não é necessário
Sem suporte para PDFinput.LoadPdf(path) ou input.LoadPdf(stream)
Sem pré-processamentoinput.Deskew(), input.DeNoise(), input.Binarize(), input.Contrast()
Não há saída em PDF pesquisável.result.SaveAsSearchablePdf(outputPath)
Sem coordenadas de palavrasresult.Pages[0].Words[i].X, .Y, .Width, .Height
Sem confiança por palavraresult.Pages[0].Words[i].Confidence
net8.0-ios apenas alvonet8.0 + IronOcr.iOS pacote
net8.0-android apenas alvonet8.0 + IronOcr.Android pacote

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

Problema 1: AddTesseractOcr não pode ser removido sem quebrar as classes dependentes.

TesseractOcrMaui: Toda classe que realiza OCR recebe ITesseract através da injeção de construtor. Removendo AddTesseractOcr() imediatamente quebra esses construtores com uma exceção de resolução de ID.

Solução: Remova o parâmetro do construtor e substitua-o por uma instanciação IronTesseract direta. Se o projeto usar um contêiner de ID e você quiser manter o padrão injetável, registre IronTesseract manualmente:

// Option A: Direct instantiation (recommended for most cases)
public class ScanPageViewModel
{
    public string ScanDocument(string imagePath)
    {
        var ocr = new IronTesseract();
        using var input = new OcrInput();
        input.LoadImage(imagePath);
        return ocr.Read(input).Text;
    }
}

// Option B: Register IronTesseract in DI if your architecture requires it
// In MauiProgram.cs or Program.cs:
builder.Services.AddSingleton<IronTesseract>();

// Then inject normally:
public class ScanPageViewModel
{
    private readonly IronTesseract _ocr;
    public ScanPageViewModel(IronTesseract ocr) { _ocr = ocr; }

    public string ScanDocument(string imagePath)
    {
        using var input = new OcrInput();
        input.LoadImage(imagePath);
        return _ocr.Read(input).Text;
    }
}
C#

Problema 2: Arquivos Traineddata ausentes após a remoção do pacote

TesseractOcrMaui: A pasta Resources/Raw/tessdata/, os arquivos .traineddata dentro dela e as declarações <MauiAsset> no .csproj precisam ser removidas. Deixá-los assim causa avisos de compilação e aumenta o tamanho do pacote do aplicativo com arquivos não utilizados.

Solução: Exclua a pasta tessdata, remova as entradas <MauiAsset> e desinstale qualquer idioma que foi baixado manualmente. Instale o pacote de idiomas equivalente do IronOCR:

# Delete traineddata assets
rm -rf Resources/Raw/tessdata

# Remove from .csproj (delete the MauiAsset ItemGroup):
# <ItemGroup>
#   <MauiAsset Include="Resources\Raw\tessdata\*.traineddata" />
# </ItemGroup>

# Install IronOCR language pack (if non-English language was needed)
dotnet add package IronOcr.Languages.French
dotnet add package IronOcr.Languages.German
SHELL

Os pacotes de idiomas do IronOCR são resolvidos durante a compilação e agrupados sem qualquer gerenciamento manual de arquivos. O guia de vários idiomas documenta todos os pacotes disponíveis e a configuração simultânea em vários idiomas.

Problema 3: InitAsync deve ser chamado antes de cada RecognizeTextAsync.

TesseractOcrMaui: A chamada ITesseract.InitAsync(language) deve preceder toda chamada RecognizeTextAsync. As equipes geralmente adicionam sinalizadores de proteção _isInitialized, travamento verificado duas vezes ou semáforos para evitar inicialização repetida. Todo esse código se torna código morto após a migração.

Solução: IronTesseract não tem etapa de inicialização. O idioma é definido uma vez na instância. Remova todas as chamadas InitAsync, todos os sinalizadores _isInitialized e toda a lógica de proteção de inicialização:

// Before: initialization guard required before every OCR call
private bool _isInitialized = false;
private readonly SemaphoreSlim _initLock = new SemaphoreSlim(1, 1);

public async Task<string> GetTextAsync(string imagePath)
{
    await _initLock.WaitAsync();
    try
    {
        if (!_isInitialized)
        {
            await _tesseract.InitAsync("eng");
            _isInitialized = true;
        }
    }
    finally { _initLock.Release(); }

    var result = await _tesseract.RecognizeTextAsync(imagePath);
    return result.RecognizedText ?? string.Empty;
}

// After: no initialization, no guard, no semaphore
public string GetText(string imagePath)
{
    var ocr = new IronTesseract();
    using var input = new OcrInput();
    input.LoadImage(imagePath);
    return ocr.Read(input).Text;
}
C#

Problema 4: O padrão de verificação result.Success deve ser substituído.

TesseractOcrMaui: O valor de retorno RecognizeTextAsync carrega um booleano Success e uma string Status. Código que verifica if (!result.Success) e lê result.Status para informações de erro precisa ser reescrito.

Solução: O IronOCR utiliza a semântica de exceção padrão do .NET . Substitua as verificações de flag de sucesso por blocos try/catch. Em caso de sucesso, .Text está sempre preenchido (string vazia se nenhum texto foi encontrado):

// Before: success-flag pattern
var result = await _tesseract.RecognizeTextAsync(imagePath);
if (!result.Success)
{
    logger.LogError("OCR failed: {Status}", result.Status);
    return string.Empty;
}
return result.RecognizedText ?? string.Empty;

// After: exception pattern
try
{
    var ocr = new IronTesseract();
    using var input = new OcrInput();
    input.LoadImage(imagePath);
    var result = ocr.Read(input);
    return result.Text; // empty string if no text found — never null
}
catch (Exception ex)
{
    logger.LogError(ex, "OCR failed for {Path}.", imagePath);
    return string.Empty;
}
C#

Problema 5: Framework de destino exclusivo para MAUI em projetos de biblioteca compartilhada

TesseractOcrMaui: Uma biblioteca de classes que referencia TesseractOcrMaui automaticamente herda sua restrição de plataforma. A <TargetFramework> da biblioteca deve ser definida para um apelido de MAUI (net8.0-android, net8.0-ios ou net8.0-windows), o que o impede de ser referenciado por projetos de servidor.

Solução: Altere o alvo da biblioteca de classes para net8.0 ou netstandard2.1 e referencie IronOcr em vez disso. A biblioteca agora é resolvida corretamente a partir de qualquer projeto que a utilize:

<!-- Before: locked to MAUI target becauseTesseractOcrMauihas no net8.0 target -->
<TargetFramework>net8.0-android</TargetFramework>
<PackageReference Include="TesseractOcrMaui" Version="*" />

<!-- After: universal target — referenced from MAUI, API, worker, and Functions -->
<TargetFramework>net8.0</TargetFramework>
<PackageReference Include="IronOcr" Version="*" />
XML

Problema 6: O processamento de PDF requer a remoção de uma segunda biblioteca.

TesseractOcrMaui: Equipes que implementaram suporte a PDF adicionaram uma segunda biblioteca (PDFium, PdfPig ou um renderizador em nuvem) para converter páginas de PDF em imagens antes de passá-las para RecognizeTextAsync. Após a migração para o IronOCR, essa segunda biblioteca e todo o seu código de renderização de páginas podem ser excluídos.

Solução: Remova a biblioteca de renderização de PDF e substitua todo o pipeline de extração de páginas com input.LoadPdf():

// Before: PDF library + manual temp file management (50+ lines)
using var pdfDoc = PdfDocument.Open(pdfPath);
var results = new List<string>();
foreach (var page in pdfDoc.GetPages())
{
    var tempImagePath = Path.Combine(FileSystem.CacheDirectory, $"page_{page.Number}.png");
    RenderPageToImage(page, tempImagePath, dpi: 300);
    await _tesseract.InitAsync("eng");
    var r = await _tesseract.RecognizeTextAsync(tempImagePath);
    results.Add(r.RecognizedText ?? string.Empty);
    File.Delete(tempImagePath);
}
return string.Join("\n", results);

// After: native PDF support — 5 lines
var ocr = new IronTesseract();
using var input = new OcrInput();
input.LoadPdf(pdfPath);
var result = ocr.Read(input);
return result.Text;
C#

O guia de entrada de PDF abrange a seleção de intervalo de páginas, PDFs protegidos por senha e carregamento baseado em fluxo.

Lista de verificação de migração TesseractOcrMaui

Pré-migração

Antes de alterar qualquer código, faça uma auditoria no código-fonte para inventariar todo o uso de TesseractOcrMaui:

# Find all files that referenceTesseractOcrMauinamespaces
grep -r "TesseractOcrMaui" --include="*.cs" .

# Find all ITesseract injection points
grep -r "ITesseract" --include="*.cs" .

# Find all AddTesseractOcr registrations
grep -r "AddTesseractOcr" --include="*.cs" .

# Find all InitAsync calls
grep -r "InitAsync" --include="*.cs" .

# Find all RecognizeTextAsync calls
grep -r "RecognizeTextAsync" --include="*.cs" .

# Find traineddata asset declarations in project files
grep -r "tessdata" --include="*.csproj" .

# Find MauiAsset traineddata declarations
grep -r "MauiAsset" --include="*.csproj" .

# Identify projects with MAUI-only target frameworks that hold OCR logic
grep -r "net8.0-android\|net8.0-ios\|net8.0-windows" --include="*.csproj" .
SHELL

Observe toda classe que toma ITesseract em um construtor — esses construtores irão mudar. Observe todo arquivo de projeto que declara <MauiAsset> para traineddata — essas declarações serão excluídas. Identifique se existe uma biblioteca de renderização de PDF e se ela é usada exclusivamente para o pré-processamento de OCR.

Migração de código

  1. Execute dotnet remove package TesseractOcrMaui em todo projeto que o referencia
  2. Execute dotnet add package IronOcr em todo projeto que realizará OCR
  3. Execute dotnet add package IronOcr.Android em projetos MAUI visando Android
  4. Execute dotnet add package IronOcr.iOS em projetos MAUI visando iOS
  5. Execute dotnet add package IronOcr.Languages.* para qualquer idioma não inglês anteriormente agrupado como traineddata
  6. Adicione IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY"; na inicialização do aplicativo em cada projeto de ponto de entrada
  7. Exclua Resources/Raw/tessdata/ e todos os arquivos .traineddata de projetos MAUI
  8. Remova todas as linhas <MauiAsset Include="Resources\Raw\tessdata\*.traineddata" /> dos arquivos .csproj
  9. Remova builder.Services.AddTesseractOcr() de todos os arquivos MauiProgram.cs
  10. Substitua todos using TesseractOcrMaui; e using TesseractOcrMaui.Results; por using IronOcr;
  11. Remova parâmetros de construtor ITesseract de todas as classes de serviço e modelo de visualização
  12. Substitua chamadas await _tesseract.InitAsync("eng") por ocr.Language = OcrLanguage.English;, se necessário (o padrão é o inglês)
  13. Substitua await _tesseract.RecognizeTextAsync(imagePath) por ocr.Read(input) usando uma instância OcrInput
  14. Substitua result.RecognizedText por result.Text
  15. Substitua verificações if (!result.Success) por blocos try/catch
  16. Se uma biblioteca de renderização de PDF foi adicionada apenas para dar suporte ao TesseractOcrMaui, remova-a e substitua o código de extração de páginas por input.LoadPdf()
  17. Altere qualquer estrutura de destino apenas para MAUI em bibliotecas de classes que mantinham lógica de OCR para net8.0 ou netstandard2.1

Pós-migração

  • Verificar se o OCR gera texto a partir de uma imagem JPEG capturada pela câmera do dispositivo, tanto em sistemas iOS quanto Android.
  • Verifique se o OCR produz texto da mesma imagem carregada via byte[] no endpoint da API do lado do servidor
  • Confirme se a biblioteca de classes compartilhada compila e executa de forma idêntica quando referenciada tanto em projetos MAUI quanto em projetos ASP.NET Core.
  • Teste se a entrada de PDF funciona de ponta a ponta sem a criação de arquivos temporários.
  • Verifique se a saída SaveAsSearchablePdf é indexável em um visualizador de PDF
  • Confirme se as pontuações de confiança estão presentes em result.Confidence e em page.Words[i].Confidence
  • Teste se o aplicativo MAUI gera um log de inicialização sem erros e sem exceções de arquivo "traineddata" não encontrado.
  • Verifique se a pasta Resources/Raw/tessdata/ está ausente do pacote do aplicativo MAUI em compilações de release
  • Execute um trabalho em lote paralelo com 10 ou mais documentos para confirmar a segurança de threads.
  • Confirme que a remoção de InitAsync não deixou semáforos órfãos ou variáveis de estado _isInitialized em nenhuma classe de serviço

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

Uma base de código em todo o produto. Após a migração, todos os projetos na solução — aplicativo móvel MAUI, API ASP.NET Core, Função do Azure, trabalhador em segundo plano — chamam a mesma classe DocumentOcrService da mesma biblioteca compartilhada. A configuração do idioma, as configurações de pré-processamento e o ajuste de precisão são feitos em um único local. Quando um novo tipo de documento exige um novo filtro de pré-processamento, a alteração é feita uma única vez e entra em vigor em todos os lugares.

Implantação no servidor sem reescrita. O IronOCR pode ser implantado em contêineres Linux, Windows Server, Azure App Service,AWS Lambdae qualquer outro ambiente de execução .NET 8 sem modificações. A mesma instância IronTesseract que processa capturas de câmera móvel processa uploads de PDF do lado do servidor. O guia de implantação do Azure e o guia de implantação da AWS documentam as etapas de configuração específicas da plataforma.

Processamento de PDF sem segunda biblioteca. A entrada de PDF nativa através de input.LoadPdf() elimina a biblioteca de renderização de PDF, o loop de extração de imagens página por página, o gerenciamento de arquivos temporários e o código de limpeza que a arquitetura doTesseractOcrMauirequereu. Contratos de PDF digitalizados, faturas e documentos de identidade são carregados em uma linha. A mesma passagem de OCR que extrai texto pode produzir um PDF pesquisável com result.SaveAsSearchablePdf() — uma capacidade que oTesseractOcrMauinão pode fornecer em nenhum nível.

Pré-processamento que lida com imagens móveis reais. input.Deskew(), input.DeNoise(), input.Binarize() e input.Sharpen() são chamadas de método único que aplicam correções de imagem calibradas antes que o mecanismo Tesseract veja os dados. Equipes que aceitavam uma precisão de 40 a 60% em capturas de imagens móveis com pouca luz, sem pré-processamento, agora observam uma precisão de 85 a 90% ou mais após a adição de um pipeline com três filtros. Sem necessidade de SkiaSharp, ImageSharp ou implementação de algoritmos. O guia de correção da qualidade da imagem documenta todos os filtros disponíveis e quando aplicá-los.

Suporte comercial com um caminho de escalonamento definido. A Iron Software oferece suporte por e-mail para todos os níveis de licença do IronOCR e suporte prioritário por telefone e chat nos níveis Professional e Enterprise . Quando uma atualização da plataforma quebra a resolução de bibliotecas nativas em um nível específico da API do Android — o tipo de falha que a fila de problemas do GitHub doTesseractOcrMauiresolve com trabalho voluntário — existe uma equipe de engenharia real com a obrigação de dar uma resposta. O licenciamento perpétuo começa em $999 para o nível Lite; A página de licenciamento lista todos os níveis e os respectivos níveis de suporte incluídos.

Mais de 125 idiomas disponíveis via NuGet sem aumentar o tamanho do pacote do aplicativo. OTesseractOcrMauiinclui os arquivos traineddata dentro do aplicativo MAUI — cada idioma adiciona de 10 a 50 MB ao tamanho do download do aplicativo. Os pacotes de idiomas do IronOCR são instalados via NuGet e incluídos apenas em builds do lado do servidor ou em builds da plataforma onde são explicitamente referenciados. Os pacotes de aplicativos móveis permanecem enxutos; As compilações do lado do servidor recebem o conjunto completo de idiomas. Adicionar um novo idioma é um comando dotnet add package sem alterações no arquivo do projeto e sem gerenciamento de arquivos. O catálogo completo de idiomas lista todos os mais de 125 pacotes disponíveis.

Observe: PDFium, PdfPig, e Tesseract são marcas registradas de seus respectivos proprietários. Este site não é afiliado, endossado ou patrocinado pelo Chromium Project, Google, ou UglyToad. Todos os nomes de produtos, logotipos e marcas são propriedade de seus respectivos proprietários. As comparações são apenas para fins informativos e refletem informações disponíveis publicamente no momento da redação.

Artigos relacionados

Key in blue circle

Obtenha sua chave de avaliação gratuita de 30 dias instantaneamente.

Your trial license will be sent to your email address

Sem limitações. 100% desbloqueado. Sem cartão de crédito.

bullet_checkedNão é necessário cartão de crédito nem criação de conta.Sem limitações. 100% desbloqueado. Sem cartão de crédito.
  • Logo Aetna
  • Logo NASA
  • Logo GE
  • Logo Porsche
  • Logo USDA
  • Logo Qatar
Join Millions of Engineers who’ve tried IronPDF
Agende sua consulta sem compromisso.
Preencha o formulário abaixo ou envie um e-mail para sales@ironsoftware.com
Os seus dados serão sempre mantidos em sigilo.
Aprovado por milhões de engenheiros em todo o mundo.
Logotipos dos clientes da Iron Software
Obtenha sua chave de avaliação gratuita de 30 dias instantaneamente.
Não é necessário cartão de crédito nem criação de conta.