Web Scanning Framework



Overview

The Web Scanning Demo is composed of a website (client) and an executable (service).

Below is a diagram of the entire system working with a scanner, file system, and the cloud.

Diagram of Web Scanning Setup

The client code is simply JavaScript that communicates with a self-hosted web service (scanning service), which in turn communicates with the scanner. The scanning service also contains functionality for allowing any other API function to be used. The sample demonstrates how to use LEAD's image processing features (flip, rotate, border remove, hole punch remove, and deskew).

The source code for the executable hosting the scanning service is provided so you can add additional libraries as needed, brand the EXE as necessary, and package the executable using a packaging software of your choice.

The viewer contains a thumbnail list of each page scanned. It resides to the left of the main viewer.

After the user has finished scanning and editing the images, they can be saved to the client's local drive or saved to memory. Once saved, the file can be sent to a server such as Microsoft's SharePoint, Microsoft's One Drive, Google Docs, etc.

Benefits

The main benefit of this system is that it allows you to maintain one code base that works across all browsers supporting HTML5.

Limitations

Currently LEADTOOLS only supports scanning, using TWAIN, on Windows operating system and using SANE, on Linux operating system.

Components

Scanning Service

Windows

Location: Leadtools.Services.Twain.dll

The Scanning Service is housed as a library hosted in an executable named Leadtools.WebScanning.Host.exe., which provides the library and the executable in both 32- and 64 bit. The executable must be downloaded and installed on the client's machine to communicate with the scanner located on the client's machine. The Scanning Service receives REST-based commands from the JavaScript code in the client page and turns them into TWAIN commands. If the JavaScript demo cannot communicate with the Scanning Service, it displays a dialog with a message and offers a link to download the installer (an *.msi file).

The Scanning Service has the following functionality:

Additional features, such as obtaining scanning status, are also available.

The Scanning Service relies on LEADTOOLS libraries to both communicate with the TWAIN device and to provide image processing features. The LEADTOOLS libraries are distributed as part of the Scanning Service installer.

Image Processing

Windows

Location: LEADTOOLS21\Examples\DotNet\CS\Leadtools.WebScanning.Host\Service\ImageProcessing.cs

The Scanning Service uses an extensible interface to call defined image processing functions. It allows you to use JavaScript to send a request specifying the image processing function name, parameters, and page number to act on. The scanning service receives the request and calls the corresponding image processing function. You can extend the functions available by adding any of LEADTOOLS Image Processing functions, or by adding code from any other 3rd party.

Command Callback

Windows

Location: LEADTOOLS21\Examples\DotNet\CS\Leadtools.WebScanning.Host\UI\WebScanningForm.cs

In addition to creating an extensible image processing interface, you can also call any custom code from within the scanning service executable (Leadtools.WebScanning.Host.exe). From JavaScript, simply send a command name and parameters to the scanning service. This will call a function that receives the command name and parameters and from there you can add any additional business logic necessary.

private Stream CommandCallBack(CommandEventArgs args) 
{ 
   Console.WriteLine(args.CommandName); 
   Console.WriteLine(args.Arguments); 
   //TODO: Handle user  
   command return null; 
} 

For instance, you may want to add code to save all scanned pages to a file in memory, then use a 3rd party cloud storage API to store the file to the cloud. Or you may just want to allow a user to save a copy of the scanned pages to their local machine.

Service Hosting Application

Windows

Location: LEADTOOLS21\Examples\DotNet\CS\Leadtools.WebScanning.Host

This is the Windows Application project that references, hosts the Scanning Service, and holds the code for the Image Processing and Command Callback functionality.

The code for the application exposes the host class allowing for adjustments to the URL, port number, and protocol (HTTP/HTTPS) the Scanner Service will be listening under. You can adjust the bindings and endpoints as necessary as well.

After installation, the Leadtools.WebScanning.Host.exe runs as a Windows Application, but hidden from view. The user will see it appear in their system tray as an icon. The icon can be replaced with your company's brand.

The user can right-click the icon and select to close the application, or open a dialog displaying an option to have the application start up whenever Windows starts. This dialog can also be modified to add additional settings and branding as well.

Client-Side JavaScript

Location: LEADTOOLS21\\Examples\\JS\\ScanningDemo

The client-side JavaScript site's main JavaScript code is in the ScanningDemo\App\Main.js file. This code uses the Leadtools.Scanning.js (\LEADTOOLS21\Examples\JS\ScanningDemo\Common\Libs) code to communicate with the scanning service sending commands using Web requests.

The Leadtools.Scanning.js code contains an IScanning interface as well as the TwainScanning and TwainService implementations to provide TWAIN-specific functionality. The most predominantly used TWAIN constants have also been defined to allow for IntelliSense programming within Typescript.

The source code to this demo is provided to jump-start your project. For instance, quickly modify the "look and feel" of the demo page or add to it functions specific to your solution.

Installer Project

Location: LEADTOOLS21\Examples\DotNet\CS\WebScanning.Setup

The installer project allows you to build the *.msi file which contains the Scanning Service and its required dependencies. Use this project to add additional dependencies you may need to deploy with the Scanning Service. For instance, if you add additional image processing features, you may need to deploy additional LEADTOOLS image processing libraries with the Scanning Service.

The installer registers:

Using the API

Portions of the API for this system are documented within LEAD's Online Documentation. Other portions are not documented because the source code to the component is provided. The documentation for the Leadtools.Services.Twain Assembly and the Leadtools.Sane Assembly can be found online.

The following sections describe the portions of the provided source code that are the most relevant to the functionality of the system.

Classes / Hierarchy (High-Level View)

web-scanning-hierarchy.jpg

IScanning

The IScanning interface defines the basic functionality for the Web Scanning framework.

TwainScanning

TwainScanning derives from IScanning, this is the TWAIN implementation class. TwainScanning uses the TwainService class to send messages to the Web Scanning Service. TwainService functions and their descriptions are the same as in IScanning.

Function Description
Init Attempts to launch the hosting application
getStatus Obtains the status of a scan (either scanning or not)
getSources Obtains a list of all devices available for scanning
selectSource Selects a device for scanning
Acquire Initiates the scanning process
getPage Obtains a page that has been scanned from the scanning service
Stop Ends a scanning session
Start Begins a scanning session
applyImageProcessingCommand Applies an image processing command to a specific page
getImageProcessingPreview Obtains a preview image for the specified image processing command
runCommand Sends a custom user command to the Scanning Service for processing
getHandle Obtains the handle to the underlying implementation class which may provide more specific functionality

TwainService

Although the class does not derive from the IScanning interface, it provides an implementation for each of the functions. The class essentially is a proxy class as it builds the command that is sent to the Web Scanning Service. It also contains TWAIN-specific functionality such as retrieving and modifying a scanner's settings (known as capabilities).

Function Description
abortAcquire Aborts an acquisition currently in progress
setCapabilityValue Changes the current value of a scanner's setting
getCapability Obtains the current, default, and all possible values for a scanner's setting
deletePage Removes a scanned page from the Web Scanning Service
isAvailable Determines whether a TWAIN source is installed
setVersion Allows selection of the version of the TWAIN library that is used by the Web Scanning Service. By calling this function with Version 1, the Web Scanning Service will attempt to use the twain32.dll. By calling this function with Version 1 the Web Scanning Service will attempt to use the TwainDSM.dll.

SaneScanning

Deriving from IScanning, this is the SANE implementation class. This class uses the SaneService class to send the message to the Web Scanning Service. The functions have similar descriptions as in IScanning.

SaneService

Although the class does not derive from the IScanning interface, it provides an implementation for each of the functions. The class essentially is a proxy class as it builds the command that is sent to the Web Scanning Service. It also contains SANE specific functionality such as retrieving and modifying a scanner's settings known as options.

Function Description
abortAcquire Aborts an acquisition currently in progress
setOptionValue Changes the current value of a scanner's setting
getOptionValue Obtains the current, default, and all possible values for a scanner's setting
deletePage Removes a scanned page from the Web Scanning Service

Client-Side/JavaScript/Browser

Location: LEADTOOLS21\Examples\JS\ScanningDemo

This web application provides the user interface for the system. It communicates directly with the Scanning Service where all actions are initiated by the user.

web-scanning-browser.jpg

When the window loads (window.onload) the Scanning Service is started using the startScanningService(...); function. In this function a new instance of the lt.Scanning.JavaScript.IScanning is created and a connection with the Scanning Service is established. If the Leadtools.WebScanning.Host.exe is not running, the framework will automatically launch the application. The user may see a warning in their browser that the web site is attempting to launch an application on their machine. This is a standard dialog created by the browser.

Once connected and scanners are found on the device, the demo then lets the user perform these common two tasks with scanning, and some common image processing functionality with each of the pages:

Demo Showcased Functionality

Select Scanner

In the Main.ts file the function selectSourceBtn_Click first obtains a list of scanners installed on the machine using the _scanningService.getSources function. This function will send a request to the Scanning Service which will use the LEADTOOLS Twain API to obtain a list of TWAIN scanners installed on the machine.

After the list of scanner names is obtained, a UI element is populated with the names and a dialog is presented to the user.

When the user selects a scanner name, the code in Main.ts (under #selectSourceDialog) is called, where _scanningService.selectSource is ultimately called, passing in the name for the scanner.

Acquire

In the Main.ts file the function scanBtn_Click first calls the _scanningService.acquire function to begin the scanning process. The default behavior is to show the manufacturer's dialog for the scanner; this is the first parameter in the acquire function.

When the acquire function returns, all pages will have been scanned and saved in a temporary cache.

You have access to each image using the _scanningService.getPage function, which returns the location of the page in the form of URL. This allows minimal code to assign each page to HTML image elements.

You can also remove a page from the cache using the TwainService.deletePage function.

Image Processing

In the Main.ts file the _scanningService.applyImageProcessingCommand function sends a request to the Scanning Service and end up in the Image Processing event for the Scanning Service.

The applyImageProcessingCommand lets you specify a starting and ending page as well as to process multiple pages in one function call.

Command Callback

Although not found in the demo, the _scanningService.runCommand function allows you to send a command name and parameters to the Scanning Service, along with any user data.

The Scanning Service receives the request in an event with the event arguments containing each of the parameters. You then have the ability to do something with the data using your own custom code.

Sample: Save Scanned Images to Local Drive

JavaScript
SaveToLocalParams param = new SaveToLocalParams();  
param.filename = GetFileName(); 
param.format = GetFileFormat(); 
$.get(_scanningService.runCommand("SaveToLocal", param, null)); 

Scanning Service
private Stream CommandCallBack(CommandEventArgs args) 
{ 
  if(args.CommandName == "SaveToLocal")  
  {  
     SaveToLocalParams params = Json.Parse(args.Arguments); 
     SaveToLocal(params);  
  }  
  return null;  
} 
 
private void SaveToLocal(SaveToLocalParams e) 
{    
   RasterImage page = null; 
   RasterCodecs codecs = new RasterCodecs(); 
   TwainStatus status = this.ScanningService.GetStatus(id, userData); 
    
   for (int pageNumber = 1; pageNumber <= status.PagesCount; pageNumber++)    
   {    
      page = this.ScanningService.GetImage(id, pageNumber);  
      if (page != null)    
      {       
         codecs.Save(page, e.Filename, e.Format, 0, 1, 1, -1, CodecsSavePageMode.Append); 
      }    
   }  
} 

Sample: Save Scanned Images to Memory and Return

JavaScript
SaveToMemoryParams param = new SaveToMemoryParams();  
param.format = GetFileFormat(); 
$.get( twainService.runCommand("SaveToMemory", args, null), function (memoryFile) { alert("success"); }); 

Scanning Service
private Stream CommandCallBack(CommandEventArgs args) 
{ 
   if(args.CommandName == "SaveToMemory")    
   {    
      SaveToMemoryParams params = Json.Parse(args.Arguments); Stream s = 
      SaveToMemory(params); 
       
      WebOperationContext.Current.OutgoingRequest.ContentType = 
      GetContentType(params.Format); 
      WebOperationContext.Current.OutgoingRequest.ContentLength = s.Length;       
      return s;    
   }    
   return null; 
} 
 
private Stream SaveToMemory(SaveToMemoryParams e) 
{ 
   RasterImage page = null;    
   RasterCodecs codecs = new RasterCodecs();    
   MemoryStream ms = new MemoryStream();    
   TwainStatus status = this.ScanningService.GetStatus(id, userData);    
   for (int pageNumber = 1; pageNumber <= status.PagesCount; pageNumber++) 
   {    
      page = this.ScanningService.GetImage(id, pageNumber);  
      if (page != null)    
      {    
         codecs.Save(page, ms, e.Format, 0, 1, 1, -1, CodecsSavePageMode.Append);    
      }    
   }    
   return ms; 
} 

Additional functionality

GetHandle

The _scanningService.getHandle function allows you to obtain a reference to the underlying TwainService class the TwainScanning class uses. This allows you to make calls to the TwainService using functions specific to the service. These functions include abortAcquire, getCapability, setCapability, deletePage, and setVersion.

GetCapability

Sample code for how to use this function can be found within the Scanning Demo project in the Main.ts file. Search for getTwainCapability to find the function.

SetCapability

Sample code for how to use this function can be found within the Scanning Demo project in the Main.ts file. Search for setTwainCapability to find the function.

Helpful links

Troubleshooting

HTTP could not register URL http://+:80/ScanService/

Full Error: HTTP could not register URL http://+:80/ScanService Your process does not have access rights to this namespace (see Configuring HTTP and HTTPS for details.)

If you receive this error, follow the directions at the specified link in the error to resolve it. The solution has been tested with a user from the "PowerUsers" group as well as a user from the "Users" group. After registering the URL with each user, the user was able to scan from the Leadtools.WebScanning.Host.exe without any issues using the sample web page that ships with the toolkit.

Top ^

Related Topics

Overview
Components
Using API
Help Version 21.0.2021.11.1
Products | Support | Contact Us | Intellectual Property Notices
© 1991-2021 LEAD Technologies, Inc. All Rights Reserved.

LEADTOOLS Imaging, Medical, and Document
Products | Support | Contact Us | Intellectual Property Notices
© 1991-2021 LEAD Technologies, Inc. All Rights Reserved.