Grandes Arquivos TIFF Acima de 2 GB Não Carregam

This article was translated from English: Does it need improvement?
Translated
View the article in English

O IronOCR carrega entradas de imagem em um único buffer na memória através de seu tipo interno AnyBitmap. Esse buffer é indexado por um inteiro de 32 bits, por isso é limitado a cerca de 2 GB, independentemente de quanta memória do sistema você tem. Um TIFF maior que 2 GB excede esse limite e falha ao carregar.

Loaded pages: 0

OcrInput.LoadImage(filePath) cria internamente um AnyBitmap e materializa a imagem inteira em um buffer. Porque esse buffer é indexado por int, ele é efetivamente limitado a cerca de 2 GB, não importa quanta memória esteja livre, então um TIFF um pouco acima do limite não pode ser mantido e o carregamento falha. Isso é uma limitação em tempo de execução, não específica do sistema operacional, portanto, afeta todas as plataformas .NET igualmente.

AvisoLoadImage(filePath) atualmente retorna zero páginas carregadas em vez de lançar uma exceção clara. Essa falha silenciosa é um problema conhecido; uma exceção mais clara está planejada. O design de um único buffer é um limite arquitetônico, e o streaming nativo de TIFF por página ainda não está disponível.

Solução

A solução é dividir o TIFF em pedaços de menos de 2 GB e passar cada pedaço para o IronOCR como um array de bytes, em vez de um caminho de arquivo.

1. Adicionar Magick.NET

Use o Magick.NET para dividir o TIFF antes de passá-lo para o IronOCR. Escolha a variante que corresponde ao seu projeto (Q8/Q16, AnyCPU/x64).

dotnet add package Magick.NET-Q16-AnyCPU
dotnet add package Magick.NET-Q16-AnyCPU
SHELL

2. Dividir o TIFF e Carregar Cada Pedaço

Abra o TIFF como um MagickImageCollection, divida-o em pedaços pelo número de páginas, cada um com menos de 2 GB, converta cada pedaço em um array de bytes e carregue-o com OcrInput.LoadImage(byte[]).

var inputPath = "input.tiff";
var pagesPerChunk = 100;
using var allPages = new MagickImageCollection(inputPath);
int chunkNumber = 1;
for (int i = 0; i < allPages.Count; i += pagesPerChunk)
{
    using var chunk = new MagickImageCollection();
    for (int j = i; j < Math.Min(i + pagesPerChunk, allPages.Count); j++)
    {
        chunk.Add(allPages[j].Clone());
    }
    foreach (var image in chunk)
    {
        image.SetCompression(CompressionMethod.LZW);
    }
    var chunkBytes = chunk.ToByteArray();
    using (var ocrInput = new OcrInput())
    {
        ocrInput.LoadImage(chunkBytes);
        var pages = ocrInput.GetPages().ToList();
        Console.WriteLine($"Loaded pages: {pages.Count}");
        var result = new IronTesseract().Read(ocrInput);
        Console.WriteLine("OCR Text Length: " + (result.Text?.Length ?? 0));
    }
    Console.WriteLine($"Chunk {chunkNumber} processed");
    chunkNumber++;
}
var inputPath = "input.tiff";
var pagesPerChunk = 100;
using var allPages = new MagickImageCollection(inputPath);
int chunkNumber = 1;
for (int i = 0; i < allPages.Count; i += pagesPerChunk)
{
    using var chunk = new MagickImageCollection();
    for (int j = i; j < Math.Min(i + pagesPerChunk, allPages.Count); j++)
    {
        chunk.Add(allPages[j].Clone());
    }
    foreach (var image in chunk)
    {
        image.SetCompression(CompressionMethod.LZW);
    }
    var chunkBytes = chunk.ToByteArray();
    using (var ocrInput = new OcrInput())
    {
        ocrInput.LoadImage(chunkBytes);
        var pages = ocrInput.GetPages().ToList();
        Console.WriteLine($"Loaded pages: {pages.Count}");
        var result = new IronTesseract().Read(ocrInput);
        Console.WriteLine("OCR Text Length: " + (result.Text?.Length ?? 0));
    }
    Console.WriteLine($"Chunk {chunkNumber} processed");
    chunkNumber++;
}
Imports System
Imports System.Linq
Imports ImageMagick

Dim inputPath As String = "input.tiff"
Dim pagesPerChunk As Integer = 100
Using allPages As New MagickImageCollection(inputPath)
    Dim chunkNumber As Integer = 1
    For i As Integer = 0 To allPages.Count - 1 Step pagesPerChunk
        Using chunk As New MagickImageCollection()
            For j As Integer = i To Math.Min(i + pagesPerChunk, allPages.Count) - 1
                chunk.Add(allPages(j).Clone())
            Next
            For Each image In chunk
                image.SetCompression(CompressionMethod.LZW)
            Next
            Dim chunkBytes = chunk.ToByteArray()
            Using ocrInput As New OcrInput()
                ocrInput.LoadImage(chunkBytes)
                Dim pages = ocrInput.GetPages().ToList()
                Console.WriteLine($"Loaded pages: {pages.Count}")
                Dim result = New IronTesseract().Read(ocrInput)
                Console.WriteLine("OCR Text Length: " & If(result.Text?.Length, 0))
            End Using
        End Using
        Console.WriteLine($"Chunk {chunkNumber} processed")
        chunkNumber += 1
    Next
End Using
$vbLabelText   $csharpLabel

Cada pedaço passa por LoadImage(chunkBytes) como bytes brutos, mantendo cada buffer abaixo do limite de 2 GB. SetCompression(CompressionMethod.LZW) reduz cada pedaço antes de ser convertido em um array de bytes.

3. Ajustar o Tamanho dos Pedaços

Ajuste pagesPerChunk para seus dados. Reduza-o se um pedaço se aproximar de 2 GB ou se a memória estiver apertada; aumente-o para páginas menores para reduzir a sobrecarga.

4. Contabilizar o Magick.NET na Implantação

Magick.NET envia binários nativos do ImageMagick. Considere o tamanho adicional do pacote e a pegada de dependência nativa ao implantar.

Curtis Chau
Redator Técnico

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

Leia mais
Pronto para começar?
Nuget Baixar 6,136,090 | Versão: 2026.7 recém-lançado
Still Scrolling Icon

Ainda está rolando a tela?

Quer provas rápidas? PM > Install-Package IronOcr
executar um exemplo Veja sua imagem se transformar em texto pesquisável.