OCR Showcase Demo Code Sample

Requirements
View Demo

Generate searchable PDFs from scanned documents or images using OCR (Optical Character Recognition). The scanned file that contains characters is converted into machine-readable searchable and selectable text as a PDF document.

This sample code includes Server SDK processing in JavaScript, with UI provided by WebViewer. If a viewer is not needed, or you want to work with a different language or framework for the Server SDK, please check out our Server SDK OCR Sample Code.

This demo allows you to:

  • Choose your own PDF or image file
  • Select default documents in various languages: English, French, Spanish, Italian, German, Russian
  • Convert into characters that are selectable and searchable
  • Extract the characters as string

Implementation steps

To add OCR Module capability with Server SDK, and view with WebViewer:

Step 1: Follow get-started in JavaScript for Server SDK
Step 2: Follow get-started in your preferred web stack for WebViewer
Step 3: Download OCR Module
Step 4: Add the ES6 JavaScript sample code provided in this guide

Note: Only the first page is processed in this demo.
1// ES6 Compliant Syntax
2// GitHub Copilot v1.0 - GPT-4 Model - September 24, 2024
3// File: ocr-module/client/index.js
4
5import WebViewer from '@pdftron/webviewer';
6
7function initializeWebViewer() {
8
9 console.log('Initializing WebViewer...');
10 const viewerElement = document.getElementById('viewer');
11 if (!viewerElement) {
12 console.error('❌ Viewer element not found. Please ensure there is a div with id "viewer" in your HTML.');
13 return;
14 }
15
16 WebViewer({
17 path: '/lib',
18 initialDoc: UIElements.demoFilesPath + UIElements.ocrdemofiles['eng'],
19 enableFilePicker: true, // Enable file picker to open files. In WebViewer -> menu icon -> Open File.
20 enableMeasurement: false,
21 loadAsPDF: true,
22 licenseKey: 'YOUR_LICENSE_KEY',
23 }, viewerElement).then(instance => {
24
25 // Once the PDF document is loaded, send it to the server.
26 // The sent PDF document will be processed by the server,
27 // by extracting form fields JSON data when the user clicks the Detect Form Fields button.
28 instance.Core.documentViewer.addEventListener('documentLoaded', async () => {
29 if (!UIElements.loadingFromList) {
30 UIElements.loadedFromPicker = true;
31 UIElements.loadLabelText = ' Use file picker to load your own file';
32 }
33
34 // If next time we load from list, this will be set to true again.
35 UIElements.loadingFromList = false;
36
37 // Customize the main webviewer left panel after loading completes.
38 UIElements.customizeUI(instance, performOCR);
39 });
40 console.log('✅ WebViewer loaded successfully.');
41 }).catch((error) => {
42 console.error('Failed to initialize WebViewer:', error);
43 });
44}
45
46// Perform OCR by sending the current PDF page to the server.
47const performOCR = async (instance) => {
48 // Reset JSON data
49 UIElements.jsonData = null;
50 let resultText = '';
51
52 // Preparation of the PDF blob to be sent to the server.
53 const doc = instance.Core.documentViewer.getDocument();
54 const currentPage = instance.Core.documentViewer.getCurrentPage();
55 const xfdfString = await instance.Core.annotationManager.exportAnnotations(); // obtaining annotations in the loaded document
56 const data = await doc.getFileData({ xfdfString });
57 const arr = new Uint8Array(data);
58 const blob = new Blob([arr], { type: 'application/pdf' });
59 const formData = new FormData();
60 formData.append(doc.filename, blob, doc.filename);
61 // Send the PDF blob to the server for processing.
62 new Promise(function (resolve, reject) {
63 console.log('🚀 Sending PDF to server for processing...');
64 fetch(`http://localhost:5050/server/handler.js?filename=${doc.filename}&currentPage=${currentPage}&lang=${UIElements.selectedLanguage}`, {
65 method: 'POST',
66 body: formData,
67 }).then(function (response) {
68
69 if (response.status === 200) {
70 response.text().then(function (json) {
71 UIElements.jsonData = json;
72 const ocrResult = JSON.parse(UIElements.jsonData);
73
74 for (const page of ocrResult.Page) {
75 for (const para of page.Para) {
76 for (const line of para.Line) {
77 for (const word of line.Word) {
78 resultText += word.text + ' ';
79 }
80 resultText += '\n';
81 }
82 }
83 }
84 resolve();
85 })
86 } else {
87 const errorText = `❌ Server responded with status: ${response.status}`;
88 resultText = errorText + resultText;
89 console.error(resultText);
90 reject(new Error(`Server error: ${response.status}`));
91 }
92 }).catch(function (error) {
93 let errorText = '❌ Failed to connect to server: ' + error;
94 errorText += '\n📍 Attempted URL: http://localhost:5050/server/handler.js';
95 errorText += '\n🔍 This likely means the OCR server is not running on port 5050';
96 console.error(errorText);
97 resultText = errorText + resultText;
98 reject(error);
99 });
100 }).catch(function (error) {
101 const errorText = '❌ Error in PDF upload promise: ' + error;
102 console.error(errorText);
103 resultText = errorText + resultText;
104 }).finally(function () {
105 UIElements.ocrText.textContent = resultText;
106 UIElements.setLoading(instance, false);
107 });
108}
109
110
111function loadUIElementsScript() {
112 return new Promise((resolve, reject) => {
113 if (window.UIElements) {
114 console.log('UIElements already loaded');
115 resolve();
116 return;
117 }
118
119 const script = document.createElement('script');
120 script.src = '/showcase-demos/ocr-module/client/ui-elements.js';
121 script.onload = function () {
122 console.log('✅ UIElements script loaded successfully');
123 resolve();
124 };
125 script.onerror = function () {
126 console.error('Failed to load UIElements script');
127 reject(new Error('Failed to load ui-elements.js'));
128 };
129 document.head.appendChild(script);
130 });
131}
132
133// Load UIElements script first, then initialize WebViewer.
134loadUIElementsScript().then(() => {
135 initializeWebViewer();
136}).catch((error) => {
137 console.error('Failed to load UIElements:', error);
138});

Did you find this helpful?

Trial setup questions?

Ask experts on Discord

Need other help?

Contact Support

Pricing or product questions?

Contact Sales