Large TIFF Files Over 2 GB Fail to Load
IronOCR loads image input into a single in-memory buffer through its internal AnyBitmap type. That buffer is indexed by a 32-bit integer, so it caps at roughly 2 GB regardless of how much system memory you have. A TIFF larger than 2 GB exceeds this limit and fails to load.
Loaded pages: 0
OcrInput.LoadImage(filePath) creates an AnyBitmap internally and materializes the whole image into one buffer. Because that buffer is indexed by int, it is effectively limited to about 2 GB no matter how much memory is free, so a TIFF slightly over the limit cannot be held and the load fails. This is a runtime constraint, not OS-specific, so it affects every .NET platform equally.
LoadImage(filePath) currently returns zero loaded pages instead of throwing a clear exception. This silent failure is a known issue; a clearer exception is planned. The single-buffer design is an architectural limit, and native per-page TIFF streaming is not yet available.Solution
The fix is to split the TIFF into sub-2 GB chunks and pass each chunk to IronOCR as a byte array rather than a file path.
1. Add Magick.NET
Use Magick.NET to split the TIFF before handing it to IronOCR. Pick the variant that matches your project (Q8/Q16, AnyCPU/x64).
dotnet add package Magick.NET-Q16-AnyCPU
dotnet add package Magick.NET-Q16-AnyCPU
2. Split the TIFF and Load Each Chunk
Open the TIFF as a MagickImageCollection, break it into page-count chunks that each stay under 2 GB, convert every chunk to a byte array, and load it with 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
Each chunk goes through LoadImage(chunkBytes) as raw bytes, keeping every buffer under the 2 GB ceiling. SetCompression(CompressionMethod.LZW) shrinks each chunk before it is converted to a byte array.
3. Tune the Chunk Size
Adjust pagesPerChunk for your data. Lower it if a chunk approaches 2 GB or if memory is tight; raise it for smaller pages to reduce overhead.
4. Account for Magick.NET in Deployment
Magick.NET ships ImageMagick native binaries. Factor in the added package size and the native dependency footprint when you deploy.

