Tesseract OCR Adapters
HPDFTesseractRecognition offers optional Windows engines implementing IHPDFOCREngine for searchable OCR text layers
Native DLL factory
function HPDFCreateTesseractDLLOCREngine(const LibraryPath,
TessDataDirectory, Language: string): IHPDFOCREngine; overload;
function HPDFCreateTesseractDLLOCREngine(const LibraryPath,
TessDataDirectory, Language: string;
const Options: THPDFTesseractOptions): IHPDFOCREngine; overload;
Supply an existing Tesseract DLL exposing the Tesseract 5 compatible C API, a tessdata directory and an ASCII language identifier or combination such as eng, chi_sim or chi_sim+eng
The library architecture has to match the application: a Win32 application loads a 32-bit DLL whilst a Win64 application loads a 64-bit DLL
Keep any required dependency DLLs next to the chosen library or in the standard Windows loader directories; the adapter loads the explicit library path without touching the current directory or the process search path
Before returning, the factory verifies every requested .traineddata file, loads the library and resolves the required exports; invalid paths, models or options, missing exports, architecture mismatches and unavailable dependencies all raise an exception
No OCR runtime or models are bundled, and nothing is downloaded automatically
Both factories ship in the Windows FPC/Lazarus package as well as the Delphi and C++Builder builds; rebuild Lib/FPC/HotPDFLaz.lpk for the target architecture before calling HPDFTesseractRecognition
The native FPC adapter reads the current LCL raw image — pixels written through scanlines included — and keeps Unicode words intact regardless of the system ANSI code page
Options
THPDFTesseractOptions = record
PageSegMode: THPDFTesseractPageSegMode;
EngineMode: THPDFTesseractEngineMode;
TimeoutMilliseconds: Cardinal;
MaxPixels: Integer;
class function Default: THPDFTesseractOptions; static;
end;
Call THPDFTesseractOptions.Default before overriding fields; the same record can configure the native DLL factory or the local CLI options overload
| Field | Default | Meaning |
|---|---|---|
PageSegMode | tpsAuto | Automatic page segmentation without orientation detection |
EngineMode | temDefault | The engine mode the selected language models support |
TimeoutMilliseconds | 60000 | A request deadline from 1 through 3,600,000 milliseconds; the DLL cooperates with cancellation, whilst the CLI worker is terminated on timeout |
MaxPixels | 16777216 | The input pixel budget, settable anywhere from 1 to 67,108,864 pixels |
THPDFTesseractPageSegMode = (
tpsOSDOnly, tpsAutoOSD, tpsAutoOnly, tpsAuto, tpsSingleColumn,
tpsSingleBlockVertical, tpsSingleBlock, tpsSingleLine, tpsSingleWord,
tpsCircleWord, tpsSingleCharacter, tpsSparseText, tpsSparseTextOSD,
tpsRawLine);
THPDFTesseractEngineMode = (
temLegacyOnly, temLSTMOnly, temLegacyAndLSTM, temDefault);
tpsOSDOnly and tpsAutoOnly do no word recognition at all and are rejected by the adapter; tpsAutoOSD and tpsSparseTextOSD additionally call for osd.traineddata
Take tpsSingleLine for a single text line, tpsSingleBlock for a uniform block or tpsSparseText for scattered text; none of these modes straightens out a scan's perspective or offers any general layout guarantee
temLSTMOnly needs LSTM models whilst the legacy modes need the corresponding legacy model components; unsupported combinations fail during native initialisation
Searchable PDF example
The PDF must already be loaded, and the DLL, its dependencies and the language models must be installed at the paths shown
uses SysUtils, HPDFDoc, HPDFTesseractRecognition;
procedure AddNativeOCRText(PDF: THotPDF);
var
Engine: IHPDFOCREngine;
NativeOptions: THPDFTesseractOptions;
LayerOptions: THPDFOCRTextLayerOptions;
Info: THPDFOCRTextLayerInfo;
begin
NativeOptions := THPDFTesseractOptions.Default;
NativeOptions.EngineMode := temLSTMOnly;
NativeOptions.PageSegMode := tpsAuto;
Engine := HPDFCreateTesseractDLLOCREngine(
'C:\OCR\libtesseract-5.dll', 'C:\OCR\tessdata',
'chi_sim+eng', NativeOptions);
LayerOptions := THPDFOCRTextLayerOptions.Default;
if not PDF.ApplyLoadedOCRTextLayer([0], Engine, LayerOptions, Info) then
raise Exception.Create(string(Info.Diagnostic));
end;
Results and ownership
The adapter copies the borrowed bitmap into a top-down grayscale buffer, passes the request DPI through and recognises via a request-local native API instance
Words keep their native reading order, validated UTF-8 Unicode text, top-left pixel bounds and confidence rescaled from 0-100 onto 0-1; supplementary characters consume two UTF-16 units
Word baselines come through with both endpoints where available; when one is not, the existing text-layer geometry fallback takes over
For a predominantly vertical baseline, the native adapter uses the word box width as TextHeightPixels; horizontal baselines use the box height, including reversed reading directions, so a vertical word's length does not become its font size
This is a dominant-axis estimate: an axis-aligned word box and baseline alone cannot recover exact text height at arbitrary skew angles
An empty page succeeds with an empty word array; malformed UTF-8, embedded control characters, invalid geometry or confidence, exhausted word or text budgets, cancellation and recognition failures all return False, clear every partial word and fill in the diagnostic
Every request releases its iterator, allocated native strings, monitor and API instance; releasing the adapter drops its library reference
Limits and cancellation
Each input dimension may be at most 32,767 pixels and must fit within MaxPixels; recognised text has to fit the request's MaxTextCodeUnits budget and the adapter's 1,048,576 UTF-16 unit ceiling, and the word count has to fit MaxWords
During bitmap conversion and result iteration the adapter checks cancellation and elapsed time, and during recognition it hands the native side a monitor carrying the remaining deadline and a cancellation callback
Native cancellation is cooperative: Tesseract's monitor covers word recognition but does not interrupt every initialisation or layout-analysis step, so those calls may run to completion before a requested cancellation or expired deadline surfaces
The pixel and output budgets set no hard limit on the native library's model or recognition memory; prefer the process adapter when the application needs a worker it can terminate independently
ApplyLoadedOCRTextLayer validates every result and publishes all selected pages atomically, so an adapter failure leaves the loaded document exactly as it was
The DLL adapter rejects invalid UTF-8, trims decoded word text, and rejects remaining C0, DEL, and C1 control characters before returning results, so malformed text fails the request instead of being silently omitted by the PDF text layer
Local CLI factory
function HPDFCreateTesseractOCREngine(const ExecutablePath,
TessDataDirectory, Language: string;
TimeoutMilliseconds: Cardinal = 60000): IHPDFOCREngine; overload;
function HPDFCreateTesseractOCREngine(const ExecutablePath,
TessDataDirectory, Language: string;
const Options: THPDFTesseractOptions): IHPDFOCREngine; overload;
The options overload forwards PageSegMode as --psm and EngineMode as --oem, uses the configured timeout, and checks MaxPixels before saving the borrowed bitmap or starting a worker
The existing timeout overload preserves automatic page segmentation and executable-selected engine mode without imposing a new adapter pixel limit; use the options overload when an explicit input limit is required
Both overloads retain requested DPI, TSV output, restricted inherited handles, cancellation polling, and worker termination on failure; the CLI has no native baseline information, limits TSV output to 64 MiB, and limits diagnostic-file output to 1 MiB
Invalid segmentation modes, engine modes, timeouts, and pixel limits raise EArgumentException when creating the configured engine; model availability, including osd.traineddata for orientation modes, and model/engine compatibility are checked by the executable during recognition
var
CLIOptions: THPDFTesseractOptions;
Engine: IHPDFOCREngine;
begin
CLIOptions := THPDFTesseractOptions.Default;
CLIOptions.PageSegMode := tpsSingleLine;
CLIOptions.EngineMode := temLSTMOnly;
CLIOptions.MaxPixels := 8000000;
Engine := HPDFCreateTesseractOCREngine(
'C:\OCR\tesseract.exe', 'C:\OCR\tessdata', 'eng', CLIOptions);
end;
Use tpsSingleWord for an isolated word, tpsSparseText for scattered text, or tpsSingleBlockVertical with a suitable vertical-text model for one vertical block; the factory does not crop pages or select models automatically
The CLI adapter strictly validates UTF-8, rejects NUL bytes and C0/C1 control characters inside recognised words, and clears all results if malformed output follows an otherwise valid word
Turn to Searchable OCR Text Layers for the CLI example, rendering options, optional-content grouping and conformance limits