# Große TIFF-Dateien über 2 GB schlagen fehl beim Laden
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.
```txt
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.
[[w:(`LoadImage(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).
```bash
dotnet add package Magick.NET-Q16-AnyCPU
```
### 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[])`.
```csharp
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++;
}
```
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.
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
Loaded pages: 0
Text
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.
Warnung: LoadImage(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++;
}
C#
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 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 Handbücher.