JavaScript Scanning Library API Dev Guide

Include scanner.js

For evaluation or lite usage, you can simply include a JavaScript .js file from asprise.com. Alternatively, you may download Scanner.js zip and unzip the files into a folder on your own web server.

Option 1: Include scanner.js from asprise.com

For this option, you simply use a script tag to include scanner.js:

Include scanner.js from asprise.com
<html lang="en">
<head>
    <script src="//asprise.azureedge.net/scannerjs/scanner.js" type="text/javascript"></script>

Alternatively, you can host it on your own server.

Option 2: Host scanner.js on your own server

For this option, you can either use bower to automatically download or manually download scanner.js.

Automatic download with bower

If you use bower to manage components and dependencies, you can simply execute:

bower install scanner.js

After scanner.js has been installed, you can then include it in your pages:

Include bower installed scanner.js
<html lang="en">
<head>
    <script src="bower_components/scanner.js/dist/scanner.js" type="text/javascript"></script>

Alternatively, you can manually download it instead of using bower.

Manual download

Download scanner.js zip and unzip the files into a folder on your own web server.

There isn’t any server side script in scanner.js files so you can unzip it to any web server. Once done, you can include it in your web page:

Include scanner.js from your server
<html lang="en">
<head>
    <script src="//YOUR_SERVER/PATH_TO/scanner.js" type="text/javascript"></script>

The Scanning Process

In this section, we’ll walk through the typical scanning process.

We’ll use a simple example to illustrate the basic usage of scanner.js. This example will allow the user to scan images and display them on the web page (uploading will be shown in later examples). Below is the screenshot of the web page after two pages are scanned:

Demo: Scan to JPG and display

Make sure you have already included scanner.js script. To perform a scan, you need to call the main interface Javascript function scanner.scan, which accepts the following arguments in order:

callbackFunction
Function to be called after the scan is done. Required.
requestSpecification
The scan request in JavaScript or plain string, as defined in Scanner.js Request DSL Reference. Required.
useAspriseDialog
Whether Asprise scan dialog (allows the user to preview, delete, re-arrange order, and edit acquired images) should be used. Optional. Default to true.
showScannerUI
Whether native UI (if any) of the scanner device should be shown. Optional. Default to false.

Initiate a scan

To initiate a scan, you can simply call scanner.scan with proper arguments. For example, the code below initiates a scan that will output images in jpg format:

Scan to JPEG format in-memory
function scanToJpg() {
   scanner.scan(displayImagesOnPage,
   {
      "output_settings" :
      [
         {
            "type" : "return-base64",
            "format" : "jpg"
         }
      ]
   }
   );
}

You may use a button to invoke the above function:

<button type="button" onclick="scanToJpg();">Scan</button>

<div id="images"></div>

The div with name images will be used to display images scanned later.

Once the user presses the Scan button, the scan dialog will present and the user can then scan documents. After the scanning is done, the result handler callback function will be invoked.

Handle the scan result using a callback function

Scanner.js will invoke the callback function with the following arguments:

successful
Boolean flag indicating whether the call is successful or not.
mesg
Optional message especially when not successful; could be undefined.
response
The response returned from scanner.js.

Below is the implementation of the result callback function for the example above:

Process scan result and display images on the web page
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
/** Processes the scan result */
function displayImagesOnPage(successful, mesg, response) {
   if(!successful) { // On error
      console.error('Failed: ' + mesg);
      return;
   }

   if(successful && mesg != null && mesg.toLowerCase().indexOf('user cancel') >= 0) { // User canceled.
      console.info('User canceled');
      return;
   }

   var scannedImages = scanner.getScannedImages(response, true, false); // returns an array of ScannedImage
   for(var i = 0; (scannedImages instanceof Array) && i < scannedImages.length; i++) {
      var scannedImage = scannedImages[i];
      processScannedImage(scannedImage);
   }
}

/** Images scanned so far. */
var imagesScanned = [];

/** Processes a ScannedImage */
function processScannedImage(scannedImage) {
   imagesScanned.push(scannedImage);
   var elementImg = createDomElementFromModel( {
       'name': 'img',
       'attributes': {
           'class': 'scanned',
           'src': scannedImage.src
       }
   });
   document.getElementById('images').appendChild(elementImg);
}

First, we check whether the scan is successful or not. If successful, we check whether the user cancels - in which case no image will be returned.

In a single scan session, you may specify to return both originals and thumbnails (see Scanner.js Request DSL Reference for details). The scanner.getScannedImages function can be used to extract either or both types of the images from the response:

function getScannedImages(response, includeOriginals, includeThumbnails)

scanner.getScannedImages returns an array of ScannedImage, which is declared as below:

var ScannedImage = function (mimeType, srcIsBase64, src, imageInfo) { // constructor
   // Object fields
   this.mimeType = mimeType;       // Mime type, e.g., 'image/jpeg'
   this.srcIsBase64 = srcIsBase64; // true if src is in base64 data uri false if normal url
   this.src = src;                 // src, can be either base64 data uri or normal url
   this.imageInfo = imageInfo;     // object storing image properties
};

// Object methods
ScannedImage.prototype.getWidth(); // image width or undefined if not available
ScannedImage.prototype.getHeight(); // image height or undefined

ScannedImage.prototype.isColor(); // Whether it is a color image
ScannedImage.prototype.isGray(); // Whether it is a gray image
ScannedImage.prototype.isBlackWhite(); // Whether it is a black/white image

ScannedImage.prototype.getResolution(); // The horizontal scan resolution if available
ScannedImage.prototype.getBitsPerPixel(); // Bits per pixel of undefined

ScannedImage.prototype.getBase64NoPrefix(); // Base64 encoding of the image data

ScannedImage.prototype.toString(); // Readable string describing the image

Once an array of ScannedImage is obtained, we can iterate each ScannedImage (Lines 13-17) and create an img element from it and then display images on the web page using function processScannedImage. Note that we use imagesScanned to track all ScannedImages so that we may manipulate later (e.g., upload to server).

scanner.createDomElementFromModel is function defined in scanner.js to help create DOM elements from declarations.

Again, the complete source code is available on GitHub.

Now, the scanned images are shown on the web page. Next, we’ll explore how to scan and upload to the server side.

Scan then Upload in Browsers

There are two options to implement scan then upload in browsers. You can scan and and later upload the scanned images with an existing <form> when submitted. Alternatively, you can instruct scanner.js to scan and upload directly to the server side.

Option 1: Scan and Upload with a Form

We can simply extend the previous example by adding a HTML <form> element and an optional <div> to display server response as well as a JavaScript function to submit the form:

Form HTML
<form id="form1" action="https://asprise.com/scan/applet/upload.php?action=dump" method="POST" enctype="multipart/form-data" target="_blank" >
   <input type="text" id="sample-field" name="sample-field" value="Test scan"/>
   <input type="button" value="Submit" onclick="submitFormWithScannedImages();">
</form>

<div id="server_response"></div>
JavaScript form submission function
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
function submitFormWithScannedImages() {
   if (scanner.submitFormWithImages('form1', imagesScanned, function (xhr) {
       if (xhr.readyState == 4) { // 4: request finished and response is ready
           document.getElementById('server_response').innerHTML = "<h2>Response from the server: </h2>" + xhr.responseText;
           document.getElementById('images').innerHTML = ''; // clear images
           imagesScanned = [];
       }
   })) {
       document.getElementById('server_response').innerHTML = "Submitting, please stand by ...";
   } else {
       document.getElementById('server_response').innerHTML = "Form submission cancelled.";
   }
}

The <form> target URL https://asprise.com/scan/applet/upload.php?action=dump is a PHP script that accept form post and echo back all the data received. You may use it to test your form submissions. All uploaded images to this URL will be automatically deleted after a few days. The source code of this script is available here. Note that you may use any programming language (like C# ASP.NET, Java, PHP, Python, Ruby on Rails) to implement the server side.

Let’s take a look at the JavaScript function. scanner.submitFormWithImages, which is defined in scanner.js, submits scanned images along with all form data to the action url through XMLHttpRequest. It accepts the following arguments in order:

formId
The value of the attribute id of the <form> element. Required.
images
An Array of ScannedImage. Its length must be greater than 0 otherwise form submission will be canceled. Required.
onReadyStateChangeHandler
Callback function to be set as XMLHttpRequest.onreadystatechange.

scanner.submitFormWithImages returns the XMLHttpRequest object or undefined if submission is canceled (form with the given id doesn’t exist or no scanned images are passed).

When form post is done (xhr.readyState == 4), we displays the server response and clear scanned images on the web page (Lines 3-7).

The following is a screenshot of the web page after the scanned image has been uploaded through the form:

Demo: Scan to form and upload

In practice, the upload script usually returns key information through JSON rather than HTML markups. Instead of using https://asprise.com/scan/applet/upload.php?action=dump, you may set the target URL to https://asprise.com/scan/applet/upload.php?action=upload to return path to the upload file only.

Scan to PDF and Upload with a Form

One common use of scanner.js is to scan images as PDF and display thumbnails on the web page. We can modify the code of the above example to implement this feature.

First, we create a JavaScript function scanToPdfWithThumbnails to initiate a scan with two output settings: one for originals (PDF) and one for thumbnails (JPG):

JavaScript scan originals as PDF and thumbails as JPG
function scanToPdfWithThumbnails() {
   scanner.scan(displayImagesOnPage,
     {
         "output_settings": [
             {
                 "type": "return-base64",
                 "format": "pdf",
                 "pdf_text_line": "By ${USERNAME} on ${DATETIME}"
             },
             {
                 "type": "return-base64-thumbnail",
                 "format": "jpg",
                 "thumbnail_height": 200
             }
         ]
     }
   );
}

For detailed configuration, please refer to Image Formats Supported.

Now, we need to modify displayImagesOnPage to store originals and display thumbnails on the web page:

JavaScript scan originals into PDF and thumbails into JPG
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
function displayImagesOnPage(successful, mesg, response) {
   if(!successful) { // On error
       console.error('Failed: ' + mesg);
       return;
   }

   if(successful && mesg != null && mesg.toLowerCase().indexOf('user cancel') >= 0) { // User cancelled.
       console.info('User cancelled');
       return;
   }

   var scannedImages = scanner.getScannedImages(response, true, false); // returns an array of ScannedImage
   for(var i = 0; (scannedImages instanceof Array) && i < scannedImages.length; i++) {
       var scannedImage = scannedImages[i];
       processOriginal(scannedImage);
   }

   var thumbnails = getScannedImages(response, false, true); // returns an array of ScannedImage
   for(var i = 0; (thumbnails instanceof Array) && i < thumbnails.length; i++) {
       var thumbnail = thumbnails[i];
       processThumbnail(thumbnail);
   }
}

/** Images scanned so far. */
var imagesScanned = [];

/** Processes an original */
function processOriginal(scannedImage) {
   imagesScanned.push(scannedImage);
}

/** Processes a thumbnail */
function processThumbnail(scannedImage) {
   var elementImg = createDomElementFromModel( {
       'name': 'img',
       'attributes': {
           'class': 'scanned',
           'src': scannedImage.src
       }
   });
   document.getElementById('images').appendChild(elementImg);
}

The submitFormWithScannedImages function in previous example will remain the same: it will submit form along with imagesScanned (which stores the originals).

Once the user clicks Submit button, the PDF file will be uploaded as shown below. Click the PDF icon to view it.

Demo: Scan PDF to form and upload

Option 2: Scan to PDF and Upload Directly Through Scanner.js

Scanner.js has the capability of uploading images immediately after scanning. Instead of uploading images through a <form>, you may instruct scanner.js to upload images directly.

JavaScript scan and upload directly
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
function scanAndUploadDirectly() {
   scanner.scan(displayServerResponse,
       {
           "output_settings": [
               {
                   "type": "upload",
                   "format": "pdf",
                   "upload_target": {
                       "url": "https://asprise.com/scan/applet/upload.php?action=dump",
                       "post_fields": {
                           "sample-field": "Test scan"
                       },
                       "cookies": document.cookie,
                       "headers": [
                           "Referer: " + window.location.href,
                           "User-Agent: " + navigator.userAgent
                       ]
                   }
               }
           ]
       }
   );
}

function displayServerResponse(successful, mesg, response) {
   if(!successful) { // On error
       document.getElementById('server_response').innerHTML = 'Failed: ' + mesg;
       return;
   }

   if(successful && mesg != null && mesg.toLowerCase().indexOf('user cancel') >= 0) { // User cancelled.
       document.getElementById('server_response').innerHTML = 'User cancelled';
       return;
   }

   document.getElementById('server_response').innerHTML = getUploadResponse(response);
}

Line 7 specifies the image format is pdf. Of course, you can also use other formats like jpg, but here we want a single file even if there are multiple images.

Line 6 specifies the output setting type is upload. For this type, you must specify upload_target. The upload target should contains information like url, additional post fields, cookies and headers if any (Lines 8-18).

After the images are scanned and uploaded, displayServerResponse will be invoked. In this case, response contains the server response instead of the actual image data. Defined in scanner.js, getUploadResponse extracts server response.

And the corresponding HTML code:

<button type="button" onclick="scanAndUploadDirectly();">Scan and Upload</button>

<div id="server_response"></div>

Other In-Browser Scan Tasks

Scanner.js offers a wide range of functionalities. Below lists common used tasks.

Scan to Local Disk

To scan to local disk, you need to add an output setting with save type and specify the save_path (either absolute path or path containing macros, refer to save, save-thumbnail):

JavaScript scan PDF to local disk
function scanToLocalDisk() {
   scanner.scan(displayResponseOnPage,
       {
           "output_settings": [
               {
                   "type": "save",
                   "format": "pdf",
                   "save_path": "${TMP}\\${TMS}${EXT}"
               }
           ]
       }
   );
}

function displayResponseOnPage(successful, mesg, response) {
   document.getElementById('response').innerHTML = scanner.getSaveResponse(response);
}

Scan Without Using Asprise Dialog

Asprise Dialog provides an optimized user experience, and using it is highly recommended. However, if you don’t want to make use it, you can set use_asprise_dialog to false to disable it:

JavaScript scan without Asprise Dialog
function scanWithoutAspriseDialog() {
   scanner.scan(displayImagesOnPage,
           {
               "use_asprise_dialog": false,
               "output_settings": [
                   {
                       "type": "return-base64",
                       "format": "jpg"
                   }
               ]
           }
   );
}

Scan as PDF with CCITT G4 for Ultra Small File Size

If file size is a concern, you may use PDF with CCITT G4 compression for great saving of disk space. The trade-off is that PDF with CCITT G4 is black/white only. To use it:

JavaScript scan as PDF with CCITT G4
scanner.scan(displayServerResponse,
    {
        "output_settings": [
            {
                "type": "upload",
                "format": "pdf",
                "pdf_force_black_white": true, // Enables CCITT G4 compression
                "upload_target": {
                    "url": "https://asprise.com/scan/applet/upload.php?action=dump"
                }
            }
        ]
    }
);

Additional Control Options

JSON KeyDescriptionValues
use_asprise_dialog Whether Asprise scan dialog should be used; Effective only if it is not specified through argument to the scan function. true | false
show_scanner_ui Whether scanner UI should be shown; Effective only if it is not specified through argument to the scan function. false | true
dialog_width The width of the Asprise scanning dialog to be shown e.g., 1024
dialog_height The height of the Asprise scanning dialog to be shown e.g., 800
source_name The source name of the device to be used or 'select' using the device list dialog or 'default' to use the default device. Default value is 'select'. select | default | EXACT_SOURCE

Low Level Scanner Access API

You may use Scanner.js to perform low level scanner operations, for example, listing all scanner sources with full capabilities and setting/getting source capabilities.

Lists all scanners available optionally with capabilities

You use scanner.listSources to list all available scanners:

List all scanners
function listSources() {
   displayText("Listing sources ...");
   scanner.listSources(callbackFunc, false, "all", true, true);
}

function callbackFunc(successful, mesg, result) {
   displayText((successful ? "OK" : "ERROR") + (mesg ? " - " + mesg : "") + "\n" + result);
}

listSources takes the following parameters in order:

callbackFunc
The function to be called after the operation is done; required.
nameOnly
boolean - if true, return list of device names separated by ‘,’ otherwise return device info in JSON format. Default: true.
capsToRetrieve
boolean - only effective if nameOnly is false - If set, return JSON string; can be cap name or code separated by comma or ‘all’ to list all caps supported.
detectDeviceType
boolean - detect whether the device has ADF and/or flatbed, default; false
excludeTwainDsOnWia
boolean - exclude WIA synthesized sources; default: true

Prompts the user to select a source

You use scanner.getSource to prompt the user to select a scanner:

JavaScript scan as PDF with CCITT G4
function selectSource() {
   displayText("Select a source ...");
   scanner.getSource(callbackFunc, "select", true);
}

Sets and gets source capabilities

scanner.getSource does more than source selection. You can use it to set and retrieve all the capabilities of a particular source.

Sets and gets source capabilities
function getSourceCaps() {
   displayText("Gets source capabilities ...");
   scanner.getSource(callbackFunc, "select", false, "all", false, true, "CAP_FEEDERENABLED: false; ICAP_UNITS: TWUN_INCHES");
}

getSource takes the following parameters in order:

callbackFunc
The function to be called after the operation is done; required.
sourceName
The exact source name or “default” to open default source; “select” to prompt dialog selection; Default: “select”
nameOnly
If true, return the device name only; default: true
capsToRetrieve
Only effective if nameOnly is false - can be cap name or code separated by comma or ‘all’ to list all caps supported.
getCurrent
true to return current value false to return current value as well as value range if available; Default: true
detectDeviceType
Detect whether the device has ADF and/or flatbed; default: false.
capsToSet
Optionally, you may set capabilities before getting capabilities, e.g, ‘ICAP_PIXELTYPE: TWPT_GRAY,TWPT_BW; ICAP_XSCALING/RESET; ICAP_XRESOLUTION: 200’

getSource returns the result in JSON or comma separated string depending on the parameter nameOnly.

Get system information

scanner.getSystemInfo allows JavaScript to query system information:

Get system info
function getSourceCaps() {
   displayText("Gets system info ...");
   scanner.getSystemInfo(callbackFunc);
}

Sample output:

{
   "default_paper_size" : "letter",
   "measurement_system" : "us",
   "os" : "Win10-64",
   "timezone_bias" : 0,
   "timezone_name" : "Eastern Standard Time",
   "timezone_type" : "standard",
   "twain_version" : "2.3.0.0, 2.3.0.0",
   "user_default_lang_code" : "en_US",
   "user_default_lang_id" : 1033,
   "user_default_lc_code" : "en_US",
   "user_default_lc_id" : 1033,
   "user_default_ui_lang_code" : 1033,
   "user_default_ui_lang_id" : 1033,
   "user_geo_nation_id" : 244,
   "user_geo_nation_name" : "US; United States",
   "user_geo_region_id" : -1,
   "user_geo_region_name" : ""
}

Scanner.js Configuration Options

You may use configuration options to control the behavior of Scanner.js. Before including the scanner.js script, you need to create an object named scannerjs_config:

List of scanner.js configuration options
 <script type="text/javascript">
     window.scannerjs_config = { // must set before including scanner.js to
         eager_init: true, // true (default): initialize on start; false: you need to manually call scanner.initialize()

         display_install_func: undefined, // specify a func(Boolean show) to be called to show/hide scan app prompt dialog
         display_scan_ready_func: undefined, // specify a func() to be called upon scanning is enabled
         skip_load_default_css: false, // false (default): loading css styling for the default dialog; true: skip loading

         event_listener: undefined, // specify a func(String eventName, Object details) for listening events like scanner.EVENT_READY

         log_level: 0, // 0 (default): log all;  16: log error only; 1024: log nothing

         scan_app_enabled: true, // true (default): enable scan app; false: disable scan app
         scan_app_download_url: 'http://asprise.azureedge.net/scanapp/scan-setup.exe', // scan app download url
         java_applet_enabled: true, // false (default): don't use Java applet even if the browser supports it; true: enable Java applet support

         form_field_name_for_img_objects: 'com_asprise_scannerjs_images[]', // the name of the form field for direct file uploading
         form_field_name_for_img_urls: 'com_asprise_scannerjs_images_urls[]', // the name of the form field for URL only uploading
     };
 </script>
 <script src="//asprise.azureedge.net/scannerjs/scanner.js" type="text/javascript"></script>

Delayed Initialization

By default, scanner.js will initialize on page load. You may disable it by setting eager_init to false. In this case, you need to initialize manually by calling scanner.initialize().

Changing User Interfaces of Notification Dialogs

When the user invokes a scan operation and scan app is not connected, scanner.js will present a dialog prompting the user to download and run the scan app. After scan app is enabled, scanner.js will then dismiss it and displays an ‘OK’ dialog to notify the user.

Styling the dialogs

Below is a HTML code snippet illustrating the structure of the notification dialogs:

HTML structure of notification dialogs
<div id="asprise-web-scan-setup-dialog-wrapper" class="asprise-web-scan-dialog-wrapper">
   <div id="asprise-web-scan-setup-dialog-overlay" class="overlay asprise-web-scan-dialog-display"></div>
   <div id="asprise-web-scan-setup-dialog" class="asprise-web-scan-dialog asprise-web-scan-dialog-display"> ... </div>
   <div id="asprise-web-scan-setup-ok-dialog" class="asprise-web-scan-dialog small-dialog asprise-web-scan-setup-ok-dialog"> ... </div>
</div>

You can easily style these dialogs using CSS with selectors of id and/or classes.

If you need to have something completely different from the standard default dialogs, you can:

Implement your own notification UI

To do so, you need to implement and configure two functions.

List of scanner.js configuration options
window.scannerjs_config = {
   // specify a func(Boolean show) to be called to show/hide scan app prompt dialog
   display_install_func: function(show) {
       console.log("Display enabling scan app dialog? " + show);
       if(show) {
           $('#dialog-enable-scan').show(500);
       } else {
           $('#dialog-enable-scan').hide();
       }
       // return true; // 'return true' to continue the default behavior of showing/hiding the standard dialog
   },

   // specify a func() to be called upon scanning is enabled
   display_scan_ready_func: function() {
       console.log("Ready to scan.");
       $('#dialog-ready-to-scan').show().delay(1500).fadeOut();
   }
};

Using Java Applet Instead of the Scan App

If most of your end users are using browsers that supports Java applet, you can configure scanner.js to use Java applet instead of the scan app:

Use Java applet for scanning
window.scannerjs_config = {
   scan_app_enabled: false, // true (default): enable scan app; false: disable scan app
   java_applet_enabled: true // false (default): don't use Java applet even if the browser supports it; true: enable Java applet support
};

Obtain a License for Production Use

So you have finished developing your scanner enabled web app. It’s time to make it available to the end users. First, order a license from us. Once you receive the license code, you can put it in the configuration object:

window.scannerjs_config = {
   license: 'LICENSE_CODE'
};

The above one line completes the license application. No server activiation or any actions required from you or your end users.

Happy scanning.