可搜尋 OCR 文字層
HotPDF 可以為應用程式提供的 OCR 引擎轉譯選定的已載入頁面,並以原子方式加入與每個辨識詞對齊的可搜尋隱形 Unicode 文字
SearchableOCR 主控台示範提供一條可執行的工作流程:用 --create-sample 產生三頁純影像樣本,選擇內建 OCR、RapidOCR 或 Tesseract DLL/CLI 辨識,挑選頁面,組態信心度與資源限制,然後存下帶轉換統計的可搜尋副本
引擎整合
以應用程式可取得的任何同步 OCR 提供者實作 IHPDFOCREngine
引擎透過 THPDFOCRRequest 收到借用的 TBitmap、要求的 DPI、正規化的頁面旋轉、media box 座標、剩餘的詞數與 UTF-16 額度,以及生效的取消權杖
詞框與選用的基線使用左上原點的點陣圖像素座標,Recognize 回傳之後引擎不得保留或釋放借用的點陣圖
選用的本地引擎
2.754.0 版在 Windows 上新增明確的 Tesseract 與 RapidOCR 工廠,回傳 IHPDFOCREngine;不帶引擎的多載仍選用既有的內建引擎
先在本地安裝並備妥選定的引擎再建立其轉接器,然後把轉接器傳給 ApplyLoadedOCRTextLayer 的引擎多載;執行檔、Python 套件與 OCR 模型都是選用的外部相依,HotPDF 不隨附
Tesseract
選用的原生 Tesseract DLL 轉接器透過 HPDFCreateTesseractDLLOCREngine 與 THPDFTesseractOptions,加入可設定的頁面分割與引擎模式、多語言辨識,以及原生詞基線
function HPDFCreateTesseractOCREngine(const ExecutablePath,
TessDataDirectory, Language: string;
TimeoutMilliseconds: Cardinal = 60000): IHPDFOCREngine; overload;
function HPDFCreateTesseractOCREngine(const ExecutablePath,
TessDataDirectory, Language: string;
const Options: THPDFTesseractOptions): IHPDFOCREngine; overload;
宣告位於 HPDFTesseractRecognition;提供能輸出 TSV 的 Tesseract 執行檔,以及含所需語言模型的資料目錄,例如 chi_sim 對應的 chi_sim.traineddata
選項多載接受 THPDFTesseractOptions.Default 並明確設定頁面分割、辨識引擎模式、逾時與輸入像素上限;依輸入版型挑選 tpsSingleLine、tpsSingleWord 或 tpsSparseText,做法見 Tesseract OCR 轉接器
此範例假設執行檔與資料已安裝在所示路徑,且 PDF 是已載入文件的 THotPDF 執行個體
uses SysUtils, HPDFDoc, HPDFTesseractRecognition;
procedure AddTesseractText(PDF: THotPDF);
var
Engine: IHPDFOCREngine;
Options: THPDFOCRTextLayerOptions;
Info: THPDFOCRTextLayerInfo;
begin
Engine := HPDFCreateTesseractOCREngine(
'C:\OCR\Tesseract\tesseract.exe',
'C:\OCR\Tesseract\tessdata', 'chi_sim', 60000);
Options := THPDFOCRTextLayerOptions.Default;
if not PDF.ApplyLoadedOCRTextLayer([0], Engine, Options, Info) then
raise Exception.Create('OCR text layer was not added');
end;
RapidOCR
原生 RapidOCR DLL 轉接器透過 HPDFCreateRapidOCRDLLOCREngine,以持續駐留處理程序內的 CPU ONNX 模型辨識記憶體快照,在 Delphi、C++Builder 與 Windows FPC/Lazarus 組建中支援選用的角度分類與合作式取消
RapidOCR 本地模型轉接器也提供 THPDFRapidOCROptions 多載,可明確指定 ONNX 模型路徑、選用的角度分類、本地字元字典與字型、CPU 執行緒上限與輸入像素預算,適用於 Delphi、C++Builder 與 FPC/Lazarus 組建
function HPDFCreateRapidOCREngine(const PythonExecutable, BridgeScript,
ModelDirectory: string; TimeoutMilliseconds: Cardinal = 60000): IHPDFOCREngine;
宣告位於 HPDFRapidOCRRecognition;在 Python 備妥 rapidocr 與 onnxruntime、隨附的 tools/OCR/rapidocr_tsv.py 橋接腳本,以及這三個本地模型
ch_PP-OCRv4_det_mobile.onnxch_PP-OCRv4_rec_mobile.onnxch_ppocr_mobile_v2.0_cls_mobile.onnx
橋接腳本還需要 %WINDIR%\Fonts\arial.ttf 給 RapidOCR 的結果容器、停用自動下載,並為每個設定的執行池使用一條 ONNX 執行緒;缺模型、套件或本地字型都會讓辨識失敗
目前的橋接腳本使用簡體中文模型組態,保留辨識出的標點,不做全形半形替換
uses SysUtils, HPDFDoc, HPDFRapidOCRRecognition;
procedure AddRapidOCRText(PDF: THotPDF);
var
Engine: IHPDFOCREngine;
Options: THPDFOCRTextLayerOptions;
Info: THPDFOCRTextLayerInfo;
begin
Engine := HPDFCreateRapidOCREngine(
'C:\OCR\Python\python.exe',
'C:\HotPDF\tools\OCR\rapidocr_tsv.py',
'C:\OCR\RapidOCR\models', 60000);
Options := THPDFOCRTextLayerOptions.Default;
if not PDF.ApplyLoadedOCRTextLayer([0], Engine, Options, Info) then
raise Exception.Create('OCR text layer was not added');
end;
兩個工廠都會驗證執行檔與資料路徑存在,並接受 1 到 3,600,000 毫秒的逾時,預設 60,000;組態無效丟出 EArgumentException
共享轉接器以加引號路徑與受限繼承控制代碼啟動隱藏的本地程序,每 25 毫秒輪詢取消、逾時與輸出大小,失敗時先終止程序再清理暫存檔
TSV 輸出上限 64 MiB、診斷檔輸出 1 MiB,回傳的診斷截斷到 4,096 字元;辨識出的詞也必須符合請求的詞數與 UTF-16 額度以及有效的點陣圖邊界
TSV 辨識輸出必須是有效的 UTF-8,已辨識詞內不得含 NUL 位元組或 C0/C1 控制字元;即使錯誤之前已有有效詞,格式錯誤的輸出仍會讓整個辨識請求失敗
這些是輸出與請求限制,不是對外部引擎記憶體使用的硬上限;取消與引擎失敗透過文字層狀態回傳,不會發布部分頁面
辨識證據與限制
本地 RapidOCR 3.8.4 基準在五個固定的中文掃描區域通過全部 15 次重複:兩個 300 DPI 的清晰區域與三個 150 DPI 的低解析度壓力區域,以目前的參考逐字稿評估,字元錯誤率最高 5%、刪除率最高 2%
所有重複都通過閱讀順序檢查、共 5,190 項詞或字元座標檢查,以及 72 DPI 的可見像素相等性;兩個清晰區域對這些參考的字元錯誤為零
兩次 AI 視覺審查對中文文字與數字的判讀一致,但點陣圖中部分標點碼位仍屬模糊、人工裁定尚待完成;標點差異仍計為錯誤,這些結果是語料證據,不是普遍的準確度保證
幾何與搜尋文字
HotPDF 反轉轉譯器的頁面變換,讓詞基線在旋轉 0、90、180 或 270 度的頁面上仍然對齊
每個接受的詞以文字轉譯模式 3 Tr、貼合的水平文字縮放與旋轉感知的文字矩陣寫入,頁面點陣不變,同時保留可選取內容的順序
共享的 Type 0 Identity-H 字型為 Unicode 純量指派有界的文件本地 CID,並寫出完整的 ToUnicode 對應,補充平面字元包含 UTF-16 代理對目標
同一基線上相鄰的拉丁與西里爾字詞,若其幾何顯示有詞間距,會獲得明確的 Unicode 空格;相鄰的 CJK 字詞保留原始文字,不插入空格
處理掃描的 PDF
Demo/Delphi/SearchableOCR/SearchableOCR.dpr 主控台範例會載入掃描的 PDF、以明確指定的本地語言設定檔執行原生 RapidOCR、在所有符合條件的頁面發布隱形 Unicode 文字,並儲存新的 PDF 而不開啟檢視器
SearchableOCR.exe scan.pdf searchable.pdf --dll C:\HotPDF\Lib\Native\RapidOCR\Win64\HotPDFRapidOCR.dll --models C:\HotPDF\Lib\Native\RapidOCR\Models --language ru --dpi 300
簡體中文使用 --language ch,繁體中文使用 --language chinese_cht;DLL 必須與執行檔架構相符,且選定的本地模型套件必須已安裝
範例會拒絕覆寫已存在的輸出檔;更新帶標記的 HotPDF OCR 層時,可傳入 --replace-ocr
Windows FPC 解碼 JPEG 掃描影像時,會先繪製到最終的點陣圖像素格式再進行辨識,讓 LCL 格式轉換保留解碼後的影像
更新既有的 OCR 文字層
把 THPDFOCRTextLayerOptions.ReplaceExistingOCRTextLayer 設為 True,即可在與新文字相同的交易中,替換辨識頁面上先前產生、帶有標記的 HotPDF OCR 串流
這只會在帶標記的頁面上略過 SkipPagesWithText,且儲存後重新載入仍然有效;THPDFOCRTextLayerInfo.ReplacedPageCount 回報被替換的頁數
辨識失敗與沒有接受任何詞的頁面會保留舊的文字層;不帶標記的串流一律保留,包括第三方 OCR 以及較早 HotPDF 版本產生的文字層
替換會中斷舊 OCR 內容串流的連結,但不會移除可能仍被其他地方引用的字型資源或可選內容群組;增量儲存可能保留先前版本中被取代的物件
預設行為維持跳過任何含有可擷取文字的頁面,包括掃描影像上的頁碼或頁首;關閉 SkipPagesWithText 會辨識整個頁面,可能與既有原生文字重複,混合頁面因此需要由應用程式自行挑選處理方式
邊界、取消與原子性
THPDFOCRTextLayerOptions.Default 啟用 300 DPI 辨識、跳過已有文字的頁面,並限制頁數、像素、詞數、UTF-16 單元與產生的內容位元組
HotPDF 驗證每個引擎結果並建好所有頁面內容,才啟動單一 copy-on-write 圖形交易,因此引擎失敗、幾何無效、預算耗盡、取消或提交錯誤都不會改動已載入的物件圖形
空的頁面索引陣列選取所有已載入頁面,重複的頁面索引按首次出現順序只算一次
MaxTotalWords 計入所有收到的詞,包括稍後因低信心度或無效幾何而被丟棄的詞;每一次後續的頁面請求只會收到剩餘的額度
當詞數或 UTF-16 預算耗盡且還有下一個合格頁面時,處理會在轉譯或辨識該頁之前回報 otlsBudgetExceeded,且不發布任何規劃中的文字層;因既有文字而跳過的頁面不需要剩餘的辨識預算
可選內容群組
設定 UseOptionalContentGroup,透過每頁的 Resources/Properties 字典把所有產生文字綁到一個具名圖層
此選項需要 PDF 1.5 並遵循 StrictVersionLock;預設讓隱形文字留在可選內容群組之外,相容性最廣
合規注意事項
產生的可搜尋層刻意使用未內嵌的合成字型,因為轉譯模式 3 本來就不畫字形
此 API 本身不會產出符合 PDF/A 的 OCR 輸出,PDF/A 流程應改用內嵌字型的文字層路徑,並在發布前執行所需的合規驗證