For the complete documentation index, see llms.txt. This page is also available as Markdown.

Handwriting Intelligent Character Recognition (ICR) workflows for the Apryse Server SDK

Requirements

These packages are required to use these features in production. Trial keys have unlimited access to all features

Package: ICRModule: ICR

This guide includes handwriting ICR workflows starting with the simplest use cases, then moving to more advanced use cases.

Process a scanned document

Make a searchable PDF by adding invisible text to an image-based PDF, such as a scanned document, using Handwriting ICR.

PDFDoc doc(input_pdf_path);

// Run ICR on the .pdf with the default options.
HandwritingICRModule::ProcessPDF(doc);
PDFDoc doc = new PDFDoc(input_pdf_path);

// Run ICR on the .pdf with the default options.
HandwritingICRModule.ProcessPDF(doc);
doc := NewPDFDoc(input_pdf_path)
// Run ICR on the .pdf with the default options.
HandwritingICRModuleProcessPDF(doc)
Using doc As PDFDoc = New PDFDoc(input_pdf_path)

   ' Run ICR on the .pdf with the default options.
   HandwritingICRModule.ProcessPDF(doc)
      
End Using
PDFDoc doc = new PDFDoc(input_pdf_path);

// Run ICR on the .pdf with the default options.
HandwritingICRModule.processPDF(doc);

Full code sample to process a scanned document

We also have a full code sample to add searchable/selectable text to an image-based PDF, like a scanned document, which shows how to use the Apryse Handwriting ICR module on scanned documents in multiple programming languages. The Handwriting ICR module can make searchable PDFs and extract scanned text for further indexing. Samples are available in Python, C# (.Net), C++, Go, Java, Node.js (JavaScript), PHP, Ruby, VB, and Obj-C.

Extract handwritten text as JSON

If you want to apply raw ICR output to the input document, you can call HandwritingICRModule.ProcessPDF. However, it is likely that some post-processing will be beneficial, e.g., common spell checker or comparing results against white/blacklists. For this purpose, you can, first, extract text and corresponding metadata as JSON before re-applying the processed results to the input document.

// Open the .pdf document.
PDFDoc doc(input_path + "icr.pdf");

// Extract ICR results in JSON format.
UString json = HandwritingICRModule::GetICRJsonFromPDF(doc);

// Post-processing step (whatever it might be) 

// Re-apply results. 
HandwritingICRModule::ApplyICRJsonToPDF(doc, json);
// Open the .pdf document
PDFDoc doc = new PDFDoc(input_pdf_path);

// Extract ICR results in JSON format
string json = HandwritingICRModule.GetICRJsonFromPDF(doc);

// Post-processing step (whatever it might be) 

// Re-apply results. 
HandwritingICRModule.ApplyICRJsonToPDF(doc, json);
doc := NewPDFDoc(input_pdf_path)
json := HandwritingICRModuleGetICRJsonFromPDF(doc)
// Post-processing step (whatever it might be)
// Re-apply results. 
HandwritingICRModuleApplyICRJsonToPDF(doc, json)

Output Attributes

ICR output consists of nested arrays:

  • Array of pages.

  • Array of paragraphs.

  • Array of lines.

  • Array of words.

Pages have additional metadata:

Attribute
Value
Description

num

page number

dpi

document resolution (needed to correctly scale the coordinates from points to pixels)

origin

TopLeft

coordinate system has origin at the top left corner (default)

BottomLeft

coordinate system has origin at the bottom left corner (i.e., PDF page coordinate system)

Then, each word in the ICR output includes the following:

Attribute
Value
Description

x

bounding box lower left corner x coordinate

y

bounding box lower left corner y coordinate

length

length of bounding box

font-size

text's font size

text

text output

orientation

L

270 degrees clockwise rotation

R

90 degrees clockwise rotation

D

180 degrees clockwise rotation

U

0 degrees clockwise rotation

Each line has an optional box property consisting of 4 values having the same interpretation as pdftron::PDF::Rect.

External ICR results

The API can also be used to apply ICR JSON generated by different OCR or ICR engines. The expected structure for input JSON is:

Note that the ICR structure is simplified and we're expecting an array of Page, with each page consisting of Word array. Each Word is described by its text content and 4 typographic point values (font-size="12" x="321" y="141" length="43" in the example above) needed to construct the bounding box for placement of text on a page.

Last updated

Was this helpful?