2 GB Üzerindeki Büyük TIFF Dosyaları Yüklenemiyor
IronOCR, resim girdisini kendi içindeki AnyBitmap türü aracılığıyla tek bir hafıza içi arabelleğe yükler. Bu tampon 32-bit bir tamsayı ile indekslenir, bu nedenle sistem belleğinizde ne kadar olduğundan bağımsız olarak, yaklaşık 2 GB ile sınırlandırılır. 2 GB'den büyük bir TIFF bu sınırı aşar ve yüklenemez.
Loaded pages: 0
OcrInput.LoadImage(filePath) dahili olarak bir AnyBitmap oluşturur ve tüm resmi tek bir arabelleğe materyalize eder. Bu arabelleğin int ile indekslenmesi nedeniyle, kullanılan bellek ne kadar serbest olursa olsun yaklaşık 2 GB ile sınırlıdır, bu yüzden limitin biraz üzerindeki bir TIFF tutulamaz ve yükleme başarısız olur. Bu bir çalışma zamanı kısıtlamasıdır, işletim sistemine özgü değildir, bu yüzden her .NET platformunu eşit şekilde etkiler.
LoadImage(filePath), açık bir istisna atmak yerine şu anda sıfır yüklü sayfa döndürmektedir. Bu sessiz başarısızlık bilinen bir sorundur; daha net bir istisna planlanıyor. Tek tampon tasarımı mimari bir sınırdır ve yerel her sayfa için TIFF akışı henüz mevcut değildir.Çözüm
Çözüm, TIFF'i 2 GB'ın altında parçalara bölmek ve her parçayı dosya yolu yerine bir bayt dizisi olarak IronOCR'ye iletmektir.
1. Magick.NET Ekleyin
Magick.NET'i kullanarak TIFF'i IronOCR'ye iletmeden önce bölün. Projenizle eşleşen varyantı seçin (Q8/Q16, AnyCPU/x64).
dotnet add package Magick.NET-Q16-AnyCPU
dotnet add package Magick.NET-Q16-AnyCPU
2. TIFF'i Bölün ve Her Parçayı Yükleyin
TIFF'i MagickImageCollection olarak açın, 2 GB altında kalan sayfa sayısı parçalarına ayırın, her parçayı byte dizisine dönüştürün ve OcrInput.LoadImage(byte[]) ile yükleyin.
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
Her parça, her bir arabelleği 2 GB tavanın altında tutarak LoadImage(chunkBytes) içinden ham byte olarak geçer. SetCompression(CompressionMethod.LZW), bir byte dizisine dönüştürülmeden önce her parçayı küçültür.
3. Parça Boyutunu Ayarlayın
Verileriniz için pagesPerChunk ayarlayın. Bir parça 2 GB'a yaklaşıyorsa veya bellek dar ise düşürün; küçük sayfalar için yükü azaltmak üzere artırın.
4. Dağıtımda Magick.NET'i Hesaba Katın
Magick.NET, ImageMagick yerlisi ikili dosyalarını taşır. Dağıttığınızda ek paket boyutu ve doğal bağımlılık ayak izini hesaba katın.

