Handwriting ICR to search PDFs and Extract Handwritten Text - C# (.Net) Sample Code

Requirements
View Demo

Sample code shows how to use the Apryse Server OCR module on scanned documents in multiple languages; provided in Python, C++, C# (.Net), Java, Node.js (JavaScript), PHP, Ruby and VB. The OCR module can make searchable PDFs and extract scanned text for further indexing.

Looking for OCR + WebViewer? Check out our OCR - Showcase Sample Code

Learn more about our Server SDK and OCR capabilities.

Implementation steps

To run this sample, you will need:

  1. Get started with Server SDK in your language/framework.
  2. Download ICR Module.
  3. Add the sample code provided below.

To use this feature in production, your license key will need the ICR Package. Trial keys already include this package.

1//---------------------------------------------------------------------------------------
2// Copyright (c) 2001-2026 by Apryse Software Inc. All Rights Reserved.
3// Consult legal.txt regarding legal and license information.
4//---------------------------------------------------------------------------------------
5
6using System;
7using pdftron;
8using pdftron.Common;
9using pdftron.SDF;
10using pdftron.PDF;
11
12namespace HandwritingICRTestCS
13{
14
15 /// <summary>
16 //---------------------------------------------------------------------------------------
17 // The Handwriting ICR Module is an optional PDFNet add-on that can be used to extract
18 // handwriting from image-based pages and apply them as hidden text.
19 //
20 // The Apryse SDK Handwriting ICR Module can be downloaded from https://dev.apryse.com/
21 //---------------------------------------------------------------------------------------
22 /// </summary>
23 class Class1
24 {
25 private static pdftron.PDFNetLoader pdfNetLoader = pdftron.PDFNetLoader.Instance();
26 static Class1() {}
27
28 /// <summary>
29 /// The main entry point for the application.
30 /// </summary>
31 static void Main(string[] args)
32 {
33 // The first step in every application using PDFNet is to initialize the
34 // library and set the path to common PDF resources. The library is usually
35 // initialized only once, but calling Initialize() multiple times is also fine.
36 PDFNet.Initialize(PDFTronLicense.Key);
37
38 // The location of the Handwriting ICR Module
39 PDFNet.AddResourceSearchPath("../../../../../Lib/");
40
41 // Test if the add-on is installed
42 if (!HandwritingICRModule.IsModuleAvailable())
43 {
44 Console.WriteLine("");
45 Console.WriteLine("Unable to run HandwritingICRTest: Apryse SDK Handwriting ICR Module");
46 Console.WriteLine("not available.");
47 Console.WriteLine("---------------------------------------------------------------");
48 Console.WriteLine("The Handwriting ICR Module is an optional add-on, available for download");
49 Console.WriteLine("at https://dev.apryse.com/. If you have already downloaded this");
50 Console.WriteLine("module, ensure that the SDK is able to find the required files");
51 Console.WriteLine("using the PDFNet.AddResourceSearchPath() function.");
52 Console.WriteLine("");
53 return;
54 }
55
56 // Relative path to the folder containing test files.
57 string input_path = "../../../../TestFiles/HandwritingICR/";
58 string output_path = "../../../../TestFiles/Output/";
59
60 //--------------------------------------------------------------------------------
61 // Example 1) Process a PDF without specifying options
62 try
63 {
64 Console.WriteLine("Example 1: processing icr.pdf");
65
66 // Open the .pdf document
67 using (PDFDoc doc = new PDFDoc(input_path + "icr.pdf"))
68 {
69 // Run ICR on the .pdf with the default options
70 HandwritingICRModule.ProcessPDF(doc);
71
72 // Save the result with hidden text applied
73 doc.Save(output_path + "icr-simple.pdf", SDFDoc.SaveOptions.e_linearized);
74 doc.Close();
75 }
76 }
77 catch (PDFNetException e)
78 {
79 Console.WriteLine(e.Message);
80 }
81
82 //--------------------------------------------------------------------------------
83 // Example 2) Process a subset of PDF pages
84 try
85 {
86 Console.WriteLine("Example 2: processing pages from icr.pdf");
87
88 // Open the .pdf document
89 using (PDFDoc doc = new PDFDoc(input_path + "icr.pdf"))
90 {
91 // Process handwriting with custom options
92 HandwritingICROptions options = new HandwritingICROptions();
93
94 // Optionally, process a subset of pages
95 options.SetPages("2-3");
96
97 // Run ICR on the .pdf
98 HandwritingICRModule.ProcessPDF(doc, options);
99
100 // Save the result with hidden text applied
101 doc.Save(output_path + "icr-pages.pdf", SDFDoc.SaveOptions.e_linearized);
102 doc.Close();
103 }
104 }
105 catch (PDFNetException e)
106 {
107 Console.WriteLine(e.Message);
108 }
109
110 //--------------------------------------------------------------------------------
111 // Example 3) Ignore zones specified for each page
112 try
113 {
114 Console.WriteLine("Example 3: processing & ignoring zones");
115
116 // Open the .pdf document
117 using (PDFDoc doc = new PDFDoc(input_path + "icr.pdf"))
118 {
119 // Process handwriting with custom options
120 HandwritingICROptions options = new HandwritingICROptions();
121
122 // Process page 2 by ignoring the signature area on the bottom
123 options.SetPages("2");
124 RectCollection ignore_zones_page2 = new RectCollection();
125 // These coordinates are in PDF user space, with the origin at the bottom left corner of the page.
126 // Coordinates rotate with the page, if it has rotation applied.
127 ignore_zones_page2.AddRect(78, 850.1 - 770, 340, 850.1 - 676);
128 options.AddIgnoreZonesForPage(ignore_zones_page2, 2);
129
130 // Run ICR on the .pdf
131 HandwritingICRModule.ProcessPDF(doc, options);
132
133 // Save the result with hidden text applied
134 doc.Save(output_path + "icr-ignore.pdf", SDFDoc.SaveOptions.e_linearized);
135 doc.Close();
136 }
137 }
138 catch (PDFNetException e)
139 {
140 Console.WriteLine(e.Message);
141 }
142
143 //--------------------------------------------------------------------------------
144 // Example 4) The postprocessing workflow has also an option of extracting ICR results
145 // in JSON format, similar to the one used by the OCR Module
146 try
147 {
148 Console.WriteLine("Example 4: extract & apply");
149
150 // Open the .pdf document
151 using (PDFDoc doc = new PDFDoc(input_path + "icr.pdf"))
152 {
153 // Extract ICR results in JSON format
154 string json = HandwritingICRModule.GetICRJsonFromPDF(doc);
155 System.IO.File.WriteAllText(output_path + "icr-get.json", json);
156
157 // Insert your post-processing step (whatever it might be)
158 // ...
159
160 // Apply potentially modified ICR JSON to the PDF
161 HandwritingICRModule.ApplyICRJsonToPDF(doc, json);
162
163 // Save the result with hidden text applied
164 doc.Save(output_path + "icr-get-apply.pdf", SDFDoc.SaveOptions.e_linearized);
165 doc.Close();
166 }
167 }
168 catch (PDFNetException e)
169 {
170 Console.WriteLine(e.Message);
171 }
172
173 Console.WriteLine("Done.");
174 PDFNet.Terminate();
175 }
176
177 }
178}

Did you find this helpful?

Trial setup questions?

Ask experts on Discord

Need other help?

Contact Support

Pricing or product questions?

Contact Sales