Web Scanning Framework (original) (raw)
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.
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:
- Get and Set scanning settings (capabilities)
- Scan single or multiple pages from the scanner
- Check if any scanners are installed on the machine
- Obtain a list of scanners installed
- Select a particular scanner to use
- Cancel a scan
- Use either the TWAIN 1.X library (twain_32.dll) or the TWAIN 2.X library (TwainDSM.dll). Some legacy scanners do not work well with the newer TWAIN 2.X library.
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: LEADTOOLS22\Examples\Scanning\DotNet\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 Processingfunctions, or by adding code from any other 3rd party.
Command Callback
Windows
Location: LEADTOOLS22\Examples\Scanning\DotNet\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: LEADTOOLS22\Examples\Scanning\DotNet\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: LEADTOOLS22\Examples\Scanning\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 (\LEADTOOLS22\Examples\Scanning\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: LEADTOOLS22\Examples\Scanning\JS\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:
- The url used for launching the Service Hosting Application from the browser.
- The Leadtools.WebScanning.Plugin.dll (ActiveX component) used for launching the Service Hosting Application in Internet Explorer. This is an optional plugin and can be replaced by the application's url like the rest of the browsers.
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.TwainAssembly and the Leadtools.SaneAssembly 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)
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: LEADTOOLS22\Examples\Scanning\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.
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 theLeadtools.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:
- Select Scanner
- Acquire images
- Flip, Rotate, Deskew, Hole Punch Remove (unsupported on Linux), Border Remove
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 theTwainService.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 forgetTwainCapability
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 forsetTwainCapability
to find the function.
Helpful links
Troubleshooting
HTTP could not register URLhttp://+: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 theLeadtools.WebScanning.Host.exe
without any issues using the sample web page that ships with the toolkit.