RapidOCR Local Model Adapter

Where you want cached in-process ONNX inference, turn to the RapidOCR Native DLL Adapter together with HPDFCreateRapidOCRDLLOCREngine and THPDFRapidOCRDLLOptions

The native adapter ships THPDFRapidOCRDLLOptions.ForLanguage presets covering simplified and traditional Chinese, English, the Latin languages, Japanese, Korean, the Cyrillic languages (Russian included), Arabic and Devanagari

HPDFRapidOCRRecognition supplies a Windows process adapter that implements IHPDFOCREngine in Delphi, C++Builder and FPC/Lazarus Win32 and Win64 builds

You provision Python with rapidocr and onnxruntime, the bundled tools/OCR/rapidocr_tsv.py bridge and compatible local ONNX models; the adapter itself installs no packages and downloads no models, dictionaries or fonts

Python runs in a separate hidden process, so its architecture need not match the calling application's; the ONNX Runtime package must, however, match its own Python architecture

Factory overloads

function HPDFCreateRapidOCREngine(const PythonExecutable, BridgeScript,
  ModelDirectory: string; TimeoutMilliseconds: Cardinal = 60000): IHPDFOCREngine; overload;
function HPDFCreateRapidOCREngine(const PythonExecutable, BridgeScript,
  ModelDirectory: string; const Options: THPDFRapidOCROptions): IHPDFOCREngine; overload;

The original timeout overload keeps working against the existing bridge protocol and takes the three default PP-OCRv4 model filenames; it checks the executable, script and directory paths at construction time and checks model availability inside the worker

The options overload verifies every required model, the optional dictionary and the local font before handing back the adapter; missing files or invalid options raise EArgumentException before any recognition begins

Relative model, dictionary and font paths are resolved against ModelDirectory; absolute paths may point at separately provisioned files

Stick to models compatible with RapidOCR's detection, classification and CTC recognition pipeline; a model from a different OCR pipeline may need different preprocessing and must not be chosen on the strength of the ONNX format alone

Language-specific model selection

The Python process adapter keeps using explicit THPDFRapidOCROptions paths; ForLanguage lives on the native DLL options record and is not a Python adapter method

Provision local language models and dictionaries with tools/Install-RapidOCRModels.ps1 -Destination C:/OCR/models -Language ch,cyrillic, or pass -Language All to install all nine language profiles

The helper verifies pinned SHA256 hashes and puts each recogniser at <profile>/recognition.onnx alongside its matching <profile>/dictionary.txt; recognition at run time stays offline with no automatic downloads

For Russian, take cyrillic/recognition.onnx and cyrillic/dictionary.txt; simplified Chinese uses the ch profile whilst traditional Chinese uses chinese_cht

Models := THPDFRapidOCROptions.Default;
Models.DetectionModel := 'ch_PP-OCRv3_det_infer.onnx';
Models.RecognitionModel := 'cyrillic/recognition.onnx';
Models.CharacterDictionary := 'cyrillic/dictionary.txt';
Models.ClassificationModel := 'ch_ppocr_mobile_v2.0_cls_infer.onnx';

The detector and classifier root filenames above are the provisioning helper's shared models; the matching recognition model and dictionary must be supplied as a pair, and pages or regions needing another script should go through a separate engine

Options and defaults

THPDFRapidOCROptions = record
  DetectionModel: string;
  RecognitionModel: string;
  ClassificationModel: string;
  CharacterDictionary: string;
  FontPath: string;
  UseAngleClassifier: Boolean;
  IntraOpThreads: Integer;
  InterOpThreads: Integer;
  MaxPixels: Integer;
  TimeoutMilliseconds: Cardinal;
  class function Default: THPDFRapidOCROptions; static;
end;

Initialise the record with THPDFRapidOCROptions.Default before overriding any fields

FieldDefaultMeaning
DetectionModelch_PP-OCRv4_det_mobile.onnxLocal detection model
RecognitionModelch_PP-OCRv4_rec_mobile.onnxLocal recognition model
ClassificationModelch_ppocr_mobile_v2.0_cls_mobile.onnxNeeded only when angle classification is switched on
CharacterDictionaryEmptyFalls back to the recognition model's embedded character metadata; provide a local dictionary when the model lacks that metadata
FontPathEmptyResolves to %WINDIR%\Fonts\arial.ttf for RapidOCR's result container
UseAngleClassifierTrueTurns on text angle classification; when disabled, no classification model is required or passed
IntraOpThreads1ONNX intra-operation threads, 1 to 64, capped at the worker's logical CPU count
InterOpThreads1ONNX inter-operation threads under the same limits
MaxPixels16777216Input pixel budget, 1 to 67,108,864
TimeoutMilliseconds60000Overall request deadline, 1 to 3,600,000 milliseconds

The bridge explicitly picks the ONNX Runtime CPU backend for every stage and switches off automatic downloads; if the embedded character dictionary is missing, a provisioned local CharacterDictionary becomes mandatory

Example with explicitly selected models

uses SysUtils, HPDFDoc, HPDFRapidOCRRecognition;

procedure AddLocalRapidOCRText(PDF: THotPDF);
var
  Engine: IHPDFOCREngine;
  Models: THPDFRapidOCROptions;
  Layer: THPDFOCRTextLayerOptions;
  Info: THPDFOCRTextLayerInfo;
begin
  Models := THPDFRapidOCROptions.Default;
  Models.DetectionModel := 'PP-OCRv6_det_small.onnx';
  Models.RecognitionModel := 'PP-OCRv6_rec_small.onnx';
  Models.UseAngleClassifier := False;
  Engine := HPDFCreateRapidOCREngine(
    'C:\OCR\Python\python.exe',
    'C:\HotPDF\tools\OCR\rapidocr_tsv.py',
    'C:\OCR\models', Models);
  Layer := THPDFOCRTextLayerOptions.Default;
  if not PDF.ApplyLoadedOCRTextLayer([0], Engine, Layer, Info) then
    raise Exception.Create('Local RapidOCR text layer was not added');
end;

Results, budgets, and cancellation

Every request serialises the borrowed bitmap into a private temporary directory, starts a local Python worker and tidies up its process handles and temporary files once the request completes

The options overload checks MaxPixels before the bitmap is serialised; the worker likewise checks input dimensions before loading the models and is handed the request's MaxWords and MaxTextCodeUnits limits

The bridge asks for character coordinates and validates every character's geometry, confidence and text coverage, then emits each complete recognised line with its original internal spaces and punctuation, the enclosing bounds in original image pixels and mean confidence on a 0-to-1 scale

Each emitted line takes one MaxWords slot; internal spaces count towards MaxTextCodeUnits, and publishing a whole line stops the text layer from mistaking letter spacing for word spacing

Spacing is preserved from the recogniser's line text; text that detection splits into separate boxes still depends on spatial word-gap inference, and external PDF readers may reconstruct or collapse repeated spaces during extraction

Supplementary characters consume two UTF-16 units; invalid coordinates or confidence, control characters and exhausted budgets all fail the recognition and discard partial results

An empty page succeeds with an empty word array; as no native baseline is supplied, the text layer falls back on its existing geometry handling

Cancellation, timeout and output sizes are polled every 25 milliseconds; a Windows job wraps the worker and any interpreter child processes, and termination allows up to five further seconds for process cleanup

ApplyLoadedOCRTextLayer publishes every selected page atomically once recognition has succeeded

TSV output is capped at 64 MiB and diagnostic output at 1 MiB; the input and output budgets set no hard limit on ONNX model or inference memory use

Model initialisation happens in a fresh Python process for each request and counts against the deadline

Validation

The shared Delphi and FPC adapter runners cover model preflight, custom paths, optional classification, Unicode, budgets, worker failure, cancellation and timeout; their optional RapidOCR parameters switch on real recognition and searchable PDF round-trip checks

Run Tests/Delphi/Run-TesseractRecognitionTests.ps1 or Tests/Delphi/Run-TesseractFPCRecognitionTests.ps1 with -RapidOCRPython, -RapidOCRModelDirectory, -RapidOCRDetectionModel and -RapidOCRRecognitionModel

Turn to Searchable OCR Text Layers for rendering options, Unicode PDF text mapping, optional-content grouping and conformance limits