# Duże pliki TIFF powyżej 2 GB nie ładują się
IronOCR ładuje dane wejściowe obrazu do jednego bufora w pamięci za pomocą swojego wewnętrznego typu `AnyBitmap`. Ten bufor jest indeksowany przez 32-bitową liczbę całkowitą, więc ogranicza się do około 2 GB niezależnie od ilości dostępnej pamięci systemowej. TIFF większy niż 2 GB przekracza ten limit i nie ładuje się.
```txt
Loaded pages: 0
```
`OcrInput.LoadImage(filePath)` tworzy wewnętrznie `AnyBitmap` i materializuje cały obraz w jednym buforze. Ponieważ ten bufor jest indeksowany przez `int`, jest skutecznie ograniczony do około 2 GB niezależnie od dostępnej pamięci, dlatego TIFF nieco powyżej limitu nie może być przechowywany i ładowanie nie powodzi się. To ograniczenie runtime, nie specyficzne dla systemu operacyjnego, więc wpływa na każdą platformę .NET równomiernie.
[[w:(`LoadImage(filePath)` obecnie zwraca zero załadowanych stron zamiast wyrzucania czytelnego wyjątku. To ciche niepowodzenie jest znanym problemem; planowany jest czytelniejszy wyjątek. Projekt jednobuforowy to ograniczenie architektoniczne, a natywne strumieniowanie TIFF na stronę nie jest jeszcze dostępne.)]]
## Rozwiązanie
Rozwiązaniem jest podzielenie TIFF na fragmenty mniejsze niż 2 GB i przekazanie każdego fragmentu do IronOCR jako tablicy bajtów zamiast ścieżki do pliku.
### 1. Dodaj Magick.NET
Użyj Magick.NET do podzielenia TIFF przed przekazaniem do IronOCR. Wybierz wariant pasujący do twojego projektu (Q8/Q16, AnyCPU/x64).
```bash
dotnet add package Magick.NET-Q16-AnyCPU
```
### 2. Podziel TIFF i załaduj każdy fragment
Otwórz TIFF jako `MagickImageCollection`, podziel go na fragmenty o ilości stron, które każdy pozostanie poniżej 2 GB, konwertuj każdy fragment na tablicę bajtów i załaduj go za pomocą `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++;
}
```
Każdy fragment przechodzi przez `LoadImage(chunkBytes)` jako surowe bajty, co utrzymuje każdy bufor poniżej granicy 2 GB. `SetCompression(CompressionMethod.LZW)` zmniejsza każdy fragment przed konwersją do tablicy bajtów.
### 3. Dostosuj rozmiar fragmentu
Dostosuj `pagesPerChunk` dla twoich danych. Obniż go, jeśli fragment zbliża się do 2 GB lub jeśli pamięć jest ograniczona; zwiększ go dla mniejszych stron, aby zmniejszyć narzuty.
### 4. Uwzględnij Magick.NET w wdrożeniu
Magick.NET dostarcza natywne pliki binarne ImageMagick. Weź pod uwagę zwiększony rozmiar pakietu i ślad natywnej zależności podczas wdrażania.
IronOCR ładuje dane wejściowe obrazu do jednego bufora w pamięci za pomocą swojego wewnętrznego typu AnyBitmap. Ten bufor jest indeksowany przez 32-bitową liczbę całkowitą, więc ogranicza się do około 2 GB niezależnie od ilości dostępnej pamięci systemowej. TIFF większy niż 2 GB przekracza ten limit i nie ładuje się.
Loaded pages: 0
Loaded pages: 0
Text
OcrInput.LoadImage(filePath) tworzy wewnętrznie AnyBitmap i materializuje cały obraz w jednym buforze. Ponieważ ten bufor jest indeksowany przez int, jest skutecznie ograniczony do około 2 GB niezależnie od dostępnej pamięci, dlatego TIFF nieco powyżej limitu nie może być przechowywany i ładowanie nie powodzi się. To ograniczenie runtime, nie specyficzne dla systemu operacyjnego, więc wpływa na każdą platformę .NET równomiernie.
Ostrzeżenie: LoadImage(filePath) obecnie zwraca zero załadowanych stron zamiast wyrzucania czytelnego wyjątku. To ciche niepowodzenie jest znanym problemem; planowany jest czytelniejszy wyjątek. Projekt jednobuforowy to ograniczenie architektoniczne, a natywne strumieniowanie TIFF na stronę nie jest jeszcze dostępne.
Rozwiązanie
Rozwiązaniem jest podzielenie TIFF na fragmenty mniejsze niż 2 GB i przekazanie każdego fragmentu do IronOCR jako tablicy bajtów zamiast ścieżki do pliku.
1. Dodaj Magick.NET
Użyj Magick.NET do podzielenia TIFF przed przekazaniem do IronOCR. Wybierz wariant pasujący do twojego projektu (Q8/Q16, AnyCPU/x64).
dotnet add package Magick.NET-Q16-AnyCPU
dotnet add package Magick.NET-Q16-AnyCPU
SHELL
2. Podziel TIFF i załaduj każdy fragment
Otwórz TIFF jako MagickImageCollection, podziel go na fragmenty o ilości stron, które każdy pozostanie poniżej 2 GB, konwertuj każdy fragment na tablicę bajtów i załaduj go za pomocą 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#
Każdy fragment przechodzi przez LoadImage(chunkBytes) jako surowe bajty, co utrzymuje każdy bufor poniżej granicy 2 GB. SetCompression(CompressionMethod.LZW) zmniejsza każdy fragment przed konwersją do tablicy bajtów.
3. Dostosuj rozmiar fragmentu
Dostosuj pagesPerChunk dla twoich danych. Obniż go, jeśli fragment zbliża się do 2 GB lub jeśli pamięć jest ograniczona; zwiększ go dla mniejszych stron, aby zmniejszyć narzuty.
4. Uwzględnij Magick.NET w wdrożeniu
Magick.NET dostarcza natywne pliki binarne ImageMagick. Weź pod uwagę zwiększony rozmiar pakietu i ślad natywnej zależności podczas wdrażania.
Curtis Chau posiada tytuł licencjata z informatyki (Uniwersytet Carleton) i specjalizuje się w front-endowym rozwoju, z ekspertką w Node.js, TypeScript, JavaScript i React. Pasjonuje się tworzeniem intuicyjnych i estetycznie przyjemnych interfejsów użytkownika, Curtis cieszy się pracą z nowoczesnymi frameworkami i tworzeniem dobrze zorganizowanych, atrakcyjnych wizualnie podręczników.