How to Build Angular Document Scanner with Dynamsoft Web Capture SDK

Xiao Ling - Jun 22 '22 - - Dev Community

Dynamsoft Web Capture SDK is a camera-based document scanning SDK implemented in WebAssembly and JavaScript. Comparing to Dynamic Web TWAIN, the classic web scanner SDK, there is no local service installation required, which means the web capture SDK can work in any desktop browser, mobile browser, and WebView. This article guides you through how to build an Angular document scanner app using the web capture SDK from scratch.

Angular Development Environment

  • Node.js
  • Angular CLI v13.3.7

    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
    
  • Dynamsoft Web Capture SDK v17.2.5

Creating Angular Document Scanner App Step by Step

We scaffold a new Angular project via ng new command and install Dynamsoft Web Capture SDK in terminal:

ng new angular-document-scanner
cd angular-document-scanner
npm i mobile-web-capture
Enter fullscreen mode Exit fullscreen mode

Then open the angular.json file to configure the assets.


"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"
      }
    ...
    ],
  },
  ...
},

Enter fullscreen mode Exit fullscreen mode

When running ng build, all static resource files will be copied to the assets/dynamic-web-twain folder.

The next step is to create a document scanner component, which contains document-scanner.component.css, document-scanner.component.html, document-scanner.component.spec.ts, and document-scanner.component.ts files.

ng generate component document-scanner
Enter fullscreen mode Exit fullscreen mode

The target UI layout includes following elements:

  • 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.

The UI implementation in document-scanner.component.html is as follows:


<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>
Enter fullscreen mode Exit fullscreen mode

Now, we are going to add the corresponding TypeScript code in document-scanner.component.ts.

  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';  
    
  2. In ngOnInit(), initialize the SDK.

    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(); });
    }
    

    Two things need to be noted here:

    • 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.
  3. Once the OnWebTwainReady event is triggered, we get the SDK instance and update the camera source list.

    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);
          }
    
        });
      }
    }
    
  4. Select a camera source and start document scanning.

    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); });
      }
    
    }
    
  5. After capturing and editing a document image, we can save it to local disk.

    downloadDocument() {
      if (this.dwtObject) {
        this.dwtObject.SaveAsJPEG("document.jpg", this.dwtObject.CurrentImageIndexInBuffer);
      }
    }
    
  6. Run the Angular document scanner in desktop and mobile browsers:

    ng serve --ssl
    

    Desktop browser

    Angular document scanner for desktop browser

    Mobile browser

    Angular document scanner for mobile browser

GitHub Page Deployment

One more thing is to deploy the Angular document scanner project to GitHub pages.

Here are the steps:

  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"
      },
    ]
    
  2. Create a GitHub action workflow:

    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: ${{ secrets.GITHUB_TOKEN }} 
            build_configuration: production 
            base_href: /angular-document-scanner/   
            deploy_branch: gh-pages 
            angular_dist_build_folder: dist/angular-document-scanner
    
    

    You need to replace angular-document-scanner with your project name.

  3. After the build is done, go to your GitHub Settings > Pages to launch the GtiHub page with the gh-pages branch. Don't forget to check the Enforce HTTPS option.

Try the Demo Page

https://yushulx.me/angular-document-scanner/

Source Code

https://github.com/yushulx/angular-document-scanner

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Terabox Video Player