Große TIFF-Dateien über 2 GB schlagen fehl beim Laden

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

IronOCR lädt Bilddaten in einen einzigen Speicherpuffer durch seinen internen AnyBitmap-Typ. Dieser Puffer wird durch einen 32-Bit-Integer indiziert, sodass er unabhängig davon, wie viel Systemspeicher Sie haben, auf etwa 2 GB beschränkt ist. Ein TIFF, das größer als 2 GB ist, überschreitet dieses Limit und schlägt beim Laden fehl.

Loaded pages: 0

OcrInput.LoadImage(filePath) erstellt intern einen AnyBitmap und materialisiert das gesamte Bild in einem Puffer. Da dieser Puffer durch int indexiert wird, ist er effektiv auf etwa 2 GB begrenzt, unabhängig davon, wie viel Speicher frei ist. Daher kann ein TIFF, das leicht über dem Limit liegt, nicht gehalten werden und der Ladevorgang schlägt fehl. Dies ist eine Laufzeitbeschränkung, nicht betriebssystemspezifisch, sodass es jede .NET-Plattform gleichermaßen betrifft.

WarnungLoadImage(filePath) gibt derzeit null geladene Seiten zurück, anstatt eine klare Ausnahme zu werfen. Dieser stillstehende Fehler ist ein bekanntes Problem; eine klarere Exception ist geplant. Das Single-Buffer-Design ist ein architektonisches Limit und natives per-page TIFF-Streaming ist derzeit nicht verfügbar.

Lösung

Die Lösung besteht darin, das TIFF in unter-2-GB-Stücke aufzuteilen und jedes Stück als Byte-Array an IronOCR weiterzugeben, anstatt einen Dateipfad.

1. Fügen Sie Magick.NET hinzu

Verwenden Sie Magick.NET, um das TIFF zu teilen, bevor Sie es an IronOCR weiterleiten. Wählen Sie die Variante, die zu Ihrem Projekt passt (Q8/Q16, AnyCPU/x64).

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

2. Teilen Sie das TIFF und laden Sie jeden Abschnitt

Öffnen Sie das TIFF als MagickImageCollection, unterteilen Sie es in Seitenzählungsstücke, die jeweils unter 2 GB bleiben, konvertieren Sie jedes Stück in ein Byte-Array und laden Sie es mit 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

Jedes Stück geht als rohe Bytes durch LoadImage(chunkBytes), wobei jeder Puffer unter dem 2 GB-Limit bleibt. SetCompression(CompressionMethod.LZW) verkleinert jedes Stück, bevor es in ein Byte-Array umgewandelt wird.

3. Abstimmen der Abschnittsgröße

Passen Sie pagesPerChunk an Ihre Daten an. Senken Sie es, wenn ein Abschnitt nahe an 2 GB herankommt oder wenn der Speicher knapp ist; erhöhen Sie es für kleinere Seiten, um den Overhead zu reduzieren.

4. Berücksichtigen Sie Magick.NET bei der Bereitstellung

Magick.NET liefert native ImageMagick-Binärdateien. Berücksichtigen Sie die hinzugefügte Paketgröße und den nativen Abhängigkeitsfußabdruck bei der Bereitstellung.

Curtis Chau
Technischer Autor

Curtis Chau hat einen Bachelor-Abschluss in Informatik von der Carleton University und ist spezialisiert auf Frontend-Entwicklung mit Expertise in Node.js, TypeScript, JavaScript und React. Leidenschaftlich widmet er sich der Erstellung intuitiver und ästhetisch ansprechender Benutzerschnittstellen und arbeitet gerne mit modernen Frameworks sowie der Erstellung gut strukturierter, optisch ansprechender ...

Weiterlesen
Bereit anzufangen?
Nuget Downloads 6,136,090 | Version: 2026.7 gerade veröffentlicht
Still Scrolling Icon

Scrollst du immer noch?

Sie brauchen schnell einen Beweis? PM > Install-Package IronOcr
Führen Sie ein Beispiel aus und beobachten Sie, wie Ihr Bild zu durchsuchbarem Text wird.