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

Requirements

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

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
Use Handwriting ICR to make searchable PDFs and extract text with Server SDK in C# (.Net) | Apryse documentation