Tesseract OCR Adapters
HPDFTesseractRecognition provides 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;
Provide 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 must match the application: a Win32 application loads a 32-bit DLL, while a Win64 application loads a 64-bit DLL
Keep required dependency DLLs beside the chosen library or in standard Windows loader directories; the adapter loads the explicit library path without changing the current directory or process search path
The factory verifies every requested .traineddata file, loads the library, and resolves the required exports before returning; invalid paths, models, options, missing exports, architecture mismatches, and unavailable dependencies raise an exception
No OCR runtime or models are bundled or downloaded automatically
Both factories are available in the Windows FPC/Lazarus package as well as Delphi and C++Builder builds; rebuild Lib/FPC/HotPDFLaz.lpk for the target architecture before using HPDFTesseractRecognition
The native FPC adapter reads the current LCL raw image, including pixels written through scanlines, and preserves Unicode words independently 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 supported by the selected language models |
TimeoutMilliseconds | 60000 | A request deadline from 1 through 3,600,000 milliseconds; the DLL cooperates with cancellation, while the CLI worker is terminated on timeout |
MaxPixels | 16777216 | The input pixel budget, configurable from 1 through 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 perform no word recognition and are rejected by the adapter; tpsAutoOSD and tpsSparseTextOSD additionally require osd.traineddata
Use tpsSingleLine for one text line, tpsSingleBlock for a uniform block, or tpsSparseText for scattered text; these modes do not repair a scan's perspective or provide a general layout guarantee
temLSTMOnly requires LSTM models, while legacy modes require corresponding legacy model components; unsupported combinations fail during native initialization
Searchable PDF example
The PDF must already be loaded, and the DLL, dependencies, and language models must be installed at the shown locations
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, forwards the request DPI, and recognizes through a request-local native API instance
Words retain native reading order, validated UTF-8 Unicode text, top-left pixel bounds, and confidence scaled from 0 through 100 into 0 through 1; supplementary characters consume two UTF-16 units
Available word baselines are passed through with both endpoints; when a baseline is unavailable, the existing text-layer geometry fallback applies
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 return False, clear all partial words, and populate the diagnostic
Each request releases its iterator, allocated native strings, monitor, and API instance; releasing the adapter unloads its library reference
Limits and cancellation
Input dimensions must each be at most 32,767 pixels and fit MaxPixels; recognized text must fit the request's MaxTextCodeUnits budget and the adapter's 1,048,576 UTF-16 unit limit, and word count must fit MaxWords
The adapter checks cancellation and elapsed time during bitmap conversion and result iteration, and supplies a native monitor with the remaining deadline and a cancellation callback during recognition
Native cancellation is cooperative: Tesseract's monitor covers word recognition and does not interrupt every initialization or layout-analysis step; these calls may finish before a requested cancellation or expired deadline is reported
Pixel and output budgets do not impose a hard limit on the native library's model or recognition memory use; use the process adapter when the application needs a separately terminable worker
ApplyLoadedOCRTextLayer validates all results and publishes every selected page atomically, so an adapter failure leaves the loaded document unchanged
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 recognized words, and clears all results if malformed output follows an otherwise valid word
See Searchable OCR Text Layers for the CLI example, rendering options, optional-content grouping, and conformance limits