Ir para o conteúdo do rodapé
COMPARAR COM OUTROS COMPONENTES

Uma comparação entre IronOCR e Nanonets OCR

O modelo de preços por página doAWS Textractpode parecer barato em baixo volume, mas os custos se acumulam indefinidamente em escala. Cada documento processado pelo seu aplicativo sai da sua rede, é enviado para um data center Amazon, é processado pela infraestrutura Amazon, e a conta se acumula indefinidamente. Para equipes que avaliam opções de OCR em .NET, a questão não é apenas se o Textract produz resultados precisos — ele produz —, mas se o modelo de custo por página, a transmissão obrigatória para a nuvem e a arquitetura de polling assíncrono para documentos com várias páginas correspondem ao que sua aplicação realmente precisa.

Entendendo o AWS Textract

AWS Textract é o serviço gerenciado de análise de documentos da Amazon, acessível via o AWS SDK for .NET através do pacote NuGet AWSSDK.Textract. Funciona como uma API em nuvem: seu aplicativo envia dados de documentos para a infraestrutura da Amazon e recebe resultados estruturados. O serviço requer uma conta AWS, credenciais IAM com permissões Textract e uma conexão com a internet para cada operação de OCR.

O Textract oferece diversos modos de análise distintos, cada um com preço separado:

  • DetectDocumentText: Extração de texto básico (veja preços AWS Textract para tarifas atuais por página)
  • AnalyzeDocument (Tables): Extração de tabelas estruturadas a uma tarifa maior por página do que texto básico
  • AnalyzeDocument (Forms): Extração de formulários de chave-valor a uma tarifa maior por página do que extração de tabelas
  • AnalyzeExpense: Análise de faturas e recibos a US$ 0,01 por página
  • AnalyzeID: Extração de documentos de identidade a US$ 0,025 por página
  • StartDocumentTextDetection / StartDocumentAnalysis: API assíncrona necessária para qualquer PDF com várias páginas, exigindo um bucket de preparação no S3, polling de tarefas e paginação de resultados.

O modelo de resultado usa uma lista plana de objetos Block com IDs de relacionamento que devem ser percorridos para reconstruir tabelas, formulários ou qualquer saída estruturada. Uma extração de tabela simples requer iterar blocos BlockType.TABLE, encontrando blocos filhos BlockType.CELL via IDs de relacionamento RelationshipType.CHILD, e depois buscar blocos BlockType.WORD para o texto de cada célula. Este modelo de grafo de relacionamento lida com estruturas de documentos complexas, mas não é leve.

O Pipeline S3-Assíncrono

OCR de imagem única via DetectDocumentTextAsync pode passar bytes do documento diretamente na solicitação. PDFs de várias páginas não. Qualquer PDF requer o pipeline assíncrono completo:

// AWS Textract: PDF com várias páginas requires S3 + async job
public async Task<string> ProcessPdfAsync(string pdfPath)
{
    // Step 1: Upload to S3 — credentials for two services required
    var key = $"uploads/{Guid.NewGuid()}.pdf";
    using (var fileStream = File.OpenRead(pdfPath))
    {
        await _s3Client.PutObjectAsync(new PutObjectRequest
        {
            BucketName = _bucketName,
            Key = key,
            InputStream = fileStream
        });
    }

    try
    {
        // Step 2: Start async Textract job
        var startResponse = await _textractClient.StartDocumentTextDetectionAsync(
            new StartDocumentTextDetectionRequest
            {
                DocumentLocation = new DocumentLocation
                {
                    S3Object = new S3Object { Bucket = _bucketName, Name = key }
                }
            });

        var jobId = startResponse.JobId;

        // Step 3: Poll every 5 seconds until complete
        GetDocumentTextDetectionResponse getResponse;
        do
        {
            await Task.Delay(5000);
            getResponse = await _textractClient.GetDocumentTextDetectionAsync(
                new GetDocumentTextDetectionRequest { JobId = jobId });
        } while (getResponse.JobStatus == JobStatus.IN_PROGRESS);

        if (getResponse.JobStatus != JobStatus.SUCCEEDED)
            throw new Exception($"Textract job failed: {getResponse.StatusMessage}");

        // Step 4: Paginate through result blocks
        var allText = new StringBuilder();
        string nextToken = null;
        do
        {
            var pageResponse = await _textractClient.GetDocumentTextDetectionAsync(
                new GetDocumentTextDetectionRequest
                {
                    JobId = jobId,
                    NextToken = nextToken
                });

            foreach (var block in pageResponse.Blocks.Where(b => b.BlockType == BlockType.LINE))
                allText.AppendLine(block.Text);

            nextToken = pageResponse.NextToken;
        } while (nextToken != null);

        return allText.ToString();
    }
    finally
    {
        // Step 5: Sempre clean up S3
        await _s3Client.DeleteObjectAsync(_bucketName, key);
    }
}
// AWS Textract: PDF com várias páginas requires S3 + async job
public async Task<string> ProcessPdfAsync(string pdfPath)
{
    // Step 1: Upload to S3 — credentials for two services required
    var key = $"uploads/{Guid.NewGuid()}.pdf";
    using (var fileStream = File.OpenRead(pdfPath))
    {
        await _s3Client.PutObjectAsync(new PutObjectRequest
        {
            BucketName = _bucketName,
            Key = key,
            InputStream = fileStream
        });
    }

    try
    {
        // Step 2: Start async Textract job
        var startResponse = await _textractClient.StartDocumentTextDetectionAsync(
            new StartDocumentTextDetectionRequest
            {
                DocumentLocation = new DocumentLocation
                {
                    S3Object = new S3Object { Bucket = _bucketName, Name = key }
                }
            });

        var jobId = startResponse.JobId;

        // Step 3: Poll every 5 seconds until complete
        GetDocumentTextDetectionResponse getResponse;
        do
        {
            await Task.Delay(5000);
            getResponse = await _textractClient.GetDocumentTextDetectionAsync(
                new GetDocumentTextDetectionRequest { JobId = jobId });
        } while (getResponse.JobStatus == JobStatus.IN_PROGRESS);

        if (getResponse.JobStatus != JobStatus.SUCCEEDED)
            throw new Exception($"Textract job failed: {getResponse.StatusMessage}");

        // Step 4: Paginate through result blocks
        var allText = new StringBuilder();
        string nextToken = null;
        do
        {
            var pageResponse = await _textractClient.GetDocumentTextDetectionAsync(
                new GetDocumentTextDetectionRequest
                {
                    JobId = jobId,
                    NextToken = nextToken
                });

            foreach (var block in pageResponse.Blocks.Where(b => b.BlockType == BlockType.LINE))
                allText.AppendLine(block.Text);

            nextToken = pageResponse.NextToken;
        } while (nextToken != null);

        return allText.ToString();
    }
    finally
    {
        // Step 5: Sempre clean up S3
        await _s3Client.DeleteObjectAsync(_bucketName, key);
    }
}
Imports System
Imports System.IO
Imports System.Text
Imports System.Threading.Tasks
Imports Amazon.S3
Imports Amazon.Textract
Imports Amazon.Textract.Model

Public Class TextractProcessor
    Private _s3Client As IAmazonS3
    Private _textractClient As IAmazonTextract
    Private _bucketName As String

    Public Async Function ProcessPdfAsync(pdfPath As String) As Task(Of String)
        ' Step 1: Upload to S3 — credentials for two services required
        Dim key As String = $"uploads/{Guid.NewGuid()}.pdf"
        Using fileStream As FileStream = File.OpenRead(pdfPath)
            Await _s3Client.PutObjectAsync(New PutObjectRequest With {
                .BucketName = _bucketName,
                .Key = key,
                .InputStream = fileStream
            })
        End Using

        Try
            ' Step 2: Start async Textract job
            Dim startResponse = Await _textractClient.StartDocumentTextDetectionAsync(
                New StartDocumentTextDetectionRequest With {
                    .DocumentLocation = New DocumentLocation With {
                        .S3Object = New S3Object With {.Bucket = _bucketName, .Name = key}
                    }
                })

            Dim jobId As String = startResponse.JobId

            ' Step 3: Poll every 5 seconds until complete
            Dim getResponse As GetDocumentTextDetectionResponse
            Do
                Await Task.Delay(5000)
                getResponse = Await _textractClient.GetDocumentTextDetectionAsync(
                    New GetDocumentTextDetectionRequest With {.JobId = jobId})
            Loop While getResponse.JobStatus = JobStatus.IN_PROGRESS

            If getResponse.JobStatus <> JobStatus.SUCCEEDED Then
                Throw New Exception($"Textract job failed: {getResponse.StatusMessage}")
            End If

            ' Step 4: Paginate through result blocks
            Dim allText As New StringBuilder()
            Dim nextToken As String = Nothing
            Do
                Dim pageResponse = Await _textractClient.GetDocumentTextDetectionAsync(
                    New GetDocumentTextDetectionRequest With {
                        .JobId = jobId,
                        .NextToken = nextToken
                    })

                For Each block In pageResponse.Blocks.Where(Function(b) b.BlockType = BlockType.LINE)
                    allText.AppendLine(block.Text)
                Next

                nextToken = pageResponse.NextToken
            Loop While nextToken IsNot Nothing

            Return allText.ToString()
        Finally
            ' Step 5: Always clean up S3
            Await _s3Client.DeleteObjectAsync(_bucketName, key)
        End Try
    End Function
End Class
$vbLabelText   $csharpLabel

Esta é a implementação mínima viável para um processamento confiável de PDF — cinco fases distintas, dois clientes de serviço AWS e lógica de limpeza em um bloco finally. A versão completa de produção, com tratamento de erros adequado, lógica de repetição com limite de taxa e gerenciamento de tempo limite, possui entre 150 e 300 linhas de código.

Entendendo o IronOCR

IronOCR é uma biblioteca OCR comercial para .NET que funciona inteiramente na sua infraestrutura. Ele integra um mecanismo Tesseract 5 otimizado com pré-processamento automático de imagens, suporte nativo a PDF e uma API síncrona que produz resultados diretamente, sem chamadas a serviços externos ou etapas de preparação.

Principais características da arquitetura IronOCR:

  • Processamento local apenas: nenhum dado do documento sai da máquina que executa seu aplicativo.
  • Pacote NuGet único: dotnet add package IronOcr instala tudo, incluindo binários nativos
  • Pré-processamento automático: Correção de distorção, redução de ruído, aprimoramento de contraste, binarização e ajuste de resolução ocorrem automaticamente em entradas de baixa qualidade.
  • Suporte nativo a PDF: Lê PDFs diretamente pelo caminho do arquivo ou fluxo, sem necessidade de armazenamento temporário no S3 ou tarefas assíncronas.
  • Seguro para threads: Uma única instância IronTesseract lida com solicitações simultâneas através de threads sem contenção
  • Licenciamento perpétuo: $999 Lite / $1,499 Plus / $2,999 Professional / $5,999 Unlimited — um pagamento, sem cobranças por página, sem medições de uso
  • Mais de 125 pacotes de idiomas: instalados como pacotes NuGet separados, carregados localmente, sem chamadas de rede.

Comparação de recursos

Recurso AWS Textract IronOCR
Local de processamento Nuvem da Amazon (obrigatório) Local / no local
PDF com várias páginas Requer S3 + tarefa assíncrona Chamada síncrona direta
Modelo de custo Por página (contate AWS para preços atuais) Licença perpétua, sem taxa por página.
É necessário ter acesso à internet. Sempre Nunca
Configuração de credenciais Usuário/função do IAM + S3 opcional string de chave de licença única
Implantação isolada da internet Não é possível. Suporte completo
Suporte para PDF criptografado Não suportado Integrado (parâmetro de senha)

Comparação Detalhada de Recursos

Recurso AWS Textract IronOCR
Extração de texto
OCR básico (imagens) Sim — DetectDocumentTextAsync Sim — ocr.Read(path)
PDF com várias páginas Requer S3 + polling assíncrono Direto input.LoadPdf(path)
PDF protegido por senha Não suportado input.LoadPdf(path, Password: "x")
Entrada de fluxo Sim (matriz de bytes na solicitação) Sim — input.LoadImage(stream)
Extração Estruturada
Extração de tabela AnalyzeDocument + percurso gráfico de bloco Reconstrução baseada na posição das palavras
Extração de campos de formulário AnalyzeDocument + blocos KEY_VALUE_SET Zonas baseadas em região CropRectangle
Resultados por linha Block filtrando por BlockType.LINE Coleta direta result.Lines
Nível de palavra com coordenadas Block filtrando por BlockType.WORD result.Words com .X, .Y, .Width
Pontuações de confiança Confiança por bloco Por palavra e geral result.Confidence
Modelo de Processamento
Síncrono (imagens) Sim (apenas uma página) Sim (todos os tipos de documento)
Assíncrono Necessário para PDFs Opcional — Task.Run() wrapper
Processamento em lote Requer gerenciamento de limite de taxa (5 TPS por padrão) Parallel.ForEach sem restrições
Pré-processamento
Desalinhamento automático Não exposto input.Deskew()
Remoção de ruído Interno (não configurável) input.DeNoise()
Aprimoramento de contraste Interno (não configurável) input.Contrast()
Melhoria de resolução Interno (não configurável) input.EnhanceResolution(300)
Binarização Interno input.Binarize()
Formatos de saída
Texto simples Sim Sim
PDF pesquisável Não result.SaveAsSearchablePdf(path)
hOCR Não result.SaveAsHocrFile(path)
JSON estruturado Por meio de serialização em bloco result.Words / result.Lines
Implantação
No local Não Sim
Com espaço de ar Não Sim
Docker Sim (com credenciais da AWS inseridas) Sim (não são necessárias credenciais)
AWS Lambda Nativo Apoiado
Azure Sim Sim
Linux Sim (gerenciado pela AWS) Sim — get-started/linux/
Conformidade
HIPAA Requer BAA com a AWS. Sem processador externo
RGPD Os dados são transferidos para regiões da AWS. Os dados permanecem dentro dos limites.
ITAR Proibido sem autorização especial. Totalmente no local
Com espaço de ar / CMMC Nível 3 Não é possível. Apoiado

Custo em escala

O modelo de precificação por página é a principal restrição estrutural do AWS Textract. Custos que parecem pequenos por página se acumulam significativamente em um fluxo de trabalho de documento real.

Abordagem AWS Textract

// Every call to this method costs money — per page, permanently
public async Task<string> DetectTextAsync(string imagePath)
{
    var imageBytes = File.ReadAllBytes(imagePath);  // Image leaves your network

    var request = new DetectDocumentTextRequest
    {
        Document = new Document
        {
            Bytes = new MemoryStream(imageBytes)
        }
    };

    var response = await _client.DetectDocumentTextAsync(request);  // per-page charge

    return string.Join("\n", response.Blocks
        .Where(b => b.BlockType == BlockType.LINE)
        .Select(b => b.Text));
}
// Every call to this method costs money — per page, permanently
public async Task<string> DetectTextAsync(string imagePath)
{
    var imageBytes = File.ReadAllBytes(imagePath);  // Image leaves your network

    var request = new DetectDocumentTextRequest
    {
        Document = new Document
        {
            Bytes = new MemoryStream(imageBytes)
        }
    };

    var response = await _client.DetectDocumentTextAsync(request);  // per-page charge

    return string.Join("\n", response.Blocks
        .Where(b => b.BlockType == BlockType.LINE)
        .Select(b => b.Text));
}
Imports System.IO
Imports System.Threading.Tasks

' Every call to this method costs money — per page, permanently
Public Async Function DetectTextAsync(imagePath As String) As Task(Of String)
    Dim imageBytes = File.ReadAllBytes(imagePath)  ' Image leaves your network

    Dim request = New DetectDocumentTextRequest With {
        .Document = New Document With {
            .Bytes = New MemoryStream(imageBytes)
        }
    }

    Dim response = Await _client.DetectDocumentTextAsync(request)  ' per-page charge

    Return String.Join(vbLf, response.Blocks _
        .Where(Function(b) b.BlockType = BlockType.LINE) _
        .Select(Function(b) b.Text))
End Function
$vbLabelText   $csharpLabel

Consulte a página de preços do AWS Textract para tarifas atuais por página. Diferentes recursos da API (detecção básica de texto, extração de tabelas, extração de formulários) têm taxas diferentes. Um documento contendo tabelas e campos de formulário incorreria em cobranças maiores do que a detecção básica de texto, e os custos cresceriam com o volume sem limite superior e sem maneira de pagar adiantado.

Em volumes altos de páginas, o custo total de três anos pode ser substancial, e o medidor continua a correr.

Abordagem IronOCR

// One license. Não per-page cost. Same code handles 1 page or 1,000,000.
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";

var text = new IronTesseract().Read("document.jpg").Text;
// One license. Não per-page cost. Same code handles 1 page or 1,000,000.
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";

var text = new IronTesseract().Read("document.jpg").Text;
Imports IronOcr

' One license. Não per-page cost. Same code handles 1 page or 1,000,000.
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY"

Dim text = New IronTesseract().Read("document.jpg").Text
$vbLabelText   $csharpLabel

A licença $2,999 Professional cobre 10 desenvolvedores, projetos ilimitados e volume de página ilimitado. Após o primeiro ano, o custo contínuo por página processada é zero. Para equipes processando volumes de páginas significativos, a licença IronOCR se paga rapidamente em comparação aos custos crescentes por página na nuvem.

A página de licenciamento do IronOCR aborda detalhes dos níveis de licenciamento, opções de assinatura SaaS para cenários de cobrança baseada no uso e termos de redistribuição para OEMs.

Soberania e Conformidade de Dados

A arquitetura doAWS Textracttorna uma garantia impossível: que seus documentos permaneçam dentro da sua infraestrutura. Cada operação de OCR transmite o conteúdo do documento para os servidores da Amazon.

Abordagem AWS Textract

// This code sends PHI, legal documents, financial records — whatever is in
// the file — to Amazon Web Services infrastructure
public async Task<string> ProcessSensitiveDocumentAsync(string documentPath)
{
    var imageBytes = File.ReadAllBytes(documentPath);

    // Data crosses your security perimeter here
    var request = new DetectDocumentTextRequest
    {
        Document = new Document
        {
            Bytes = new MemoryStream(imageBytes)
        }
    };

    // Amazon processes it; you receive text back
    var response = await _client.DetectDocumentTextAsync(request);

    return string.Join("\n", response.Blocks
        .Where(b => b.BlockType == BlockType.LINE)
        .Select(b => b.Text));
}
// This code sends PHI, legal documents, financial records — whatever is in
// the file — to Amazon Web Services infrastructure
public async Task<string> ProcessSensitiveDocumentAsync(string documentPath)
{
    var imageBytes = File.ReadAllBytes(documentPath);

    // Data crosses your security perimeter here
    var request = new DetectDocumentTextRequest
    {
        Document = new Document
        {
            Bytes = new MemoryStream(imageBytes)
        }
    };

    // Amazon processes it; you receive text back
    var response = await _client.DetectDocumentTextAsync(request);

    return string.Join("\n", response.Blocks
        .Where(b => b.BlockType == BlockType.LINE)
        .Select(b => b.Text));
}
Imports System.IO
Imports System.Threading.Tasks
Imports Amazon.Textract
Imports Amazon.Textract.Model

Public Class DocumentProcessor
    Private _client As AmazonTextractClient

    Public Sub New(client As AmazonTextractClient)
        _client = client
    End Sub

    ' This code sends PHI, legal documents, financial records — whatever is in
    ' the file — to Amazon Web Services infrastructure
    Public Async Function ProcessSensitiveDocumentAsync(documentPath As String) As Task(Of String)
        Dim imageBytes = File.ReadAllBytes(documentPath)

        ' Data crosses your security perimeter here
        Dim request As New DetectDocumentTextRequest With {
            .Document = New Document With {
                .Bytes = New MemoryStream(imageBytes)
            }
        }

        ' Amazon processes it; you receive text back
        Dim response = Await _client.DetectDocumentTextAsync(request)

        Return String.Join(vbLf, response.Blocks _
            .Where(Function(b) b.BlockType = BlockType.LINE) _
            .Select(Function(b) b.Text))
    End Function
End Class
$vbLabelText   $csharpLabel

A AWS oferece um Acordo de Parceiro ComercialHIPAApara entidades abrangidas, e as regiões GovCloud fornecem autorização FedRAMP High. Essas estruturas não alteram a arquitetura fundamental: os documentos saem da sua infraestrutura para cada operação. Para dados técnicos controlados pelo ITAR, isso não é uma nuance de conformidade — é uma proibição. Para cargas de trabalho CMMC Nível 3 com CUI (Informações Não Classificadas Controladas), a transmissão em nuvem requer autorizações específicas que a maioria dos contratados da área de defesa não possui. Para sistemas isolados da internet — redes de pesquisa, ambientes de controle industrial, instalações confidenciais — o Textract simplesmente não está disponível.

AWS Textract está disponível em seis regiões: us-east-1, us-west-2, eu-west-1, eu-west-2, ap-southeast-1 e ap-southeast-2. Organizações com requisitos de residência de dados fora dessas regiões não têm uma opção compatível.

Abordagem IronOCR

// IronOCR: document bytes never leave this process
public string ProcessSensitiveDocument(string documentPath)
{
    // Processes entirely on local hardware — no network call
    var ocr = new IronTesseract();
    return ocr.Read(documentPath).Text;
}
// IronOCR: document bytes never leave this process
public string ProcessSensitiveDocument(string documentPath)
{
    // Processes entirely on local hardware — no network call
    var ocr = new IronTesseract();
    return ocr.Read(documentPath).Text;
}
' IronOCR: document bytes never leave this process
Public Function ProcessSensitiveDocument(documentPath As String) As String
    ' Processes entirely on local hardware — no network call
    Dim ocr As New IronTesseract()
    Return ocr.Read(documentPath).Text
End Function
$vbLabelText   $csharpLabel

Como o IronOCR é executado localmente, ele se integra naturalmente aos fluxos de trabalho da área da saúde que processam informações de saúde protegidas (PHI), aos sistemas de documentos jurídicos que lidam com comunicações privilegiadas, aos aplicativos financeiros que processam imagens de cartões de pagamento e aos sistemas de processamento de informações controladas não classificadas (CUI) de contratados da área de defesa. Não há processador externo para auditar, nenhum BAA para negociar, nenhuma restrição de residência de dados a cumprir. O âmbito de conformidade abrange a infraestrutura da sua própria organização.

Para equipes que implantam na infraestrutura da AWS, mas precisam de processamento local, o IronOCRé executado no AWS EC2 e no Lambda sem qualquer dependência do Textract — o processamento ocorre dentro dos limites da sua própria conta da AWS, em vez do serviço gerenciado da Amazon.

Sondagem assíncrona vs. Processamento síncrono

A divisão arquitetônica entre as APIs síncronas (imagem única) e assíncronas (PDF de várias páginas) do Textract não é um detalhe de API menor. Isso define como os serviços são construídos, como os erros são tratados e o quanto os responsáveis ​​pela manutenção do código precisam ler e analisar.

Abordagem AWS Textract

// Full production-grade async processor for Textract PDF handling
public class TextractAsyncProcessor
{
    private readonly AmazonTextractClient _textractClient;
    private readonly AmazonS3Client _s3Client;
    private readonly string _bucketName;
    private readonly TimeSpan _pollInterval = TimeSpan.FromSeconds(5);
    private readonly TimeSpan _maxWaitTime = TimeSpan.FromMinutes(10);

    public async Task<DocumentResult> ProcessDocumentAsync(
        string localFilePath,
        CancellationToken cancellationToken = default)
    {
        var s3Key = $"textract-uploads/{Guid.NewGuid()}{Path.GetExtension(localFilePath)}";

        try
        {
            // Phase 1: Upload to S3
            await UploadToS3Async(localFilePath, s3Key, cancellationToken);

            // Phase 2: Start Textract job
            var jobId = await StartTextractJobAsync(s3Key, cancellationToken);

            // Phase 3: Poll until complete (up to 10 minutes)
            var pollResult = await PollForCompletionAsync(jobId, cancellationToken);

            if (!pollResult.Success)
                throw new Exception($"Textract job failed: {pollResult.ErrorMessage}");

            // Phase 4: Retrieve paginated results
            return await GetAllResultsAsync(jobId, cancellationToken);
        }
        finally
        {
            // Phase 5: S3 cleanup — must succeed or storage costs accumulate
            await DeleteFromS3Async(s3Key, cancellationToken);
        }
    }

    private async Task<(bool Success, string ErrorMessage)> PollForCompletionAsync(
        string jobId, CancellationToken cancellationToken)
    {
        var startTime = DateTime.UtcNow;
        int pollCount = 0;

        while (DateTime.UtcNow - startTime < _maxWaitTime)
        {
            cancellationToken.ThrowIfCancellationRequested();

            var response = await _textractClient.GetDocumentTextDetectionAsync(
                new GetDocumentTextDetectionRequest { JobId = jobId }, cancellationToken);

            pollCount++;

            switch (response.JobStatus)
            {
                case JobStatus.SUCCEEDED: return (true, null);
                case JobStatus.FAILED: return (false, response.StatusMessage ?? "Unknown error");
                case JobStatus.IN_PROGRESS:
                    await Task.Delay(_pollInterval, cancellationToken);
                    break;
                default:
                    throw new Exception($"Unknown job status: {response.JobStatus}");
            }
        }

        return (false, "Job timed out");
    }
}
// Full production-grade async processor for Textract PDF handling
public class TextractAsyncProcessor
{
    private readonly AmazonTextractClient _textractClient;
    private readonly AmazonS3Client _s3Client;
    private readonly string _bucketName;
    private readonly TimeSpan _pollInterval = TimeSpan.FromSeconds(5);
    private readonly TimeSpan _maxWaitTime = TimeSpan.FromMinutes(10);

    public async Task<DocumentResult> ProcessDocumentAsync(
        string localFilePath,
        CancellationToken cancellationToken = default)
    {
        var s3Key = $"textract-uploads/{Guid.NewGuid()}{Path.GetExtension(localFilePath)}";

        try
        {
            // Phase 1: Upload to S3
            await UploadToS3Async(localFilePath, s3Key, cancellationToken);

            // Phase 2: Start Textract job
            var jobId = await StartTextractJobAsync(s3Key, cancellationToken);

            // Phase 3: Poll until complete (up to 10 minutes)
            var pollResult = await PollForCompletionAsync(jobId, cancellationToken);

            if (!pollResult.Success)
                throw new Exception($"Textract job failed: {pollResult.ErrorMessage}");

            // Phase 4: Retrieve paginated results
            return await GetAllResultsAsync(jobId, cancellationToken);
        }
        finally
        {
            // Phase 5: S3 cleanup — must succeed or storage costs accumulate
            await DeleteFromS3Async(s3Key, cancellationToken);
        }
    }

    private async Task<(bool Success, string ErrorMessage)> PollForCompletionAsync(
        string jobId, CancellationToken cancellationToken)
    {
        var startTime = DateTime.UtcNow;
        int pollCount = 0;

        while (DateTime.UtcNow - startTime < _maxWaitTime)
        {
            cancellationToken.ThrowIfCancellationRequested();

            var response = await _textractClient.GetDocumentTextDetectionAsync(
                new GetDocumentTextDetectionRequest { JobId = jobId }, cancellationToken);

            pollCount++;

            switch (response.JobStatus)
            {
                case JobStatus.SUCCEEDED: return (true, null);
                case JobStatus.FAILED: return (false, response.StatusMessage ?? "Unknown error");
                case JobStatus.IN_PROGRESS:
                    await Task.Delay(_pollInterval, cancellationToken);
                    break;
                default:
                    throw new Exception($"Unknown job status: {response.JobStatus}");
            }
        }

        return (false, "Job timed out");
    }
}
Imports System
Imports System.IO
Imports System.Threading
Imports System.Threading.Tasks
Imports Amazon.Textract
Imports Amazon.S3
Imports Amazon.Textract.Model

' Full production-grade async processor for Textract PDF handling
Public Class TextractAsyncProcessor
    Private ReadOnly _textractClient As AmazonTextractClient
    Private ReadOnly _s3Client As AmazonS3Client
    Private ReadOnly _bucketName As String
    Private ReadOnly _pollInterval As TimeSpan = TimeSpan.FromSeconds(5)
    Private ReadOnly _maxWaitTime As TimeSpan = TimeSpan.FromMinutes(10)

    Public Async Function ProcessDocumentAsync(localFilePath As String, Optional cancellationToken As CancellationToken = Nothing) As Task(Of DocumentResult)
        Dim s3Key = $"textract-uploads/{Guid.NewGuid()}{Path.GetExtension(localFilePath)}"

        Try
            ' Phase 1: Upload to S3
            Await UploadToS3Async(localFilePath, s3Key, cancellationToken)

            ' Phase 2: Start Textract job
            Dim jobId = Await StartTextractJobAsync(s3Key, cancellationToken)

            ' Phase 3: Poll until complete (up to 10 minutes)
            Dim pollResult = Await PollForCompletionAsync(jobId, cancellationToken)

            If Not pollResult.Success Then
                Throw New Exception($"Textract job failed: {pollResult.ErrorMessage}")
            End If

            ' Phase 4: Retrieve paginated results
            Return Await GetAllResultsAsync(jobId, cancellationToken)
        Finally
            ' Phase 5: S3 cleanup — must succeed or storage costs accumulate
            Await DeleteFromS3Async(s3Key, cancellationToken)
        End Try
    End Function

    Private Async Function PollForCompletionAsync(jobId As String, cancellationToken As CancellationToken) As Task(Of (Success As Boolean, ErrorMessage As String))
        Dim startTime = DateTime.UtcNow
        Dim pollCount As Integer = 0

        While DateTime.UtcNow - startTime < _maxWaitTime
            cancellationToken.ThrowIfCancellationRequested()

            Dim response = Await _textractClient.GetDocumentTextDetectionAsync(New GetDocumentTextDetectionRequest With {.JobId = jobId}, cancellationToken)

            pollCount += 1

            Select Case response.JobStatus
                Case JobStatus.SUCCEEDED
                    Return (True, Nothing)
                Case JobStatus.FAILED
                    Return (False, If(response.StatusMessage, "Unknown error"))
                Case JobStatus.IN_PROGRESS
                    Await Task.Delay(_pollInterval, cancellationToken)
                Case Else
                    Throw New Exception($"Unknown job status: {response.JobStatus}")
            End Select
        End While

        Return (False, "Job timed out")
    End Function
End Class
$vbLabelText   $csharpLabel

Isto não é um texto padrão que pode ser gerado e esquecido. Quando uma tarefa do Textract falha durante a execução, a limpeza do S3 ainda precisa ser realizada. Quando uma tarefa expira após 10 minutos, o solicitante precisa de uma mensagem de erro clara. Quando a rede cai durante a sondagem, a estratégia de repetição não deve criar tarefas duplicadas. Cada um desses modos de falha requer tratamento explícito — a estrutura mostrada acima é a implementação mínima responsável.

O processamento em lote adiciona outra camada: o limite padrão de TPS StartDocumentTextDetection do Textract é de 5 solicitações por segundo. Processar 100 documentos exige uma limitação de SemaphoreSlim, um temporizador de reabastecimento de taxa e lógica de repetição para ProvisionedThroughputExceededException.

Abordagem IronOCR

// IronOCR: same synchronous API regardless of document type or size
public string ProcessDocument(string filePath)
{
    using var input = new OcrInput();

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

    return new IronTesseract().Read(input).Text;
}
// IronOCR: same synchronous API regardless of document type or size
public string ProcessDocument(string filePath)
{
    using var input = new OcrInput();

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

    return new IronTesseract().Read(input).Text;
}
Imports System.IO

' IronOCR: same synchronous API regardless of document type or size
Public Function ProcessDocument(filePath As String) As String
    Using input As New OcrInput()
        If Path.GetExtension(filePath).Equals(".pdf", StringComparison.OrdinalIgnoreCase) Then
            input.LoadPdf(filePath)
        Else
            input.LoadImage(filePath)
        End If

        Return New IronTesseract().Read(input).Text
    End Using
End Function
$vbLabelText   $csharpLabel

Não há loop de polling, rastreamento de ID de tarefa, bucket S3 ou paginação de resultados. O mesmo código processa tanto um único arquivo JPEG quanto um PDF de 200 páginas. O processamento é concluído ou rejeitado — não há estado intermediário "em andamento" para gerenciar. Para processamento em lote, IronOCR é seguro para threads e uma única instância IronTesseract lida com Parallel.ForEach sem bloqueios ou semáforos.

O guia de configuração do IronTesseract aborda a configuração, e o guia de entrada de PDF documenta a seleção de intervalo de páginas, PDFs protegidos por senha e entrada baseada em fluxo para PDFs recuperados de bancos de dados ou respostas HTTP.

Custos indiretos de gerenciamento de credenciais

Para iniciar uma operação de OCR com o AWS Textract, é necessário configurar o IAM antes que qualquer página seja processada.

Abordagem AWS Textract

Antes de chamar DetectDocumentTextAsync, um desenvolvedor deve:

  1. Crie uma conta da AWS ou obtenha acesso a uma conta existente.
  2. Criar um usuário ou função IAM com permissões textract:DetectDocumentText e textract:AnalyzeDocument
  3. Gere e armazene com segurança o ID da chave de acesso e a chave de acesso secreta.
  4. Configure a resolução de credenciais — variáveis ​​de ambiente, arquivo de credenciais da AWS ou perfil de instância EC2.
  5. Se estiver processando PDFs: criar um bucket S3, configurar a política do bucket, adicionar permissões s3:PutObject e s3:DeleteObject
  6. Implementar políticas de rotação de credenciais para atender aos padrões de segurança.
  7. Armazene as credenciais com segurança em cada ambiente de implantação — segredos do Docker, segredos do Kubernetes, AWS Secrets Manager ou variáveis ​​do pipeline de CI/CD.
// Every environment needs these configured before this constructor succeeds
public TextractOcrService()
{
    // Reads credentials from environment, ~/.aws/credentials, or IAM role
    _client = new AmazonTextractClient(Amazon.RegionEndpoint.USEast1);
}
// Every environment needs these configured before this constructor succeeds
public TextractOcrService()
{
    // Reads credentials from environment, ~/.aws/credentials, or IAM role
    _client = new AmazonTextractClient(Amazon.RegionEndpoint.USEast1);
}
' Every environment needs these configured before this constructor succeeds
Public Sub New()
    ' Reads credentials from environment, ~/.aws/credentials, or IAM role
    _client = New AmazonTextractClient(Amazon.RegionEndpoint.USEast1)
End Sub
$vbLabelText   $csharpLabel

Quando as credenciais expiram, são giradas ou estão configuradas incorretamente, todas as chamadas OCR falham com AmazonTextractException carregando ErrorCode == "AccessDeniedException". Em um sistema de produção, isso significa implementar blocos de tratamento específicos para falhas de credenciais e monitorar desvios nas políticas de IAM.

Abordagem IronOCR

// One-time setup at application startup
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";

// Or from environment — recommended for deployments
IronOcr.License.LicenseKey = Environment.GetEnvironmentVariable("IRONOCR_LICENSE");
// One-time setup at application startup
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";

// Or from environment — recommended for deployments
IronOcr.License.LicenseKey = Environment.GetEnvironmentVariable("IRONOCR_LICENSE");
' One-time setup at application startup
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY"

' Or from environment — recommended for deployments
IronOcr.License.LicenseKey = Environment.GetEnvironmentVariable("IRONOCR_LICENSE")
$vbLabelText   $csharpLabel

A chave de licença é uma sequência estática. Não expira durante a operação, não requer rotação e não possui permissões de gerenciamento. Um contêinerDockerque processa documentos não precisa de credenciais AWS injetadas, uma função IAM vinculada a um contexto de execução ou acesso à rede do AWS STS para atualização de token.

A redução completa de sobrecarga de credenciais ao mudar do Textract para IronOCR: três pacotes NuGet removidos (AWSSDK.Textract, AWSSDK.S3, AWSSDK.Core), todas as variáveis de ambiente AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY / AWS_DEFAULT_REGION removidas, e funções IAM e configurações de bucket S3 descomissionadas. O guia de entrada de imagem e o guia de entrada de fluxo abrangem toda a gama de métodos de entrada que substituem os modelos de documento de matriz de bytes e objeto S3 do Textract.

Referência de Mapeamento de API

APIAWS Textract Equivalente de IronOCR
AmazonTextractClient IronTesseract
AmazonS3Client Não é necessário
DetectDocumentTextRequest OcrInput
DetectDocumentTextResponse OcrResult
AnalyzeDocumentRequest OcrInput com CropRectangle para zonas
StartDocumentTextDetectionRequest OcrInput — síncrono, sem necessidade de iniciar
GetDocumentTextDetectionRequest Não é necessário — resultados imediatos
Document.Bytes input.LoadImage(bytes) ou input.LoadImage(stream)
S3Object (estágio de documentos) string ou fluxo de caminho de arquivo
Block (BlockType.LINE) result.Lines
Block (BlockType.WORD) result.Words
Block (BlockType.TABLE) Agrupamento de posições de palavras via result.Words
Block (BlockType.KEY_VALUE_SET) Extração de região CropRectangle
Block.Confidence word.Confidence / result.Confidence
JobStatus.SUCCEEDED Não aplicável — retorno síncrono
JobStatus.IN_PROGRESS Não aplicável — nenhum estado assíncrono
response.NextToken (paginação) Não aplicável — resultados não paginados
ProvisionedThroughputExceededException Não aplicável — sem limites de TPS
client.DetectDocumentTextAsync(request) ocr.Read(path)
client.AnalyzeDocumentAsync(request) ocr.Read(input)
client.StartDocumentTextDetectionAsync(request) ocr.Read(input)
client.GetDocumentTextDetectionAsync(request) Não aplicável

Quando as equipes consideram migrar doAWS Textractpara o IronOCR

Quando a conta mensal se torna uma despesa do orçamento

As equipes que começaram a usar o Textract em baixo volume frequentemente se deparam com um momento específico: a fatura da AWS para processamento de OCR aparece em uma revisão orçamentária trimestral e alguém pergunta se esse custo é fixo. Não é. Em altos volumes de páginas, os custos anuais do Textract podem ser substanciais — consulte a página de preços do AWS Textract para tarifas atuais. A licença IronOCR Professional por $2,999 paga por si mesma rapidamente em volumes de páginas moderados a altos.

Quando um requisito de conformidade bloqueia o processamento em nuvem

Organizações de saúde que implementam fluxos de trabalho de digitalização de documentos frequentemente descobrem, no meio do projeto, que as informações de saúde protegidas pelaHIPAA(PHI-PHI) não podem ser transmitidas por serviços em nuvem sem um Acordo de Parceiro Comercial (BAA) e uma revisão jurídica adicional, ou que sua equipe de segurança proíbe completamente a transmissão para a nuvem. Os contratados da área de defesa que lidam com desenhos técnicos, especificações ou qualquer informação controlada não classificada (CUI) estão sujeitos a restrições doITARe do CMMC que excluem oAWS Textractde sua consideração. Escritórios de advocacia que processam comunicações confidenciais têm preocupações semelhantes. Esses não são casos extremos teóricos de conformidade — eles aparecem regularmente em revisões de compras, auditorias de segurança e negociações de contratos. O IronOCR processa os dados localmente, portanto, a questão de conformidade para dados de documentos se resume a saber se sua própria infraestrutura está dentro do escopo, e não se a infraestrutura da Amazon está.

Quando a complexidade do PDF assíncrono excede seu valor

O pipeline assíncrono do S3 de cinco fases — upload, início da tarefa, polling, paginação dos resultados, limpeza — não é tecnicamente difícil de implementar. É difícil de manter, testar e operar. Cada fase é um ponto de falha. Falhas no envio de arquivos para o S3 exigem lógica de repetição. As falhas nos trabalhos do Textract exigem a distinção entre erros transitórios e permanentes. Os tempos limite de sondagem exigem um tratamento de tempo limite separado do cancelamento. A paginação de resultados requer o acúmulo de estado ao longo de múltiplas chamadas de API. Falhas na limpeza do S3 exigem alertas porque objetos órfãos acumulam custos. As equipes que implementaram esse pipeline em produção normalmente gastam mais tempo de engenharia contínua em sua manutenção do que gastaram em sua construção. O equivalente IronOCR— input.LoadPdf(path) seguido por ocr.Read(input) — elimina todas as cinco fases e seus modos de falha associados.

Quando os ambientes de implantação não têm acesso à Internet

ContêineresDockerexecutados em segmentos de rede isolados, servidores locais sem acesso à internet, ambientes de pesquisa isolados da internet e sistemas industriais com controles de rede rigorosos compartilham uma característica: oAWS Textractnão está disponível. O IronOCR é instalado como um pacote NuGet padrão e funciona sem qualquer chamada de rede após a instalação. As equipes que executam aplicativos .NET nesses ambientes não têm a opção do Textract e precisam de uma biblioteca que processe os dados localmente. O guia de implantação do Docker e o guia de implantação do Linux abordam a configuração específica para ambientes conteinerizados.

Quando a limitação de taxa interrompe os fluxos de trabalho em lote

O limite padrão de TPS StartDocumentTextDetection é de 5 solicitações por segundo. Chamadas síncronas DetectDocumentText também têm limite de taxa. Os trabalhos em lote que processam centenas ou milhares de documentos devem implementar limitação SemaphoreSlim, recuo exponencial em ProvisionedThroughputExceededException, e temporizadores de reabastecimento de taxa. A AWS aceita solicitações de aumento de limite de TPS, mas elas exigem justificativa, análise e não são garantidas. O IronOCR processa os dados na velocidade máxima permitida pela CPU local — um servidor de 32 núcleos processa 32 documentos simultaneamente, sem necessidade de configuração de limitação de capacidade ou negociação de nível de serviço.

Considerações Comuns de Migração

Substituindo o grafo de blocos por coleções diretas

Textract representa todos os resultados como um List<Block> plano onde linhas, palavras, células, tabelas e pares chave-valor são distinguidos por BlockType e vinculados por matrizes de ID de relacionamento. O IronOCR fornece coleções digitadas diretamente.

// Textract: filter flat block list by type
var lines = response.Blocks.Where(b => b.BlockType == BlockType.LINE);
var words = response.Blocks.Where(b => b.BlockType == BlockType.WORD);

// IronOCR: direct access to typed collections
var result = ocr.Read(imagePath);
var lines = result.Lines;   // IEnumerable<OcrResult.OcrResultLine>
var words = result.Words;   // IEnumerable<OcrResult.OcrResultWord>
foreach (var word in result.Words)
    Console.WriteLine($"'{word.Text}' at ({word.X},{word.Y}) confidence {word.Confidence}%");
// Textract: filter flat block list by type
var lines = response.Blocks.Where(b => b.BlockType == BlockType.LINE);
var words = response.Blocks.Where(b => b.BlockType == BlockType.WORD);

// IronOCR: direct access to typed collections
var result = ocr.Read(imagePath);
var lines = result.Lines;   // IEnumerable<OcrResult.OcrResultLine>
var words = result.Words;   // IEnumerable<OcrResult.OcrResultWord>
foreach (var word in result.Words)
    Console.WriteLine($"'{word.Text}' at ({word.X},{word.Y}) confidence {word.Confidence}%");
' Textract: filter flat block list by type
Dim lines = response.Blocks.Where(Function(b) b.BlockType = BlockType.LINE)
Dim words = response.Blocks.Where(Function(b) b.BlockType = BlockType.WORD)

' IronOCR: direct access to typed collections
Dim result = ocr.Read(imagePath)
Dim lines = result.Lines   ' IEnumerable(Of OcrResult.OcrResultLine)
Dim words = result.Words   ' IEnumerable(Of OcrResult.OcrResultWord)
For Each word In result.Words
    Console.WriteLine($"'{word.Text}' at ({word.X},{word.Y}) confidence {word.Confidence}%")
Next
$vbLabelText   $csharpLabel

O guia de resultados estruturados cobre result.Pages, result.Paragraphs, result.Lines, result.Words e acesso a coordenadas para construção de processamento de documentos consciente do layout.

Substituindo o processamento de PDF em estágios S3 pelo carregamento direto de PDF.

Qualquer código Textract que faça upload para o S3 antes de iniciar uma tarefa de detecção pode ser substituído por um carregamento direto de PDF. Sem ambiente de preparação (staging bucket), sem agendamento de uploads, sem lógica de limpeza.

// Textract: upload to S3 → start job → poll → paginate → cleanup (50+ lines)
//IronOCR equivalent:
public string ProcessPdf(string pdfPath)
{
    var ocr = new IronTesseract();
    using var input = new OcrInput();
    input.LoadPdf(pdfPath);
    return ocr.Read(input).Text;
}

// Specific page ranges (no Textract equivalent without async job per range)
public string ProcessPdfPages(string pdfPath, int startPage, int endPage)
{
    var ocr = new IronTesseract();
    using var input = new OcrInput();
    input.LoadPdfPages(pdfPath, startPage, endPage);
    return ocr.Read(input).Text;
}
// Textract: upload to S3 → start job → poll → paginate → cleanup (50+ lines)
//IronOCR equivalent:
public string ProcessPdf(string pdfPath)
{
    var ocr = new IronTesseract();
    using var input = new OcrInput();
    input.LoadPdf(pdfPath);
    return ocr.Read(input).Text;
}

// Specific page ranges (no Textract equivalent without async job per range)
public string ProcessPdfPages(string pdfPath, int startPage, int endPage)
{
    var ocr = new IronTesseract();
    using var input = new OcrInput();
    input.LoadPdfPages(pdfPath, startPage, endPage);
    return ocr.Read(input).Text;
}
Imports IronOcr

Public Class PdfProcessor
    ' Textract: upload to S3 → start job → poll → paginate → cleanup (50+ lines)
    ' IronOCR equivalent:
    Public Function ProcessPdf(pdfPath As String) As String
        Dim ocr As New IronTesseract()
        Using input As New OcrInput()
            input.LoadPdf(pdfPath)
            Return ocr.Read(input).Text
        End Using
    End Function

    ' Specific page ranges (no Textract equivalent without async job per range)
    Public Function ProcessPdfPages(pdfPath As String, startPage As Integer, endPage As Integer) As String
        Dim ocr As New IronTesseract()
        Using input As New OcrInput()
            input.LoadPdfPages(pdfPath, startPage, endPage)
            Return ocr.Read(input).Text
        End Using
    End Function
End Class
$vbLabelText   $csharpLabel

Adicionando pré-processamento para documentos que produziram baixa confiança no Textract

O pré-processamento do Textract é interno e não configurável. Quando um documento digitalizado produz resultados insatisfatórios, as únicas opções são tentar novamente ou aceitar um resultado com baixa confiabilidade. O IronOCR expõe diretamente o pipeline de pré-processamento.

// For documents that returned low-confidence results from Textract
using var input = new OcrInput();
input.LoadImage("low-quality-scan.jpg");

input.Deskew();              // Fix rotation from scanner misalignment
input.DeNoise();             // Remove scanner noise artifacts
input.Contrast();            // Boost faint text
input.EnhanceResolution(300); // Scale to optimal OCR resolution

var result = new IronTesseract().Read(input);
Console.WriteLine($"Confidence: {result.Confidence}%");
// For documents that returned low-confidence results from Textract
using var input = new OcrInput();
input.LoadImage("low-quality-scan.jpg");

input.Deskew();              // Fix rotation from scanner misalignment
input.DeNoise();             // Remove scanner noise artifacts
input.Contrast();            // Boost faint text
input.EnhanceResolution(300); // Scale to optimal OCR resolution

var result = new IronTesseract().Read(input);
Console.WriteLine($"Confidence: {result.Confidence}%");
Imports IronOcr

Dim input As New OcrInput()
input.LoadImage("low-quality-scan.jpg")

input.Deskew()              ' Fix rotation from scanner misalignment
input.DeNoise()             ' Remove scanner noise artifacts
input.Contrast()            ' Boost faint text
input.EnhanceResolution(300) ' Scale to optimal OCR resolution

Dim result = New IronTesseract().Read(input)
Console.WriteLine($"Confidence: {result.Confidence}%")
$vbLabelText   $csharpLabel

O guia de correção de qualidade de imagem e o tutorial de filtros de imagem documentam o pipeline completo de pré-processamento e combinações que funcionam melhor para tipos de documentos específicos. Para interpretação de pontuação de confiança e acesso de confiança por elemento, o guia de pontuações de confiança cobre a propriedade result.Confidence e valores de confiança por palavra.

Lidando com a mudança de padrão de assíncrono para síncrono

O código existente do Textract é necessariamente async Task<t> por todo o SDK porque é apenas assíncrono. As operações do IronOCR são síncronas. Para código de aplicativo que já possui uma cadeia de chamadas assíncronas, envolva a chamada IronOCR em Task.Run para manter o limite assíncrono.

// Preserves async call site for minimal refactoring
public async Task<string> ExtractTextAsync(string path)
{
    return await Task.Run(() => new IronTesseract().Read(path).Text);
}
// Preserves async call site for minimal refactoring
public async Task<string> ExtractTextAsync(string path)
{
    return await Task.Run(() => new IronTesseract().Read(path).Text);
}
Imports System.Threading.Tasks

' Preserves async call site for minimal refactoring
Public Async Function ExtractTextAsync(path As String) As Task(Of String)
    Return Await Task.Run(Function() New IronTesseract().Read(path).Text)
End Function
$vbLabelText   $csharpLabel

Esta é uma embalagem para facilitar o uso, não um requisito. Para processamento no lado do servidor, onde o código de chamada já está em uma thread em segundo plano, a chamada síncrona direta é preferível.

Funcionalidades adicionais do IronOCR

Além dos pontos de comparação acima, o IronOCR oferece recursos que não têm equivalente no AWS Textract:

Compatibilidade com .NET e Preparação para o Futuro

O IronOCR é compatível com .NET 8 e .NET 9, com suporte ativo para projetos .NET Standard 2.0 e .NET Framework 4.6.2 a 4.8. A biblioteca inclui binários nativos para Windows x64, Windows x86,Linuxx64 e macOS em um único pacote NuGet — sem necessidade de troca de identificadores de tempo de execução ou referências a pacotes específicos da plataforma. O pacote AWSSDK.Textract doAWS Textractsuporta os mesmos destinos .NET modernos, mas o modelo de implantação carrega toda a árvore de dependência do SDK AWS, infraestrutura de credenciais IAM, e as restrições arquitetônicas documentadas ao longo deste artigo. O IronOCR mantém um desenvolvimento ativo com lançamentos regulares que acompanham as atualizações do mecanismo Tesseract 5 e os avanços do ambiente de execução .NET , incluindo a compatibilidade com o .NET 10 quando este for lançado.

Conclusão

OAWS Textracte o IronOCR resolvem o mesmo problema — extrair texto de documentos em aplicações .NET — com pressupostos arquitetônicos fundamentalmente incompatíveis. O Textract pressupõe que os documentos possam sair da sua rede, que os custos do serviço em nuvem aumentem linearmente com o volume e que PDFs com várias páginas justifiquem um pipeline assíncrono de cinco fases com armazenamento temporário no S3. O IronOCR parte do princípio de que os documentos permanecem no local onde são processados, que os custos de licenciamento devem ser dissociados do volume e que o processamento de PDFs deve exigir as mesmas três linhas de código que o processamento de imagens.

A aritmética de custo é a linha divisória mais clara. Em baixos volumes, as taxas por página do Textract são manejáveis. À medida que o volume cresce, os custos anuais aumentam significativamente. Em volumes de páginas altos com extração de tabelas, os custos do Textract ao longo de vários anos podem exceder em muito até mesmo a licença Unlimited do IronOCR em $5,999. A matemática inicial se mantém: o modelo por página soma rápido, e nunca para.

A soberania dos dados é a segunda restrição estrutural. Para as áreas da saúde, jurídica, financeira e governamental, a questão de onde os documentos são processados ​​não é uma preferência — é uma exigência de conformidade. O IronOCR processa os dados localmente por padrão, não por configuração. Não existe um "modo local" que possa ser ativado; O processamento local é o único modo. Isso torna a resposta sobre conformidade simples: seus documentos permanecem em sua infraestrutura porque não há outro lugar para onde eles possam ir.

Para equipes que avaliam o OCR em escala real ou que operam em ambientes onde os dados dos documentos não podem sair da infraestrutura interna, a documentação do IronOCR fornece a referência completa da API, guias de implantação para Docker, AWS,Azuree Linux, além de tutoriais que abrangem toda a gama de casos de uso de OCR, desde a leitura básica de imagens até a geração de PDFs pesquisáveis ​​e a extração multilíngue.

ObserveAWS Textract e Tesseract são marcas registradas de seus respectivos proprietários. Este site não é afiliado, endossado ou patrocinado pela Amazon Web Services ou Google. 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.

Perguntas frequentes

O que é o Amazon Textract?

O Amazon Textract é uma solução de OCR usada por desenvolvedores e empresas para extrair texto de imagens e documentos. É uma das várias opções de OCR avaliadas juntamente com o IronOCR para desenvolvimento de aplicações .NET.

Como o IronOCR se compara ao Amazon Textract para desenvolvedores .NET?

IronOCR é uma biblioteca OCR .NET nativa do NuGet que utiliza o IronTesseract como mecanismo principal. Comparada ao Amazon Textract, oferece implantação mais simples (sem instaladores de SDK), preço fixo e uma API C# limpa, sem interoperabilidade COM ou dependências de nuvem.

O IronOCR é mais fácil de configurar do que o Amazon Textract?

O IronOCR é instalado por meio de um único pacote NuGet. Não há instaladores de SDK, arquivos de licença para copiar, componentes COM para registrar ou binários de tempo de execução separados para gerenciar. Todo o mecanismo de OCR está incluído no pacote.

Quais são as diferenças de precisão entre o Amazon Textract e o IronOCR?

O IronOCR alcança alta precisão de reconhecimento para documentos comerciais padrão, faturas, recibos e formulários digitalizados. Para documentos muito degradados ou com escritas incomuns, a precisão varia de acordo com a qualidade da fonte. O IronOCR inclui filtros de pré-processamento de imagem para melhorar o reconhecimento em entradas de baixa qualidade.

O IronOCR suporta extração de texto de PDFs?

Sim. O IronOCR extrai texto tanto de PDFs nativos quanto de imagens digitalizadas de PDFs em uma única chamada. Ele também suporta arquivos TIFF com várias páginas, imagens e fluxos de dados. Para PDFs digitalizados, o OCR é aplicado página por página, com objetos de resultado por página.

Como se compara o licenciamento do Amazon Textract ao do IronOCR?

O IronOCR utiliza uma licença perpétua com preço fixo, sem cobranças por página ou por digitalização. Organizações que processam grandes volumes de documentos pagam o mesmo valor de licença, independentemente do volume. Detalhes e preços por volume estão disponíveis na página de licenciamento do IronOCR.

Quais idiomas o IronOCR suporta?

O IronOCR suporta 127 idiomas através de pacotes de idiomas NuGet separados. Adicionar um idioma requer um único comando 'dotnet add package IronOcr.Languages.{Idioma}'. Não é necessário inserir arquivos manualmente nem configurar caminhos.

Como faço para instalar o IronOCR em um projeto .NET ?

Instale via NuGet: 'Install-Package IronOcr' no Console do Gerenciador de Pacotes ou 'dotnet add package IronOcr' na CLI. Pacotes de idiomas adicionais são instalados da mesma forma. Não é necessário instalar o SDK nativo.

O IronOCR é adequado para implantações em Docker e contêineres, ao contrário do Amazon Textract?

Sim. O IronOCR funciona em contêineres Docker por meio de seu pacote NuGet. A chave de licença é definida por meio de uma variável de ambiente. Não são necessários arquivos de licença, caminhos de SDK ou montagens de volume para o próprio mecanismo de OCR.

Posso experimentar o IronOCR antes de comprar, em comparação com o Amazon Textract?

Sim. O modo de avaliação do IronOCR processa documentos e retorna resultados de OCR com uma marca d'água sobreposta. Você pode verificar a precisão em seus próprios documentos antes de adquirir uma licença.

O IronOCR suporta leitura de código de barras juntamente com extração de texto?

O IronOCR concentra-se na extração de texto e OCR. Para leitura de código de barras, a Iron Software fornece o IronBarcode como uma biblioteca complementar. Ambos estão disponíveis individualmente ou como parte do pacote Iron Suite.

É fácil migrar do Amazon Textract para o IronOCR?

A migração do Amazon Textract para o IronOCR normalmente envolve a substituição das sequências de inicialização pela instanciação do IronTesseract, a remoção do gerenciamento do ciclo de vida COM e a atualização das chamadas de API. A maioria das migrações reduz significativamente a complexidade do código.

Kannaopat Udonpant
Engenheiro de Software
Antes de se tornar Engenheiro de Software, Kannapat concluiu um doutorado em Recursos Ambientais pela Universidade de Hokkaido, no Japão. Durante o doutorado, Kannapat também integrou o Laboratório de Robótica Veicular, que faz parte do Departamento de Engenharia de Bioprodução. Em 2022, ele utilizou suas habilidades ...
Leia mais

Equipe de Suporte Iron

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