在 IronOCR 中处理大 PDF 文件
在大型多页 PDF 上运行 OCR 会激增内存并导致进程崩溃。 通常的罪魁祸首是一次将所有页面加载到内存中。
System.OutOfMemoryException
OcrInput.LoadPdf("large.pdf") 一次性读取所有页面。 IronOCR 的成像系统随后同时渲染每个页面,而且因为 DPI 默认为 OutOfMemoryException 或资源死锁。
解决方案
解决方法是逐个页面处理 PDF 并保持渲染 DPI 尽可能低以容许的文本质量。
1. 获取页面数
using IronPdf.PdfDocument (或任何 PDF 库)打开文档以读取页面数。
using var pdf = IronPdf.PdfDocument.FromFile(pdfPath);
var pageCount = pdf.PageCount;
using var pdf = IronPdf.PdfDocument.FromFile(pdfPath);
var pageCount = pdf.PageCount;
Imports IronPdf
Using pdf = IronPdf.PdfDocument.FromFile(pdfPath)
Dim pageCount = pdf.PageCount
End Using
2. 一次加载一个页面
循环浏览页面,使用 OcrInput.LoadPdfPage("file.pdf", pageIndex, dpi) 单独加载每一页。 在视觉质量得到保持的情况下,将 DPI 降到 80 以下以节省内存。
3. 读取和连接
将每个单页输入传递给 IronTesseract.Read() 并将结果追加到 StringBuilder。
var ocr = new IronTesseract();
var pdfPath = "large.pdf";
using var pdf = IronPdf.PdfDocument.FromFile(pdfPath);
var pageCount = pdf.PageCount;
var textBuilder = new StringBuilder();
for (int i = 0; i < pageCount; i++)
{
using var input = new OcrInput();
input.LoadPdfPage(pdfPath, i, 80);
var result = ocr.Read(input);
textBuilder.Append(result.Text);
textBuilder.Append(' '); // Add space between pages
}
Console.WriteLine(textBuilder.ToString().Trim());
var ocr = new IronTesseract();
var pdfPath = "large.pdf";
using var pdf = IronPdf.PdfDocument.FromFile(pdfPath);
var pageCount = pdf.PageCount;
var textBuilder = new StringBuilder();
for (int i = 0; i < pageCount; i++)
{
using var input = new OcrInput();
input.LoadPdfPage(pdfPath, i, 80);
var result = ocr.Read(input);
textBuilder.Append(result.Text);
textBuilder.Append(' '); // Add space between pages
}
Console.WriteLine(textBuilder.ToString().Trim());
Imports IronOcr
Imports IronPdf
Imports System.Text
Dim ocr As New IronTesseract()
Dim pdfPath As String = "large.pdf"
Using pdf = PdfDocument.FromFile(pdfPath)
Dim pageCount As Integer = pdf.PageCount
Dim textBuilder As New StringBuilder()
For i As Integer = 0 To pageCount - 1
Using input As New OcrInput()
input.LoadPdfPage(pdfPath, i, 80)
Dim result = ocr.Read(input)
textBuilder.Append(result.Text)
textBuilder.Append(" ") ' Add space between pages
End Using
Next
Console.WriteLine(textBuilder.ToString().Trim())
End Using
using 在每个 OcrInput 上释放页面的图像数据,这样内存可以在循环中保持平稳,而不是随着页面数而增加。
选项:先压缩 PDF
对于非常复杂或图像密集的文件,逐页循环可能仍然困难。 在执行 OCR 之前使用 IronPDF 的 Compress API 压缩 PDF 以减少 IronOCR 需要处理的图像数据。 这在扫描或图像密集的文档上最有效。
直接压缩到流中,然后将该流加载到 OcrInput:
var pdf = PdfDocument.FromFile(pdfPath);
var stream = pdf.CompressPdfToStream(CompressStructTree: true);
var ocrTesseract = new IronTesseract();
using var ocrInput = new OcrInput();
ocrInput.LoadPdfPage(stream, 1);
var pdf = PdfDocument.FromFile(pdfPath);
var stream = pdf.CompressPdfToStream(CompressStructTree: true);
var ocrTesseract = new IronTesseract();
using var ocrInput = new OcrInput();
ocrInput.LoadPdfPage(stream, 1);
Imports IronTesseract
Dim pdf = PdfDocument.FromFile(pdfPath)
Dim stream = pdf.CompressPdfToStream(CompressStructTree:=True)
Dim ocrTesseract = New IronTesseract()
Using ocrInput As New OcrInput()
ocrInput.LoadPdfPage(stream, 1)
End Using
当 PDF 内含嵌入图像时,在压缩时降低 JpegQuality 以进一步缩减数据:
var pdf = PdfDocument.FromFile(@"D:\hugePdf.pdf");
var stream = pdf.CompressPdfToStream(JpegQuality: 75, CompressStructTree: true);
var pdf = PdfDocument.FromFile(@"D:\hugePdf.pdf");
var stream = pdf.CompressPdfToStream(JpegQuality: 75, CompressStructTree: true);
Imports System
Dim pdf = PdfDocument.FromFile("D:\hugePdf.pdf")
Dim stream = pdf.CompressPdfToStream(JpegQuality:=75, CompressStructTree:=True)
调试提示
- 降低 DPI:将
80的值设为100范围内,当文本仍清晰可读时大幅减少内存使用。 - 避免在大文件上
LoadPdf():只有在文档真正小的时候才一次性读取整个文档。 - 提早释放:将
OcrInput封装在using语句中,以便在页面之间释放内存。 - 小心并行化:只有在机器有额外内存和 CPU 时才同时处理页面; 这在大型 PDF 上适得其反。

