The production-proven engine: Foxit’s C++ OCR add-on (foxit::addon::ocr) with line-level confidence reporting, deskew and despeckle built in, and three output modes — searchable, natively editable, or editable via graphics-object post-processing.
Drop PDF or images here, or click to upload
Supports PDF, TIFF, JPG, BMP, PNG — C++ native engine with built-in deskew & despeckleThe engine. Uploads go through a thin PHP proxy on this server to a FastAPI service on a Windows workstation, which runs a small C++ binary built on Foxit’s classic OCR add-on (foxit::addon::ocr). Unlike most OCR APIs, it reports line-level confidence — toggle the Confidence overlay or the Review tab after a run to see exactly which lines the engine was unsure about.
The knobs. Auto-rotate maps to the binary’s --correct-skew flag: on, the engine detects page orientation and deskews; off, it trusts the input orientation — needed for forms with prominent sideways margin text, which can otherwise trick the engine into 180° page flips. The ⚙ Advanced panel exposes the underlying OCRConfig fields one-for-one: picture detection, noise removal, text-extraction mode, DPI override, and a minimum-confidence threshold.
Three output modes. OCR for Search (is_editable=false) keeps the page image and adds an invisible text overlay — the classic searchable PDF. OCR for Edit (native) (is_editable=true) is the add-on’s own editable output, rebuilt as visible text objects in a single SDK call. OCR for Edit (post-process) takes the searchable PDF and runs a second Foxit SDK pass that walks every page graphics object, inserts a white-fill PathObject underneath each invisible text object, then flips the text mode from e_ModeInvisible to e_ModeFill — the original page image (photos, diagrams, logos) is preserved verbatim while the OCR’d text becomes real, visible, editable text. A neat demonstration of graphics-object manipulation in the SDK, and it takes ~150 ms for a 24-page document.
The OCR add-on pipeline this demo runs — initialize the engine, set the language, process, save — in each SDK language binding. Condensed for clarity.
#include "common/fs_common.h"
#include "pdf/fs_pdfdoc.h"
#include "addon/ocr/fs_ocr.h"
using namespace foxit;
using namespace foxit::common;
using namespace foxit::pdf;
using namespace foxit::addon::ocr;
int main() {
Library::Initialize(sn, key); // key must include the OCR module
// Point the engine at the OCR resource directory shipped with the add-on.
OCREngine::Initialize(L"/path/to/ocr_resources");
OCREngine::SetLanguages("English"); // comma-separated for multi-language
PDFDoc doc(L"scan.pdf");
if (doc.Load() != e_ErrSuccess) return 1;
// is_editable = false → searchable PDF: page image kept, invisible text layer.
// is_editable = true → editable PDF: the engine's native editable output.
OCRProcessor processor;
processor.ProcessDocument(doc, /*is_editable=*/false);
// Per-page alternative: processor.ProcessPage(page, is_editable)
// — the engine reports line-level confidence you can read back per line.
doc.SaveAs(L"searchable.pdf",
PDFDoc::e_SaveFlagNoOriginal | PDFDoc::e_SaveFlagXRefStream);
OCREngine::Release();
Library::Release();
return 0;
}
using foxit;
using foxit.common;
using foxit.pdf;
using foxit.addon.ocr;
Library.Initialize(sn, key); // key must include the OCR module
// Point the engine at the OCR resource directory shipped with the add-on.
OCREngine.Initialize(@"C:\foxit\ocr_resources");
OCREngine.SetLanguages("English"); // comma-separated for multi-language
using var doc = new PDFDoc("scan.pdf");
doc.Load(null);
// isEditable = false → searchable PDF: page image kept, invisible text layer.
// isEditable = true → editable PDF: the engine's native editable output.
var processor = new OCRProcessor();
processor.ProcessDocument(doc, false);
// Per-page alternative: processor.ProcessPage(page, isEditable)
// — the engine reports line-level confidence you can read back per line.
doc.SaveAs("searchable.pdf",
(int)(PDFDoc.SaveFlags.e_SaveFlagNoOriginal
| PDFDoc.SaveFlags.e_SaveFlagXRefStream));
OCREngine.Release();
Library.Release();
import com.foxit.sdk.common.Library;
import com.foxit.sdk.pdf.PDFDoc;
import com.foxit.sdk.addon.ocr.*;
Library.initialize(sn, key); // key must include the OCR module
// Point the engine at the OCR resource directory shipped with the add-on.
OCREngine.initialize("/opt/foxit/ocr_resources");
OCREngine.setLanguages("English"); // comma-separated for multi-language
PDFDoc doc = new PDFDoc("scan.pdf");
doc.load(null);
// isEditable = false → searchable PDF: page image kept, invisible text layer.
// isEditable = true → editable PDF: the engine's native editable output.
OCRProcessor processor = new OCRProcessor();
processor.processDocument(doc, false);
// Per-page alternative: processor.processPage(page, isEditable)
// — the engine reports line-level confidence you can read back per line.
doc.saveAs("searchable.pdf",
PDFDoc.e_SaveFlagNoOriginal | PDFDoc.e_SaveFlagXRefStream);
OCREngine.release();
Library.release();
from FoxitPDFSDKPython3 import *
Library.Initialize(sn, key) # key must include the OCR module
# Point the engine at the OCR resource directory shipped with the add-on.
OCREngine.Initialize("/opt/foxit/ocr_resources")
OCREngine.SetLanguages("English") # comma-separated for multi-language
doc = PDFDoc("scan.pdf")
assert doc.Load("") == e_ErrSuccess
# is_editable = False → searchable PDF: page image kept, invisible text layer.
# is_editable = True → editable PDF: the engine's native editable output.
processor = OCRProcessor()
processor.ProcessDocument(doc, False)
# Per-page alternative: processor.ProcessPage(page, is_editable)
# — the engine reports line-level confidence you can read back per line.
doc.SaveAs("searchable.pdf",
PDFDoc.e_SaveFlagNoOriginal | PDFDoc.e_SaveFlagXRefStream)
OCREngine.Release()
Library.Release()
// Foxit PDF SDK for Node.js (naming follows the Node binding conventions)
const {
Library, PDFDoc, OCREngine, OCRProcessor,
} = require('@foxitsoftware/foxit-pdf-sdk-node');
Library.initialize(sn, key); // key must include the OCR module
// Point the engine at the OCR resource directory shipped with the add-on.
OCREngine.initialize('/opt/foxit/ocr_resources');
OCREngine.setLanguages('English'); // comma-separated for multi-language
const doc = new PDFDoc('scan.pdf');
doc.load(null);
// isEditable = false → searchable PDF: page image kept, invisible text layer.
// isEditable = true → editable PDF: the engine's native editable output.
const processor = new OCRProcessor();
processor.processDocument(doc, false);
// Per-page alternative: processor.processPage(page, isEditable)
// — the engine reports line-level confidence you can read back per line.
doc.saveAs('searchable.pdf',
PDFDoc.e_SaveFlagNoOriginal | PDFDoc.e_SaveFlagXRefStream);
OCREngine.release();
Library.release();
Samples are condensed for clarity — production code should check every return value and wrap SDK calls in the binding’s exception handling. Exact class/method names can differ slightly between SDK releases; the pipeline shown mirrors the real source behind this demo (foxit_cpp_classic.cpp, a heavily-commented customer sample), which adds the OCRConfig options and --correct-skew handling exposed in the toolbar above. The “Edit (post-process)” mode is a separate ~100-line SDK pass over the page graphics objects — see the explainer.