How to Build Angular Document Scanner with Dynamsoft Web Capture SDK

Angular Development Environment

npm install -g @angular/cli

ng --version

Angular CLI: 13.3.7
Node: 16.13.1
Package Manager: npm 8.1.2
OS: win32 x64

Angular: 13.3.10
... animations, common, compiler, compiler-cli, core, forms
... platform-browser, platform-browser-dynamic, router

Package Version
---------------------------------------------------------
@angular-devkit/architect 0.1303.7
@angular-devkit/build-angular 13.3.7
@angular-devkit/core 13.3.7
@angular-devkit/schematics 13.3.7
@angular/cli 13.3.7
@schematics/angular 13.3.7
ng-packagr 13.3.1
rxjs 7.5.5
typescript 4.6.4

Creating Angular Document Scanner App Step by Step

ng new angular-document-scanner
cd angular-document-scanner
npm i mobile-web-capture
"build": 
{
"builder": "@angular-devkit/build-angular:browser",
"options": {
...
"assets": [
"src/favicon.ico",
"src/assets",
{
"glob": "**/*",
"input": "./node_modules/mobile-web-capture/dist",
"output": "assets/dynamic-web-twain"
}
...
],
},
...
},
ng generate component document-scanner
  • An HTMLSelectElement for selecting the camera sources. For desktop browsers, all USB cameras are listed. For mobile browsers, all front-facing and back-facing cameras are listed.
  • A button used to trigger document scanning and a button used to download the scanned document.
  • An HTMLDivElement set as the container for storing the scanned and processed document images.
<div class="document-scanner">
<h1>Angular Document Scanner</h1>
<div>
<label for="videoSource">Video source: </label>
<select id="videoSource"></select>
<p></p>
<button id="scanButton" (click)="scanDocument()">Scan Document</button> <button id="scanButton" (click)="downloadDocument()">Download Document</button>
</div>

<h3>Document Container</h3>
<div id="dwtcontrolContainer"></div>

</div>
  1. Import the SDK module from mobile-web-capture package.
import Dynamsoft from 'mobile-web-capture';
import { WebTwain } from 'mobile-web-capture/dist/types/WebTwain';
dwtObject: WebTwain | undefined;
videoSelect: HTMLSelectElement | undefined;
sourceDict: any = {};

ngOnInit(): void {
this.videoSelect = document.querySelector('select#videoSource') as HTMLSelectElement;
Dynamsoft.DWT.ProductKey = "LICENSE-KEY";
Dynamsoft.DWT.ResourcesPath = 'assets/dynamic-web-twain';
Dynamsoft.DWT.Containers = [{ ContainerId: 'dwtcontrolContainer' }];
Dynamsoft.DWT.UseLocalService = false;
Dynamsoft.DWT.Load();
Dynamsoft.DWT.RegisterEvent('OnWebTwainReady', () => { this.onReady(); });
}
  • Apply for a 30-day trial license and thereafter update the LICENSE-KEY.
  • Set the resource path assets/dynamic-web-twain as we configure above in angular.json file.
onReady() {
this.dwtObject = Dynamsoft.DWT.GetWebTwain('dwtcontrolContainer');
this.updateCameraList();
}

updateCameraList() {
if (this.videoSelect && this.dwtObject) {
this.videoSelect.options.length = 0;
this.dwtObject.Addon.Camera.getSourceList().then((list) => {
for (var i = 0; i < list.length; i++) {
var option = document.createElement('option');
option.text = list[i].label || list[i].deviceId;
if (list[i].label) {
this.sourceDict[list[i].label] = list[i].deviceId;
}
else {
this.sourceDict[list[i].deviceId] = list[i].deviceId;
}
if (this.videoSelect) this.videoSelect.options.add(option);
}

});
}
}
scanDocument() {
if (this.videoSelect) {
let index = this.videoSelect.selectedIndex;
if (index < 0) return;

var option = this.videoSelect.options[index];
if (this.dwtObject) {
this.dwtObject.Addon.Camera.selectSource(this.sourceDict[option.text]).then(camera => {
if (this.videoSelect) this.createCameraScanner(this.sourceDict[option.text]);
});
}

}

}

async createCameraScanner(deviceId: string): Promise<void> {
if (this.dwtObject) {
await this.dwtObject.Addon.Camera.closeVideo();
this.dwtObject.Addon.Camera.scanDocument({
scannerViewer: {
deviceId: deviceId,
fullScreen: true,
autoDetect: {
enableAutoDetect: true
},
continuousScan: {
visibility: false,
enableContinuousScan: false
}
}

}).then(
function () { console.log("OK"); },
function (error: any) { console.log(error.message); });
}

}
downloadDocument() {
if (this.dwtObject) {
this.dwtObject.SaveAsJPEG("document.jpg", this.dwtObject.CurrentImageIndexInBuffer);
}
}
ng serve --ssl

GitHub Page Deployment

  1. Open angular.json file to increase the size budgets. The default budgets setting may cause the error: WARNING in budgets, maximum exceeded for initial.
"budgets": [
{
"type": "initial",
"maximumWarning": "2.5mb",
"maximumError": "5mb"
},
]
name: Build and Deploy
on:
push:
branches:
- main
jobs:
build:

runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v2
- name: All things angular
uses: AhsanAyaz/angular-deploy-gh-pages-actions@v1.3.2
with:
github_access_token: $
build_configuration: production
base_href: /angular-document-scanner/
deploy_branch: gh-pages
angular_dist_build_folder: dist/angular-document-scanner

Source Code

--

--

--

Manager of Dynamsoft Open Source Projects | Tech Lover

Love podcasts or audiobooks? Learn on the go with our new app.

Recommended from Medium

Typescript made simple

VSCode Jest Setup

DATEV Nine-Nine | Apps, libs and module-boundaries in a Nx Monorepo

ASYNCHRONOUS CONCEPT

Javascript is Weird

Some cool and awesome JavaScript tricks

Charts with SVGs in Angular2+

How to setup your Workflow using Gulp v4.0.0

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Xiao Ling

Xiao Ling

Manager of Dynamsoft Open Source Projects | Tech Lover

More from Medium

InboxPro | Made with Angular JS

InboxPro | Made with Angular JS

Angular 13: Custom form validator

Angular Libraries: entry-points, path mappings and workspace configurations

How to Build a Responsive Dashboard Application in Angular — Part 2