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.
The main benefit of this system is that it allows you to maintain one code base that works across all browsers supporting HTML5.
Currently LEADTOOLS only supports scanning, using TWAIN, on Windows operating system and using SANE, on Linux operating system.
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.
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.
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.
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.
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.
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:
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.
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.
The IScanning
interface defines the basic functionality for the Web
Scanning framework.
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 |
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. |
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
.
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 |
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.
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:
Flip, Rotate, Deskew, Hole Punch Remove (unsupported on Linux), Border Remove
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.
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.
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.
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.
SaveToLocalParams param = new SaveToLocalParams();
param.filename = GetFileName();
param.format = GetFileFormat();
$.get(_scanningService.runCommand("SaveToLocal", param, null));
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);
}
}
}
SaveToMemoryParams param = new SaveToMemoryParams();
param.format = GetFileFormat();
$.get( twainService.runCommand("SaveToMemory", args, null), function (memoryFile) { alert("success"); });
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;
}
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
.
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.
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.
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.
Overview |
Components |
Using API |