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.

WarningLoadImage(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
SHELL

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
$vbLabelText   $csharpLabel

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.

Curtis Chau
Technical Writer

Curtis Chau holds a Bachelor’s degree in Computer Science (Carleton University) and specializes in front-end development with expertise in Node.js, TypeScript, JavaScript, and React. Passionate about crafting intuitive and aesthetically pleasing user interfaces, Curtis enjoys working with modern frameworks and creating well-structured, visually appealing manuals.

...

Read More
Ready to Get Started?
Nuget Downloads 6,106,091 | Version: 2026.7 just released
Still Scrolling Icon

Still Scrolling?

Want proof fast? PM > Install-Package IronOcr
run a sample watch your image become searchable text.