Migrando do RapidOCR.NET para o IronOCR
Este guia cobre o caminho completo de migração de RapidOCR.NET (RapidOcrNet) para IronOCR para desenvolvedores .NET que precisam eliminar o gerenciamento de arquivos de modelo ONNX de seu pipeline OCR. Ele aborda a substituição de pacotes, tradução de código e as mudanças operacionais que ocorrem quando as dependências de modelos externos são completamente removidas.
Por que migrar do RapidOCR .NET?
O RapidOCR .NET funciona — para um conjunto restrito de casos de uso, em ambientes controlados, onde alguém já resolveu o problema de distribuição do modelo. Quando qualquer uma dessas condições muda, as restrições arquitetônicas da biblioteca se transformam em custos de engenharia.
Os Arquivos de Modelos ONNX São um Artefato de Implantação, Não um Pacote. RapidOCR.NET requer quatro arquivos externos — det.onnx, cls.onnx, rec.onnx, e um dicionário de caracteres — antes que um único caractere possa ser reconhecido. Esses arquivos não estão incluídos no pacote NuGet . Eles estão disponíveis nas páginas de lançamento do GitHub , exigem download manual, configuração explícita de caminhos no código e regras MSBuild personalizadas para serem copiadas durante a compilação. Todo novo desenvolvedor, todo pipeline de CI, todo ambiente de implantação repete essa cerimônia.
A troca de idioma envolve a substituição de arquivos, não a configuração. Alterar do OCR em inglês para o OCR em chinês no RapidOCR .NET exige o download de um modelo de reconhecimento e um dicionário de caracteres diferentes, seguido da reconstrução da instância do mecanismo. Espanhol, francês, alemão, russo, árabe e mais de 100 outros idiomas não possuem nenhum modelo disponível no catálogo de modelos do RapidOCR. Uma aplicação que precisa processar documentos em diversos idiomas não possui uma solução viável no RapidOCR .NET para os idiomas não suportados.
As atualizações de versão do modelo exigem intervenção manual. Quando o projeto RapidOCR lança pesos de modelo aprimorados, as equipes devem baixar os novos arquivos, substituí-los em todos os ambientes, validar os caminhos e reimplantar o modelo. Não existe nenhuma etapa de restauração de pacotes que lide com isso automaticamente. Em um ambiente com múltiplas instâncias, incluindo desenvolvimento, teste e produção, essa propagação é uma operação manual a cada vez.
A Dependência do Tempo de Execução de ONNX Adiciona Complexidade à Plataforma. RapidOCR.NET depende de Microsoft.ML.OnnxRuntime, um pacote com binários nativos específicos da plataforma. As variantes de CPU e GPU requerem pacotes diferentes. Uma imagem de contêiner construída para linux/amd64 requer binários diferentes de uma construída para linux/arm64. Cada destino de implantação precisa ser validado para garantir que a variante de tempo de execução correta esteja presente e seja compatível com os arquivos de modelo instalados.
A latência de inicialização a frio e o consumo de memória são custos fixos. O carregamento dos três modelos ONNX na inicialização leva de 2 a 5 segundos e ocupa de 300 a 500 MB de memória durante todo o processo. Esse custo é pago independentemente do volume de OCR, o que torna a biblioteca inadequada para funções sem servidor, contêineres leves ou serviços de baixo tráfego, onde a penalidade de inicialização é desproporcional à taxa de transferência.
Sem suporte comercial. O RapidOCR .NET é mantido por um único desenvolvedor da comunidade sob a licença Apache 2.0. Incidentes de produção — conflitos de versão do ONNX Runtime, falhas de inferência em formatos de imagem incomuns, aumento de memória sob carga sustentada — são encaminhados para uma fila de problemas no GitHub , sem prazo de resposta garantido e sem SLA.
O problema fundamental
Três arquivos de modelo ONNX, Plus de um dicionário de caracteres, todos baixados separadamente e configurados por caminho:
// RapidOcrNet: 4 external files required before any OCR can execute
var engine = new RapidOcrEngine(new RapidOcrOptions
{
DetModelPath = "./models/det.onnx", // ~3 MB — downloaded from GitHub
ClsModelPath = "./models/cls.onnx", // ~1 MB — downloaded from GitHub
RecModelPath = "./models/rec_en.onnx", // ~2-10 MB — language-specific download
KeysPath = "./models/en_keys.txt" // character dictionary — language-specific
});
O IronOCR não possui arquivos de modelo, configuração de caminho ou etapa de download:
// IronOCR: install the NuGet package, write one line
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";
var text = new IronTesseract().Read("document.jpg").Text;
##IronOCR vs RapidOCR .NET: Comparação de Recursos
IronOCR e RapidOCR .NET compartilham funcionalidades básicas de OCR de imagens. A lacuna se abre em todas as questões adjacentes.
| Recurso | RapidOCR.NET | IronOCR |
|---|---|---|
| Instalação do NuGet | Sim (RapidOcrNet) | Sim (IronOcr) |
| Arquivos de modelo externos necessários | Sim (4 arquivos, download manual) | Não |
| Configuração de caminho necessária | Sim | Não |
| Regras de cópia do MSBuild necessárias | Sim | Não |
| Funciona imediatamente após a instalação do NuGet. | Não | Sim |
| Dependência de tempo de execução do ONNX | Sim (aproximadamente 30–50 MB) | Não |
| Idiomas suportados | ~5 (somente CJK + inglês) | Mais de 125 idiomas disponíveis através dos pacotes NuGet. |
| Mudança de idioma | Troca de arquivos + reconstrução do motor | Cessão de propriedade |
| Suporte a idiomas europeus | Não | Sim (30+) |
| Suporte para árabe/hebraico | Não | Sim |
| Suporte para cirílico (russo, ucraniano) | Não | Sim |
| Entrada nativa de PDF | Não | Sim |
| Entrada de PDF protegida por senha | Não | Sim |
| Saída em PDF pesquisável | Não | Sim |
| Entrada TIFF de várias páginas | Não | Sim |
| Entrada de fluxo e matriz de bytes | Limitado | Sim |
| Pré-processamento de imagem integrado | Não | Sim (filtros automáticos + manuais) |
| Filtros de correção de distorção/redução de ruído/contraste | Não | Sim |
| Saída estruturada (parágrafos, linhas, palavras) | Parcial (somente blocos) | Sim, com coordenadas. |
| Pontuações de confiança por palavra | Sim (por bloco) | Sim |
| Leitura de código de barras durante OCR | Não | Sim |
| Exportação hOCR | Não | Sim |
| Processamento paralelo seguro para threads | Limitado | Sim (uma instância por thread) |
| Implantação multiplataforma | Requer binários do ONNX Runtime por plataforma. | Sim (Windows, Linux, macOS, Docker) |
| Implantação em Docker | Manual de instruções necessário (cópia das instruções) | Pronto para usar |
| Partida a frio | 2–5 segundos (carregamento do modelo) | Mínimo |
| Suporte comercial | Não | Sim |
| Licença | Apache 2.0 (gratuito) | Perpetual ($999 Lite, $1,499 Pro, $2,999 Enterprise) |
Guia Rápido: Migração do RapidOCR .NET para o IronOCR
Passo 1: Substitua o pacote NuGet
Remova o RapidOCR .NET e a dependência do ONNX Runtime:
dotnet remove package RapidOcrNet
dotnet remove package Microsoft.ML.OnnxRuntime
Instale o IronOCR a partir do NuGet :
Etapa 2: Atualizar Namespaces
Substitua o namespace RapidOCR .NET pelo namespace IronOCR:
// Before (RapidOCR.NET)
using RapidOcrNet;
// After (IronOCR)
using IronOcr;
Etapa 3: Inicializar a licença
Adicione a inicialização da licença no início da aplicação, antes de qualquer chamada IronTesseract:
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY"Uma chave de avaliação gratuita está disponível na página de licenciamento do IronOCR .
Exemplos de migração de código
Remoção da configuração do caminho do modelo ONNX
A mudança mais mecânica nesta migração é excluir o bloco de configuração RapidOcrOptions e substituí-lo por um construtor sem argumentos.
Abordagem RapidOCR .NET :
using RapidOcrNet;
// Startup validation — written because a missing model crashes at runtime, not at install
private static void EnsureModelsPresent(string modelDir)
{
var required = new[]
{
Path.Combine(modelDir, "det.onnx"),
Path.Combine(modelDir, "cls.onnx"),
Path.Combine(modelDir, "rec_en.onnx"),
Path.Combine(modelDir, "en_keys.txt")
};
var missing = required.Where(f => !File.Exists(f)).ToList();
if (missing.Any())
throw new FileNotFoundException(
$"Missing model files: {string.Join(", ", missing)}\n" +
"Download from: https://github.com/RapidAI/RapidOCR/releases");
}
// Engine factory — called once at startup, held for lifetime of service
public RapidOcrEngine CreateEngine(string modelDir)
{
EnsureModelsPresent(modelDir);
return new RapidOcrEngine(new RapidOcrOptions
{
DetModelPath = Path.Combine(modelDir, "det.onnx"),
ClsModelPath = Path.Combine(modelDir, "cls.onnx"),
RecModelPath = Path.Combine(modelDir, "rec_en.onnx"),
KeysPath = Path.Combine(modelDir, "en_keys.txt"),
UseGpu = false,
NumThreads = Environment.ProcessorCount
});
}
Abordagem IronOCR:
using IronOcr;
// Não model validation, no path configuration, no GPU flags
// IronTesseract is thread-safe; create one per thread or on demand
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY";
var ocr = new IronTesseract();
O método completo de validação EnsureModelsPresent, o objeto de configuração RapidOcrOptions e a classe de fábrica do mecanismo podem ser excluídos. Não há arquivos de modelo para validar, pois o IronOCR inclui seu mecanismo internamente como parte do pacote NuGet . O guia de instalação do IronTesseract aborda detalhadamente as opções de inicialização e a inserção da chave de licença.
Consolidação do fluxo de trabalho de detecção, classificação e reconhecimento
O RapidOCR .NET executa um pipeline ONNX de três estágios — detecção, classificação de direção e, em seguida, reconhecimento — e retorna uma lista plana não ordenada de blocos de texto que o chamador deve classificar e montar.IronOCR expõe uma única chamada .Read() suportada por seu motor Tesseract 5 interno, retornando uma saída estruturada com a ordem de leitura já aplicada.
Abordagem RapidOCR .NET :
using RapidOcrNet;
public class InvoiceTextExtractor
{
private readonly RapidOcrEngine _engine;
public InvoiceTextExtractor(string modelDir)
{
// Three separate ONNX models run in sequence on every call
_engine = new RapidOcrEngine(new RapidOcrOptions
{
DetModelPath = Path.Combine(modelDir, "det.onnx"), // Stage 1: detect text regions
ClsModelPath = Path.Combine(modelDir, "cls.onnx"), // Stage 2: classify direction
RecModelPath = Path.Combine(modelDir, "rec_en.onnx"),// Stage 3: recognize characters
KeysPath = Path.Combine(modelDir, "en_keys.txt")
});
}
public string ExtractInvoiceText(string imagePath)
{
var result = _engine.Run(imagePath);
// Blocks are unordered — must sort by vertical position, then horizontal
var orderedBlocks = result.TextBlocks
.OrderBy(b => b.BoundingBox.Top)
.ThenBy(b => b.BoundingBox.Left)
.ToList();
// Manual assembly — no paragraph or line structure
return string.Join(Environment.NewLine,
orderedBlocks.Select(b => b.Text));
}
}
Abordagem IronOCR:
using IronOcr;
public class InvoiceTextExtractor
{
private readonly IronTesseract _ocr = new IronTesseract();
public string ExtractInvoiceText(string imagePath)
{
// Single call — detection, recognition, reading order all internal
var result = _ocr.Read(imagePath);
return result.Text; // Already in reading order
}
public IEnumerable<string> ExtractInvoiceParagraphs(string imagePath)
{
var result = _ocr.Read(imagePath);
// Structured paragraphs with coordinates — no sorting or assembly needed
foreach (var page in result.Pages)
foreach (var paragraph in page.Paragraphs)
yield return paragraph.Text;
}
}
O pipeline de três etapas é inteiramente interno ao IronOCR. A lista result.TextBlocks com sua cadeia manual OrderBy se reduz a result.Text. Para chamadores que precisavam de dados de caixa delimitadora de TextBlocks, as coleções result.Pages[i].Paragraphs, .Lines e .Words fornecem coordenadas equivalentes através de uma API estruturada. A página com instruções sobre como realizar a leitura dos resultados e os recursos de OCR descreve o modelo completo de saída estruturada.
Substituição de carregamento de modelo personalizado
Aplicações que precisam alternar configurações de OCR em tempo de execução — por exemplo, roteando documentos através de diferentes parâmetros de reconhecimento com base no tipo de documento — devem reconstruir todo o RapidOcrEngine no RapidOCR.NET porque a configuração está vinculada ao construtor. O IronOCR expõe a configuração do mecanismo como propriedades que podem ser ajustadas por leitura em uma única instância.
Abordagem RapidOCR .NET :
using RapidOcrNet;
public class DocumentRouter
{
private readonly string _modelDir;
public DocumentRouter(string modelDir) => _modelDir = modelDir;
// Must create separate engine instances per configuration
// Each engine holds ~300-500 MB of loaded model weights
private RapidOcrEngine BuildEnglishEngine() =>
new RapidOcrEngine(new RapidOcrOptions
{
DetModelPath = Path.Combine(_modelDir, "det.onnx"),
ClsModelPath = Path.Combine(_modelDir, "cls.onnx"),
RecModelPath = Path.Combine(_modelDir, "en_rec.onnx"),
KeysPath = Path.Combine(_modelDir, "en_keys.txt")
});
private RapidOcrEngine BuildChineseEngine() =>
new RapidOcrEngine(new RapidOcrOptions
{
DetModelPath = Path.Combine(_modelDir, "det.onnx"),
ClsModelPath = Path.Combine(_modelDir, "cls.onnx"),
RecModelPath = Path.Combine(_modelDir, "ch_rec.onnx"), // separate download
KeysPath = Path.Combine(_modelDir, "ch_keys.txt") // separate download
});
public string ProcessDocument(string imagePath, string language)
{
// Rebuild engine for each language — model reload cost on every switch
using var engine = language == "chinese"
? BuildChineseEngine()
: BuildEnglishEngine();
var result = engine.Run(imagePath);
return string.Join("\n", result.TextBlocks
.OrderBy(b => b.BoundingBox.Top)
.Select(b => b.Text));
}
}
Abordagem IronOCR:
using IronOcr;
public class DocumentRouter
{
// One instance handles all languages — language is a property, not a constructor param
private readonly IronTesseract _ocr = new IronTesseract();
public string ProcessDocument(string imagePath, string language)
{
// Language switch requires no model reload, no rebuild
_ocr.Language = language switch
{
"chinese" => OcrLanguage.ChineseSimplified,
"japanese" => OcrLanguage.Japanese,
"arabic" => OcrLanguage.Arabic,
"russian" => OcrLanguage.Russian,
_ => OcrLanguage.English
};
return _ocr.Read(imagePath).Text;
}
}
Sem reconstrução do motor gráfico, sem recarregamento do modelo, sem download separado por idioma. Pacotes de idiomas para alvos não ingleses são instalados via NuGet — dotnet add package IronOcr.Languages.ChineseSimplified — e o passo de restauração lida com a implantação automaticamente. O guia sobre vários idiomas aborda a instalação de pacotes de idiomas e o índice de idiomas lista todos os mais de 125 pacotes disponíveis.
Migração para Processamento em Lote
RapidOCR.NET não garante segurança de thread em uma única instância RapidOcrEngine. O processamento em lote requer uma fila de thread única ou a instanciação de um mecanismo por thread, cada um com sua própria pegada de modelo de 300 a 500 MB.IronOCR é explicitamente seguro para threads: crie um IronTesseract por thread e execute-os simultaneamente sem bloqueios.
Abordagem RapidOCR .NET :
using RapidOcrNet;
public class BatchOcrProcessor
{
private readonly string _modelDir;
public BatchOcrProcessor(string modelDir) => _modelDir = modelDir;
// Thread-pool processing — each thread needs its own engine copy
// 4 threads × 300-500 MB model footprint = 1.2-2 GB RAM minimum
public Dictionary<string, string> ProcessBatch(IReadOnlyList<string> imagePaths)
{
var results = new System.Collections.Concurrent.ConcurrentDictionary<string, string>();
Parallel.ForEach(imagePaths, new ParallelOptions { MaxDegreeOfParallelism = 4 },
imagePath =>
{
// Each thread must create its own engine — not safe to share
using var engine = new RapidOcrEngine(new RapidOcrOptions
{
DetModelPath = Path.Combine(_modelDir, "det.onnx"),
ClsModelPath = Path.Combine(_modelDir, "cls.onnx"),
RecModelPath = Path.Combine(_modelDir, "rec_en.onnx"),
KeysPath = Path.Combine(_modelDir, "en_keys.txt")
});
var result = engine.Run(imagePath);
results[imagePath] = string.Join("\n",
result.TextBlocks
.OrderBy(b => b.BoundingBox.Top)
.Select(b => b.Text));
});
return new Dictionary<string, string>(results);
}
}
Abordagem IronOCR:
using IronOcr;
public class BatchOcrProcessor
{
// Thread-safe: create IronTesseract per thread, no shared state required
public Dictionary<string, string> ProcessBatch(IReadOnlyList<string> imagePaths)
{
var results = new System.Collections.Concurrent.ConcurrentDictionary<string, string>();
Parallel.ForEach(imagePaths, imagePath =>
{
// Lightweight construction — no model loading overhead per thread
var ocr = new IronTesseract();
var result = ocr.Read(imagePath);
results[imagePath] = result.Text;
});
return new Dictionary<string, string>(results);
}
}
A instanciação por thread de RapidOcrEngine desaparece. As instâncias de threads do IronOCR são leves — não há carga de modelo externo na construção. O exemplo de multithreading demonstra padrões de processamento concorrente para pipelines de alto desempenho.
Processamento TIFF de múltiplos quadros
O RapidOCR .NET aceita apenas arquivos de imagem individuais. Processar um TIFF de múltiplas páginas — o formato padrão para documentos recebidos por fax e arquivos digitalizados — requer dividi-lo em quadros individuais com uma biblioteca de imagem separada, salvando esses quadros em arquivos temporários, executando engine.Run() em cada um, e limpando depois.IronOCR lida nativamente com TIFF de múltiplos quadros através de OcrInput.LoadImageFrames.
Abordagem RapidOCR .NET :
using RapidOcrNet;
// Also requires: SixLabors.ImageSharp or System.Drawing for TIFF frame extraction
public class TiffOcrProcessor
{
private readonly RapidOcrEngine _engine;
public TiffOcrProcessor(string modelDir)
{
_engine = new RapidOcrEngine(new RapidOcrOptions
{
DetModelPath = Path.Combine(modelDir, "det.onnx"),
ClsModelPath = Path.Combine(modelDir, "cls.onnx"),
RecModelPath = Path.Combine(modelDir, "rec_en.onnx"),
KeysPath = Path.Combine(modelDir, "en_keys.txt")
});
}
public string ProcessMultiPageTiff(string tiffPath)
{
var pageTexts = new List<string>();
var tempDir = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
Directory.CreateDirectory(tempDir);
try
{
// External library required to split TIFF frames
var framePaths = SplitTiffIntoFrames(tiffPath, tempDir); // not in RapidOcrNet
foreach (var framePath in framePaths)
{
var result = _engine.Run(framePath);
pageTexts.Add(string.Join("\n",
result.TextBlocks
.OrderBy(b => b.BoundingBox.Top)
.Select(b => b.Text)));
}
}
finally
{
// Clean up temp frame files
Directory.Delete(tempDir, recursive: true);
}
return string.Join("\n\n", pageTexts);
}
private IEnumerable<string> SplitTiffIntoFrames(string tiffPath, string outputDir)
{
// Requires external library — implementation depends on what is installed
throw new NotImplementedException("Add SixLabors.ImageSharp or similar");
}
}
Abordagem IronOCR:
using IronOcr;
public class TiffOcrProcessor
{
private readonly IronTesseract _ocr = new IronTesseract();
public string ProcessMultiPageTiff(string tiffPath)
{
using var input = new OcrInput();
input.LoadImageFrames(tiffPath); // All frames loaded — no external library needed
var result = _ocr.Read(input);
return result.Text; // Pages assembled in order automatically
}
public IEnumerable<(int PageNumber, string Text, double Confidence)> ProcessTiffWithPageData(string tiffPath)
{
using var input = new OcrInput();
input.LoadImageFrames(tiffPath);
var result = _ocr.Read(input);
foreach (var page in result.Pages)
yield return (page.PageNumber, page.Text, page.Confidence);
}
}
Sem biblioteca de imagens externa, sem arquivos temporários, sem lógica de limpeza. LoadImageFrames lê todos os quadros TIFF no pipeline OcrInput em uma única chamada. O guia de entrada TIFF e GIF aborda a seleção de quadros, a filtragem de intervalo de páginas e o gerenciamento eficiente de memória de documentos grandes com vários quadros.
Extração de dados estruturados de formulários digitalizados
O RapidOCR .NET retorna blocos de texto com caixas delimitadoras, mas sem estrutura de documento de nível superior — sem o conceito de parágrafos, linhas ou palavras. A extração de campos individuais de um formulário digitalizado requer a implementação de uma lógica de interseção de coordenadas na lista de blocos brutos. O IronOCR fornece uma árvore de resultados estruturada até o nível de caractere, com coordenadas em cada nível.
Abordagem RapidOCR .NET :
using RapidOcrNet;
public class FormFieldExtractor
{
private readonly RapidOcrEngine _engine;
public FormFieldExtractor(string modelDir)
{
_engine = new RapidOcrEngine(new RapidOcrOptions
{
DetModelPath = Path.Combine(modelDir, "det.onnx"),
ClsModelPath = Path.Combine(modelDir, "cls.onnx"),
RecModelPath = Path.Combine(modelDir, "rec_en.onnx"),
KeysPath = Path.Combine(modelDir, "en_keys.txt")
});
}
// Extract text within a defined region by filtering block coordinates manually
public string ExtractFieldByRegion(string imagePath, float regionLeft, float regionTop,
float regionRight, float regionBottom)
{
var result = _engine.Run(imagePath);
// Filter blocks whose bounding box intersects the target region
var blocksInRegion = result.TextBlocks
.Where(b =>
b.BoundingBox.Left < regionRight &&
b.BoundingBox.Right > regionLeft &&
b.BoundingBox.Top < regionBottom &&
b.BoundingBox.Bottom > regionTop)
.OrderBy(b => b.BoundingBox.Top)
.ThenBy(b => b.BoundingBox.Left);
return string.Join(" ", blocksInRegion.Select(b => b.Text));
}
}
Abordagem IronOCR:
using IronOcr;
public class FormFieldExtractor
{
private readonly IronTesseract _ocr = new IronTesseract();
// Use CropRectangle to OCR only the target region — no post-filter needed
public string ExtractFieldByRegion(string imagePath, int x, int y, int width, int height)
{
var region = new CropRectangle(x, y, width, height);
using var input = new OcrInput();
input.LoadImage(imagePath, region);
return _ocr.Read(input).Text;
}
// Extract all fields with their coordinates from a full-page scan
public IEnumerable<(string Text, int X, int Y, double Confidence)> ExtractAllWords(string imagePath)
{
var result = _ocr.Read(imagePath);
foreach (var page in result.Pages)
foreach (var word in page.Words)
yield return (word.Text, word.X, word.Y, word.Confidence);
}
}
CropRectangle limita o OCR à região exata de interesse, o que é mais rápido e mais preciso do que executar OCR de página inteira e filtrar resultados após o fato. Coordenadas e valores de confiança por palavra estão disponíveis diretamente em result.Pages[i].Words sem qualquer código manual de interseção de caixa delimitadora. O guia prático de OCR baseado em regiões e o exemplo de recorte de retângulo abordam esse padrão em detalhes.
Referência de mapeamento da API RapidOCR .NET para IronOCR
| RapidOCR.NET | Equivalente de IronOCR |
|---|---|
using RapidOcrNet | using IronOcr |
new RapidOcrEngine(new RapidOcrOptions { ... }) | new IronTesseract() |
RapidOcrOptions.DetModelPath | Não é necessário — incluído internamente |
RapidOcrOptions.ClsModelPath | Não é necessário — incluído internamente |
RapidOcrOptions.RecModelPath | Não é necessário — incluído internamente |
RapidOcrOptions.KeysPath | Não é necessário — incluído internamente |
RapidOcrOptions.UseGpu | Não aplicável — otimizado internamente para CPU |
RapidOcrOptions.NumThreads | Use Parallel.ForEach com um IronTesseract por thread |
engine.Run(imagePath) | ocr.Read(imagePath) |
engine.Dispose() | using var ocr = new IronTesseract() |
result.TextBlocks | result.Pages[i].Words / .Lines / .Paragraphs |
result.TextBlocks[i].Text | result.Words[i].Text |
result.TextBlocks[i].Confidence | result.Words[i].Confidence |
result.TextBlocks[i].BoundingBox.Top | result.Words[i].Y |
result.TextBlocks[i].BoundingBox.Left | result.Words[i].X |
Classificação manual OrderBy(b => b.BoundingBox.Top) | Não é necessário — result.Text está em ordem de leitura |
string.Join("\n", result.TextBlocks.Select(b => b.Text)) | result.Text |
| Troca de arquivo de idioma (baixar modelo diferente) | ocr.Language = OcrLanguage.French |
| Reconstrução do mecanismo para mudança de idioma | Não é necessário — defina ocr.Language por chamada |
PDF-para-imagem + loop engine.Run() | ocr.Read("document.pdf") |
| Divisão manual de quadros TIFF multiframe | input.LoadImageFrames("document.tiff") |
| Sem capacidade de pesquisa em PDF | result.SaveAsSearchablePdf("output.pdf") |
| Sem capacidade de leitura de código de barras | ocr.Configuration.ReadBarCodes = true |
Problemas e soluções comuns em migrações
Problema 1: O diretório de modelos ainda existe após a migração.
RapidOCR.NET: O diretório models/ no projeto contém det.onnx, cls.onnx, rec_en.onnx e en_keys.txt, juntamente com entradas de MSBuild <Content> que os copiam na compilação. Após a mudança para o IronOCR, este diretório e essas entradas permanecem e continuam a aumentar o tamanho do arquivo de saída da compilação.
Solução: Exclua o diretório models/, remova o correspondente <ItemGroup> de .csproj, e remova qualquer lógica de validação de inicialização que verificava arquivos ausentes. Também remova a referência NuGet Microsoft.ML.OnnxRuntime se ela foi instalada separadamente. O resultado publicado de uma aplicação .NET que utiliza o IronOCR não contém arquivos de modelo externos.
<!-- Remove this entire block from .csproj -->
<ItemGroup>
<Content Include="models\**\*.*">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
Edição 2: Padrão de Construção de Motor por Thread
RapidOCR.NET: Código de processamento paralelo que criava um novo RapidOcrEngine por thread para evitar problemas de estado compartilhado carregava um custo significativo de memória: cada instância do motor carregava 300–500 MB de pesos de modelo ONNX independentemente.
Solução: Instâncias IronTesseract do IronOCR são seguras para threads e leves. Crie uma por thread em um Parallel.ForEach sem se preocupar com o custo de carregamento de modelo por instância. A abordagem do IronOCR é idêntica ao exemplo de migração de processamento em lote acima — IronTesseract lida com esse cenário com o mesmo padrão de construção por thread, mas sem o custo de carregamento de modelo de 300–500 MB que cada instância RapidOcrEngine tinha. O exemplo de multithreading mostra o padrão padrão para pipelines de alto desempenho.
Problema 3: Exceção de idioma não suportado
RapidOCR .NET: O código que encaminhava documentos não-CJK pelo RapidOCR .NET — ou tentava construir um mecanismo com um modelo inexistente para espanhol/francês/alemão — gerava um erro de arquivo não encontrado em tempo de execução ou produzia resultados vazios.
Solução: Instale o pacote NuGet de pacote de idiomas apropriado e defina ocr.Language para o valor de enumeração alvo OcrLanguage. Sem necessidade de baixar modelos, reconstruir motores ou criar caminhos de código adicionais para cada idioma:
var ocr = new IronTesseract();
ocr.Language = OcrLanguage.Spanish;
var result = ocr.Read("spanish-document.jpg");
O guia de pacotes de idiomas personalizados aborda configurações avançadas de idiomas que vão além dos mais de 125 pacotes padrão.
Problema 4: A lógica de classificação de blocos de texto para de funcionar após a migração.
RapidOCR.NET: Como result.TextBlocks era uma lista plana não ordenada, bases de códigos geralmente continham cadeias .OrderBy(b => b.BoundingBox.Top).ThenBy(b => b.BoundingBox.Left) espalhadas por todo o código de processamento de resultados.
Solução: Elimine completamente essa lógica de ordenação. result.Text no IronOCR já está montado em ordem natural de leitura. Para o código que também consumia coordenadas de caixa delimitadora dos blocos ordenados, substitua a referência do bloco por result.Pages[i].Words[j]:
// Before: manual sort + coordinate extraction
var sorted = result.TextBlocks
.OrderBy(b => b.BoundingBox.Top)
.ThenBy(b => b.BoundingBox.Left);
foreach (var block in sorted)
Console.WriteLine($"{block.Text} at ({block.BoundingBox.Left}, {block.BoundingBox.Top})");
// After: structured access, already in order
foreach (var page in result.Pages)
foreach (var word in page.Words)
Console.WriteLine($"{word.Text} at ({word.X}, {word.Y})");
Problema 5: O pipeline CI/CD falha após a remoção dos arquivos de modelo.
RapidOCR.NET: Linhas de montagem que armazenavam em cache ou buscavam o diretório models/ como um passo separado — seja de um armazenamento de artefatos, um bucket S3 compartilhado ou um repositório Git LFS — falharão quando esses passos não encontrarem nada para restaurar após a migração.
Solução: Remova completamente as etapas de busca e armazenamento em cache do arquivo de modelo do pipeline de CI. O motor do IronOCR é restaurado como parte do passo de dotnet restore padrão. Não são necessários estágios adicionais de pipeline. Para implantações em contêineres, remova quaisquer instruções Docker COPY models/ ./models/ — o guia de implantação Docker do IronOCR documenta o único pacote de sistema necessário (libgdiplus em imagens Debian/Ubuntu) e nada mais.
Problema 6: Conflitos de versão do ONNX Runtime após migração parcial
RapidOCR.NET: Aplicações que também utilizam outros pacotes ML baseados em ONNX (ML.NET, detecção de objetos ONNX, etc.) podem ter fixado Microsoft.ML.OnnxRuntime em uma versão específica para compatibilidade com RapidOCR.NET. A remoção do RapidOCR .NET pode expor conflitos de versão em outros pacotes.
Solução: Remova Microsoft.ML.OnnxRuntime da lista explícita de pacotes.IronOCR não tem dependência do Tempo de Execução de ONNX, então remover a referência RapidOCR.NET elimina completamente a fixação da versão. Outros pacotes de aprendizado de máquina que realmente exigem o ONNX Runtime podem então resolver sua própria versão compatível por meio da resolução de dependências padrão do NuGet, sem a restrição do RapidOCR .NET .
Lista de verificação para migração do RapidOCR for .NET
Tarefas pré-migração
Antes de fazer alterações, audite o código-fonte para verificar se todas as dependências do RapidOCR .NET estão sendo utilizadas:
# Find all files that reference RapidOcrNet
grep -r "RapidOcrNet\|RapidOcrEngine\|RapidOcrOptions" --include="*.cs" .
# Find model path configuration
grep -r "DetModelPath\|ClsModelPath\|RecModelPath\|KeysPath" --include="*.cs" .
# Find MSBuild model copy entries
grep -r "det\.onnx\|cls\.onnx\|rec.*\.onnx\|keys\.txt" --include="*.csproj" .
# Find model validation logic
grep -r "ValidateModel\|models/" --include="*.cs" .
# Find ONNX Runtime references
grep -r "OnnxRuntime\|Microsoft\.ML" --include="*.csproj" .
# Find language-switching patterns (multiple engine instances per language)
grep -r "CreateEnglishEngine\|CreateChineseEngine\|rec_en\|ch_rec\|en_keys\|ch_keys" --include="*.cs" .
Inventarie os resultados: anote cada lugar onde um motor é criado, cada lugar onde caminhos de modelo são configurados, cada lugar onde blocos de texto são ordenados, e cada lugar onde a conversão de PDF para imagem alimenta em engine.Run().
Tarefas de atualização de código
- Remova a referência ao pacote NuGet
RapidOcrNetde todos os arquivos.csproj. - Remova a referência ao pacote NuGet
Microsoft.ML.OnnxRuntimede todos os arquivos.csproj. - Instale o pacote NuGet
IronOcr. - Instale os pacotes NuGet de idiomas para quaisquer idiomas que não sejam inglês que o aplicativo exija.
- Exclua o diretório
models/do projeto e do repositório. - Remova as entradas MSBuild
<Content Include="models\**\*.*">de todos os arquivos.csproj. - Remova métodos de validação de modelo de inicialização (os métodos do tipo
EnsureModelsPresent). - Substitua
using RapidOcrNetporusing IronOcrem todos os arquivos de origem. - Substitua
new RapidOcrEngine(new RapidOcrOptions { ... })withnew IronTesseract(). - Substitua
engine.Run(imagePath)porocr.Read(imagePath). - Substitua cadeias de montagem
result.TextBlocks(.OrderBy().Select(b => b.Text)) porresult.Text. - Substitua a extração de campo de filtro de coordenadas por entrada de região
CropRectangle. - Substitua a construção de motor por thread pela construção
IronTesseractpor thread. - Substitua métodos de fábrica de motor específicos de idioma pelas atribuições
ocr.Language = OcrLanguage.X. - Remova o código de conversão de PDF para imagem e substitua por chamadas
ocr.Read("file.pdf")diretas. - Remova o código de divisão de quadros TIFF de múltiplos quadros e substitua por
input.LoadImageFrames("file.tiff"). - Adicione
IronOcr.License.LicenseKey = "YOUR-LICENSE-KEY"na inicialização da aplicação. - Remover as etapas de busca e armazenamento em cache do arquivo de modelo das definições do pipeline de CI/CD.
- Remova instruções
COPYdo modelo ONNX dos arquivos Docker.
Testes pós-migração
- Verificar se todos os caminhos de OCR de imagem existentes retornam texto com precisão igual ou superior à saída do RapidOCR .NET .
- Confirme que a ordem de leitura
result.Textcorresponde à sequência de campos esperada para cada tipo de documento. - Teste leituras com troca de idioma para cada valor
OcrLanguageque a aplicação usa. Execute o processador em lote paralelo e confirme que não há erros de contenção de threads ou problemas de resultados obsoletos. - Verificar se o processamento TIFF de múltiplos quadros retorna o número correto de páginas com o texto correto em cada página.
- Teste extração de campos de formulário via
CropRectanglecontra as regiões de coordenadas esperadas. - Confirme que o diretório
models/está ausente da saída de construção e dos pacotes de implantação. - Execute o pipeline de CI de ponta a ponta e confirme se não restam etapas de busca de modelo.
- Construa e execute um contêiner Docker e confirme que não há erros de camada
COPY models/ou arquivo não encontrado na inicialização. - Realizar um teste de tempo de inicialização para verificar se a latência de inicialização a frio diminuiu.
Principais benefícios da migração para o IronOCR
A Implantação Agora é Determinística. dotnet restore e dotnet publish produzem uma implantação OCR completa e funcional sem dependências de arquivos externos. O mesmo comando NuGet restore que instala a versão do pacote também instala tudo o que o mecanismo precisa para funcionar. Não há arquivos de modelo para versionar separadamente, nenhuma etapa de cache de CI para configurar e nenhum script de validação de implantação para manter. O processo de instalação é tão simples quanto qualquer outra dependência de pacote .NET .
A Cobertura de Idiomas Escala com os Requisitos de Negócio. Adicionar suporte para um novo idioma de documento significa executar dotnet add package IronOcr.Languages.X e definir ocr.Language. Não há verificação de disponibilidade do modelo upstream, nenhum download do modelo e nenhuma refatoração do mecanismo. Equipes que começam com OCR em inglês e posteriormente precisam processar contratos em alemão, faturas em árabe ou pedidos de compra em russo ampliam a abrangência sem alterar a arquitetura do aplicativo. Todos os mais de 125 pacotes de idiomas seguem o mesmo padrão de instalação.
A Saída Estruturada Elimina o Código de Montagem de Coordenadas. A hierarquia result.Pages, .Paragraphs, .Lines, .Words e .Characters substitui a lista plana TextBlocks e a lógica de ordenação que contornava sua falta de estrutura. O código que extraía o texto da ordem de leitura classificando as coordenadas dos blocos foi removido. O código que precisava de caixas delimitadoras por palavra as obtém de word.X, word.Y, word.Width, word.Height sem filtragem de interseção. Os resultados do OCR apresentam na página o modelo de saída completo.
O processamento de PDF e TIFF não requer bibliotecas externas. Os dois formatos de documento mais comuns além de JPGs de imagem única — PDFs com várias páginas e TIFFs com vários quadros — são processados nativamente pelo IronOCR. Toda a biblioteca externa que foi adicionada à árvore de dependência para suportar engine.Run() com entrada PDF ou TIFF pode ser removida. Resultado final: menos pacotes para atualizar, menos problemas de compatibilidade de versões e arquivos de projeto mais simples. Os guias de entrada de PDF e TIFF abordam ambos os formatos em detalhes.
Incidentes em produção têm um caminho de suporte. As licenças comerciais incluem suporte direto por e-mail com um ponto de contato para problemas que não podem esperar por uma resposta no GitHub . Equipes com obrigações de SLA ou fluxos de processamento de documentos críticos para os negócios podem encaminhar incidentes para os engenheiros que mantêm a biblioteca, em vez de esperar por uma resposta da comunidade. O centro de documentação do IronOCR fornece documentação de referência juntamente com esse caminho de suporte.
A Licença Perpétua $999 É um Custo Único. Não há cobrança por página, não há cobrança por transação e não há renovação anual que reabra a discussão sobre custo. As equipes de desenvolvimento que calcularam o custo das horas de engenharia gastas em gerenciamento de modelos, soluções alternativas para conversão de PDF, manutenção do pipeline de CI e escalonamento de problemas com idiomas não suportados constataram, consistentemente, que a comparação é favorável em relação ao custo da licença.
