How to Digitize Paper Documents in Angular Web Applications
In a world that is increasingly digital, the ability to transform physical paper documents into electronic files by scanning them from a multi-function printer (MFP) has become a fundamental requirement for businesses of all sizes. Scanning paper documents helps create a more organized and efficient workspace. E-documents foster better collaboration between employees and departments in an organization.Dynamic Web TWAIN was developed to help developers build web-based document scanning applications. Since version 18.0, Dynamic Web TWAIN has introduced a new feature called Remote Scan, which allows users to wirelessly scan paper documents from a web browser on any device. In this article, we will dive into the Remote Scan feature by building a web application with Angular.
This article is Part 1 in a 5-Part Series.
- Part 1 - How to Digitize Paper Documents in Angular Web Applications
- Part 2 - How to Build an Angular Barcode & QR Code Detection App: A Step-by-Step Guide
- Part 3 - How to Detect and Rectify Documents in Angular Web Applications
- Part 4 - Steps to Develop an Angular Passport MRZ Reader & Scanner
- Part 5 - Building an Angular Document Viewer for Image Loading, Annotation, and PDF Export
Angular Web TWAIN Document Scanning Demo
What is Dynamic Web TWAIN Remote Scan?
Dynamic Web TWAIN is designed using the C/S (Client/Server) model. The SDK package comprises two parts: a client-side JavaScript library and a Dynamsoft service that includes a built-in web server and scanner access modules. The client-side library communicates with the Dynamsoft service via the HTTP/HTTPS protocol.
Before version 18.0, the Dynamsoft service was only accessible from the host machine itself via localhost
or 127.0.0.1
. When you opened a web page integrated with Dynamic Web TWAIN, you had to install the Dynamsoft service the first time.
The Remote Scan feature removes the restriction of accessing the Dynamsoft service solely from the host machine. It exposes the Dynamsoft service via a public IP address or domain name using Bonjour. Additionally, it provides a proxy service, built with Bonjour technology, to help you discover all Dynamsoft services running on the local network.
Why is Remote Scan Superior to Local Host Scan?
- You don’t need to install the Dynamsoft service on every host machine. A single PC can transform all TWAIN scanners on the local network into web scanners.
- You can easily scan paper documents to Windows, Linux, macOS, Android, iOS, Chrome OS, and Raspberry Pi without concerns about MFP driver compatibility.
Try the Official Online Demo
Prerequisites
- Angular CLI: A command-line interface tool for Angular development.
npm install -g @angular/cli
- Angular Snippets for Dynamic Web TWAIN: A Visual Studio Code extension that helps you quickly create an Angular application with Dynamic Web TWAIN
- Dynamic Web TWAIN SDK: The package contains the client-side JavaScript library and the Dynamsoft service.
- Trial license key for Dynamic Web TWAIN
Setting Up Dynamsoft Service and Proxy in Windows
Making host machines discoverable via Bonjour
-
Install Dynamsoft service on every host machine that has a TWAIN scanner connected.
-
Open
http://127.0.0.1:18625/
in your web browser to enable the host machine to be accessed from the local network. By default, the network access is disabled.
Configuring the proxy service
-
Install the proxy service package as an administrator on a host machine. The proxy service manages data transmission between the client-side library and the Dynamsoft service, functioning similarly to a router. If deployed on a powerful server, a single proxy service can serve hundreds of users simultaneously. The proxy service can also be installed on cost-effective hardware like the Raspberry Pi. You can start with one Raspberry Pi and add more devices to manage traffic as scaling needs arise.
-
Visit
http://127.0.0.1:18625/admin/proxy.html
to enable the proxy service. -
Open https://www.dynamsoft.com/customer/account/certificate to bind your IP address to a custom domain. The domain name is used to access the proxy service from the client-side library. The certificate is used for HTTPS communication between the client-side library and the proxy service.
-
Upload the certificate and then click the Update button to activate the proxy service.
Quick Start an Angular Application for Document Scanning
- Install the Visual Studio extension Angular Snippets for Dynamic Web TWAIN.
-
Press
Ctrl+Shift+P
to open the command palette and then select DWT: Create Angular Application to create an Angular application with Dynamic Web TWAIN. -
Request a 30-day FREE trial license and update the license key in
src/app/dynamic-web-twain.service.ts
:Dynamsoft.DWT.ProductKey = "LICENSE-KEY";
-
Run
npm install && ng serve --ssl
to start the application.
Create an Angular Component to Support Remote Scan
Create a new Angular component named remote-scan
:
ng generate component remote-scan
Open remote-scan.component.html
to add the following HTML code:
<div class="row">
<label for="BW">
<input type="radio" value="0" name="PixelType">B&W </label>
<label for="Gray">
<input type="radio" value="1" name="PixelType">Gray</label>
<label for="RGB">
<input type="radio" value="2" name="PixelType" checked="checked">Color</label>
</div>
<div>Service:
<select (change)="onServiceChange($event)">
<option *ngFor="let option of serviceOptions" [value]="option.value"></option>
</select>
</div>
<div>Source: <select id="sources"></select></div>
<button (click)="acquireImage()">Scan Documents</button>
<div id="dwtcontrolContainer"></div>
<div class="row">
<label style="font-size: x-large;">
<input type="radio" value="jpg" name="ImageType" id="imgTypejpeg" />JPEG</label>
<label style="font-size: x-large;">
<input type="radio" value="tif" name="ImageType" id="imgTypetiff" />TIFF</label>
<label style="font-size: x-large;">
<input type="radio" value="pdf" name="ImageType" id="imgTypepdf" checked="checked" />PDF</label>
</div>
<button (click)="downloadDocument()">Download Documents</button>
Compared to local host scanning, which only lists connected devices, an additional <select>
element is added to allow users to choose the Dynamsoft service first. Once the service is selected, the <select>
element for TWAIN sources will update accordingly.
Now, open remote-scan.component.ts
to add TypeScript code.
-
Import the relevant modules:
import { Component, OnInit } from '@angular/core'; import Dynamsoft from 'dwt'; import { RemoteScanObject } from 'dwt/dist/types/RemoteScan'; import { ServiceInfo, Device, DeviceConfiguration } from 'dwt/dist/types/WebTwain.Acquire'; import { DynamicWebTWAINService } from '../dynamic-web-twain.service';
-
Initialize a remote scanning object with an HTTP/HTTPS address:
ngOnInit(): void { this.onReady(); } async onReady(): Promise<void> { var serverurl = "document.scannerproxy.com:18602"; if (window.location.protocol === 'https:') { serverurl = "document.scannerproxy.com:18604"; } this.dwtObject = await Dynamsoft.DWT.CreateRemoteScanObjectAsync(serverurl); this.container = document.getElementById("dwtcontrolContainer") as HTMLElement; this.container.style.width = 600 + "px"; this.container.style.height = 600 + "px"; let ret = this.dwtObject.Viewer.bind(this.container); ret = this.dwtObject.Viewer.show(); }
You can also change the
serverurl
tohttps://demo.scannerproxy.com
, a public service provided by Dynamsoft. This is intended solely for testing purposes and should not be used in production. -
Find all services and relevant devices:
this.services = await this.dwtObject.getDynamsoftService(); if (this.services) { if (this.services.length > 0) { this.serviceOptions.splice(0, 1); } for (let i = 0; i < this.services.length; i++) { let service = this.services[i]; if (service.attrs.name.length > 0) { this.serviceOptions.push({ label: service.attrs.name, value: service.attrs.UUID }); } else { this.serviceOptions.push({ label: service.attrs.UUID, value: service.attrs.UUID }); } } } async findSources(service: ServiceInfo): Promise<void> { var devicetype = Dynamsoft.DWT.EnumDWT_DeviceType.TWAINSCANNER | Dynamsoft.DWT.EnumDWT_DeviceType.WIASCANNER | Dynamsoft.DWT.EnumDWT_DeviceType.TWAINX64SCANNER | Dynamsoft.DWT.EnumDWT_DeviceType.ICASCANNER | Dynamsoft.DWT.EnumDWT_DeviceType.SANESCANNER | Dynamsoft.DWT.EnumDWT_DeviceType.ESCLSCANNER | Dynamsoft.DWT.EnumDWT_DeviceType.WIFIDIRECTSCANNER; this.devices = await this.dwtObject!.getDevices({ serviceInfo: service, deviceType: devicetype, }); if (this.devices) { this.selectSources = <HTMLSelectElement>document.getElementById("sources"); this.selectSources.options.length = 0; for (let i = 0; i < this.devices.length; i++) { this.selectSources.options.add(new Option(this.devices[i].name, i.toString())); } } }
-
Acquire paper documents from scanners and save them as
JPEG
,TIFF
orPDF
:acquireImage(): void { if (!this.dwtObject) return; let pixelType = '2'; var pixelTypeInputs = document.getElementsByName("PixelType"); for (var i = 0; i < pixelTypeInputs.length; i++) { if ((<HTMLInputElement>pixelTypeInputs[i]).checked) { pixelType = (<HTMLSelectElement>pixelTypeInputs[i]).value; break; } } let type = Dynamsoft.DWT.EnumDWT_PixelType.TWPT_RGB; if (pixelType === '0') { type = Dynamsoft.DWT.EnumDWT_PixelType.TWPT_BW; } else if (pixelType === '1') { type = Dynamsoft.DWT.EnumDWT_PixelType.TWPT_GRAY; } let config : DeviceConfiguration = { PixelType: type, }; this.dwtObject.acquireImage(this.devices![this.selectSources!.selectedIndex], config); } downloadDocument() { if (this.dwtObject && this.dwtObject.howManyImagesInBuffer > 0) { if ((<HTMLInputElement>document.getElementById("imgTypejpeg")).checked == true) { this.dwtObject.saveImages('DynamicWebTWAIN.pdf', [this.dwtObject!.currentImageIndexInBuffer], Dynamsoft.DWT.EnumDWT_ImageType.IT_JPG); } else if ((<HTMLInputElement>document.getElementById("imgTypetiff")).checked == true) { let indexes = Array.from({ length: this.dwtObject.howManyImagesInBuffer }, (_, index) => index); this.dwtObject.saveImages('DynamicWebTWAIN.pdf', indexes, Dynamsoft.DWT.EnumDWT_ImageType.IT_TIF); } else if ((<HTMLInputElement>document.getElementById("imgTypepdf")).checked == true) { let indexes = Array.from({ length: this.dwtObject.howManyImagesInBuffer }, (_, index) => index); this.dwtObject.saveImages('DynamicWebTWAIN.pdf', indexes, Dynamsoft.DWT.EnumDWT_ImageType.IT_PDF); } } }
Testing the Angular Application for Document Scanning
npm install
ng server --ssl
Source Code
https://github.com/yushulx/web-twain-document-scan-management/tree/main/examples/angular