在IronOCR中處理大型PDF文件

This article was translated from English: Does it need improvement?
Translated
View the article in English

在大型多頁PDF上運行OCR可能會導致記憶體激增並使過程崩潰。 通常的罪魁禍首是將每一頁都一次載入到記憶體中。

System.OutOfMemoryException

OcrInput.LoadPdf("large.pdf") 一次性讀取所有頁面。 IronOCR 的影像系統然後同時渲染每一頁,因為 DPI 預設為 200,所以記憶體的占用會很快增加。在大文件上,這意味著 OutOfMemoryException 或資源死鎖。

解決方案

解決方案是一次處理PDF一頁,並保持渲染DPI在文字質量允許的情況下儘可能低。

1. 獲取頁面數量

打開文件使用 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
$vbLabelText   $csharpLabel

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

每個 OcrInput 上的 using 釋放頁面的影像資料,以便在下一次迭代之前,記憶體維持平穩,而不是隨著頁數增長。

選項:先壓縮PDF

對於非常復雜或圖像密集的文件,逐頁迴圈仍可能掙扎。 在OCR之前使用IronPDF的壓縮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
$vbLabelText   $csharpLabel

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

警告在迴圈迭代中重用相同的MemoryStream? 在每次讀取前將其位置重置為0。 一次讀取流被消耗,因此如果位置未重置,則下一次讀取失敗。

除錯提示

  • 降低 DPI: 80100 範圍內的值大幅降低記憶體使用率,同時文字仍然清晰可讀。
  • 避免在大文件上使用 LoadPdf() 僅在文件確實很小時才一次性讀取整個文件。
  • 提前處理:OcrInput 包裹在 using 語句中,這樣在頁面之間記憶體會被釋放。
  • 謹慎併行化處理:只有在機器有多餘記憶體和CPU時並行運行頁面; 在大型PDF上會事與願違。
Curtis Chau
技術作家

Curtis Chau擁有Carleton大學的電腦科學學士學位,專精於前端開發,擁有Node.js、TypeScript、JavaScript和React的專業知識。Curtis熱衷於建立直觀且美觀的使用者介面,喜愛使用現代框架並建立結構良好、視覺吸引力的手冊。

除了開發,Curtis對物聯網(IoT)有濃厚的興趣,探索創新的方法來整合硬體和軟體。在空閒時間,他喜歡玩遊戲和建立Discord機器人,結合他對技術的熱愛與創造力。

準備開始了嗎?
Nuget 下載 6,136,090 | 版本: 2026.7 剛剛發布
Still Scrolling Icon

還在滾動?

想要快速證明? PM > Install-Package IronOcr
執行範例 觀看您的圖像轉變為可搜尋文字。