Les fichiers TIFF volumineux de plus de 2 Go ne se chargent pas
IronOCR charge l'entrée de l'image dans un seul tampon en mémoire via son type interne AnyBitmap. Ce tampon est indexé par un entier 32 bits, donc il est limité à environ 2 Go, peu importe la quantité de mémoire système disponible. Un TIFF de plus de 2 Go dépasse cette limite et ne se charge pas.
Loaded pages: 0
OcrInput.LoadImage(filePath) crée un AnyBitmap en interne et matérialise l'image entière dans un seul tampon. Parce que ce tampon est indexé par int, il est effectivement limité à environ 2 Go, peu importe la quantité de mémoire disponible, donc un TIFF légèrement au-dessus de la limite ne peut pas être conservé et le chargement échoue. C'est une contrainte d'exécution, non spécifique à l'OS, donc cela affecte chaque plateforme .NET de manière égale.
LoadImage(filePath) retourne actuellement zéro page chargée au lieu de lancer une exception claire. Cet échec silencieux est un problème connu ; une exception plus claire est prévue. Le design à tampon unique est une limite architecturale, et le streaming TIFF par page natif n'est pas encore disponible.Solution
La solution est de scinder le TIFF en morceaux de moins de 2 Go et de passer chaque morceau à IronOCR sous forme de tableau d'octets plutôt que de chemin de fichier.
1. Ajoutez Magick.NET
Utilisez Magick.NET pour diviser le TIFF avant de le remettre à IronOCR. Choisissez la variante qui correspond à votre projet (Q8/Q16, AnyCPU/x64).
dotnet add package Magick.NET-Q16-AnyCPU
dotnet add package Magick.NET-Q16-AnyCPU
2. Divisez le TIFF et chargez chaque morceau
Ouvrez le TIFF en tant que MagickImageCollection, divisez-le en morceaux comptant le nombre de pages, chaque morceau restant sous 2 Go, convertissez chaque morceau en tableau d'octets et chargez-le avec 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
Chaque morceau passe par LoadImage(chunkBytes) sous forme de bytes bruts, gardant chaque tampon sous la limite de 2 Go. SetCompression(CompressionMethod.LZW) réduit chaque morceau avant qu'il ne soit converti en tableau d'octets.
3. Ajustez la taille des morceaux
Ajustez pagesPerChunk pour vos données. Réduisez-la si un morceau approche 2 Go ou si la mémoire est limitée ; augmentez-la pour les pages plus petites pour réduire les frais généraux.
4. Prenez en compte Magick.NET dans le déploiement
Magick.NET livre des exécutables natifs ImageMagick. Tenez compte de l'augmentation de la taille du package et de l'empreinte de dépendance native lors de votre déploiement.

