How to Scan Document from Scanner and Camera Using JavaScript
Tags: documentscanning, javascript, camera, webdev
Published: 2022-01-26 01:19:28

As the dominant JavaScript document scanning SDK, [Dynamic Web TWAIN](https://www.dynamsoft.com/web-twain/features/mobile-web-capture-sdk/) has recently adopted WebAssembly as the new weapon. From version 17.2, Dynamic Web TWAIN does not only support cross-platform (Windows, Linux, and macOS) scanner access, but also allows developers to utilize desktop and mobile cameras to scan documents using JavaScript.

## SDK Installation and Activation
- [![javascript document scanning sdk](https://img.shields.io/badge/Download-Offline%20SDK-orange)](https://www.dynamsoft.com/web-twain/downloads)
- [![license applciation](https://img.shields.io/badge/Get-30--day%20FREE%20Trial%20License-blue)](https://www.dynamsoft.com/customer/license/trialLicense/?product=dwt)

Open `<Dynamic Web TWAIN version>/Resources/dynamsoft.webtwain.config.js` to configure the license key:

```javascript
Dynamsoft.DWT.ProductKey = 'LICENSE KEY';
```
    
Copy `<Dynamic Web TWAIN version>/Resources` to the static resource folder of your web project.
    
## The Crash Course of Building a Simple Web Document Scanning App
The ways of accessing scanner and camera using JavaScript are different. 


### Document Scanning from Scanner
For scanner, currently there is no standard JavaScript API available in browsers. The solution of Dynamic Web TWAIN is to run a local service accessing document scanners and transfer the scanned documents to the web page via web sockets. 

We create a `scanner.html` file with a few lines of HTML5 code to implement a simple web document scanning app:

```html
<!DOCTYPE html>
<html>

<head>
    <title>Scan Document from Scanner</title>
    <script type="text/javascript" src="Resources/dynamsoft.webtwain.initiate.js"></script>
    <script type="text/javascript" src="Resources/dynamsoft.webtwain.config.js"></script>
</head>

<body>
    <input type="button" value="scan" onclick="acquireScanner();" />

    <div id="container"></div>

    <script type="text/javascript">
        var scannerObj;
        Dynamsoft.DWT.CreateDWTObjectEx({
            WebTwainId: 'scanner',
            UseLocalService: true,
        }, function (obj) {
            scannerObj = obj;
            scannerObj.Viewer.bind(document.getElementById('container'));
            scannerObj.Viewer.width = 480;
            scannerObj.Viewer.height = 640;
            scannerObj.Viewer.show();
        }, function (ec, es) {
            console.log(es);
        });

        function acquireScanner() {
            if (scannerObj) {
                scannerObj.SelectSource();
                scannerObj.OpenSource();
                scannerObj.IfDisableSourceAfterAcquire = true;
                scannerObj.AcquireImage(() => {
                    scannerObj.CloseSource();
                }, () => {
                    scannerObj.CloseSource();
                });
            }
        }
    </script>
</body>
</html>

```

![scan document from scanner using JavaScript](https://www.dynamsoft.com/codepool/img/2022/01/capture-document-from-scanner.png)

You can run the `scanner.html` file in web browsers on Windows, macOS, and Linux. Dynamic Web TWAIN is the only JavaScript document scanning SDK that covers all desktop platforms.

### Document Scanning from Camera
Comparing to scanner, accessing camera is much easier because there is a [MediaDevices.getUserMedia()](https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia) method defined in the JavaScript standard. To save developers' time, Dynamic Web TWAIN wraps the `MediaDevices.getUserMedia()` method and provides the similar API as the scanner.

Create a `camera.html` file to implement document scanning from camera. The following code can work on both desktop and mobile web browsers.

```html
<!DOCTYPE html>
<html>

<head>
    <title>Scan Document from Camera</title>
    <script type="text/javascript" src="Resources/dynamsoft.webtwain.initiate.js"></script>
    <script type="text/javascript" src="Resources/dynamsoft.webtwain.config.js"></script>
    <script type="text/javascript" src="Resources/addon/dynamsoft.webtwain.addon.camera.js"></script>
</head>

<body>
    <input type="button" value="scan" onclick="acquireCamera();" />

    <div id="container"></div>
    <img id="img" src="" />

    <script type="text/javascript">
        var cameraObj;
        Dynamsoft.DWT.CreateDWTObjectEx({
            WebTwainId: 'camera',
            UseLocalService: false,
        }, function (obj) {
            cameraObj = obj;
            cameraObj.Viewer.bind(document.getElementById('container'));
            cameraObj.Viewer.width = 480;
            cameraObj.Viewer.height = 640;
            cameraObj.Viewer.show();
            cameraObj.Addon.Camera.play();
        }, function (ec, es) {
            console.log(es);
        });

        function acquireCamera() {
            if (cameraObj) {
                cameraObj.Addon.Camera.capture().then(function (result) {
                    console.log(result);
                    var objectURL = URL.createObjectURL(result);
                    document.getElementById('img').src = objectURL;
                });
            }
        }
    </script>
</body>
</html>
```

The JavaScript camera API requires **HTTPS**. **HTTP** only works with `localhost`: 

```bash
python -m http.server
```

![scan document from camera using JavaScript](https://www.dynamsoft.com/codepool/img/2022/01/scan-document-from-camera.png)

To test the local web project over HTTPS, you can use [ngrok](https://ngrok.com/) to create a secure tunnel:

```bash
ngrok http 8000
```

## Empower Camera Document Scanning with Edge Detection and Image Post-Processing

As we can see the image quality from camera is worse than from scanner. To improve the image quality, Dynamic Web TWAIN provides extra computer vision algorithms to do document edge detection and image post-processing.

The new [scanDocument()](https://www.dynamsoft.com/web-twain/docs/info/api/Addon_Camera.html?ver=latest#scandocument) method enables developers to create a CamScanner-like web document scanning app with a few lines of JavaScript code.

Let's create a `advanced.html` file based on `camera.html`.

We use [createTemplate()](https://www.dynamsoft.com/web-twain/docs/info/api/WebTwain_Viewer.html?ver=latest#createtemplate) method to create a document viewer template and bind it to the `container` element.

```diff
+ template = cameraObj.Viewer.createTemplate("documentScanner");
+ cameraObj.Viewer.bind(document.getElementById('container'), template);
- cameraObj.Viewer.bind(document.getElementById('container'));
```

Considering there are multiple cameras on mobile devices, we get the camera list firstly and then call `scanDocument()` with a selected camera:

```javascript
Dynamsoft.DWT.CreateDWTObjectEx({
    WebTwainId: 'camera',
    UseLocalService: false
}, function (obj) {
    cameraObj = obj;
    template = cameraObj.Viewer.createTemplate("documentScanner");
    cameraObj.Viewer.bind(document.getElementById('container'), template);
    cameraObj.Viewer.width = 720;
    cameraObj.Viewer.height = 720;
    cameraObj.Viewer.show();
    updateCameraList();
}, function (ec, es) {
    console.log(es);
});

async function createCameraScanner(deviceId) {
    await cameraObj.Addon.Camera.closeVideo();
    cameraObj.Addon.Camera.scanDocument({
        scannerViewer: {
            deviceId: deviceId,
            fullScreen: true
        }

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

function updateCameraList() {
    if (!cameraObj) return;
    var source = document.getElementById('CameraSource');
    source.options.length = 0;
    cameraObj.Addon.Camera.getSourceList().then((list) => {
        for (var i = 0; i < list.length; i++) {
            var option = document.createElement('option');
            option.text = list[i].deviceId || list[i].label
            source.options.add(option);
        }
        createCameraScanner(source.options[source.options.length - 1].text);
    });

}
```

Generally, index 0 represents the front-facing camera, and the last index represents the main back-facing camera. The index of the main back-facing camera may vary on different mobile devices.

Here is the UI of the camera viewer, which contains buttons for selecting camera resolution, switching front and rear cameras, document edge detection, auto-capturing documents, and multiple document editing.

![document edge detection](https://www.dynamsoft.com/codepool/img/2022/01/document-edge-detection.jpg)

Once a document is auto-captured, we can enter the editing mode to adjust the document edge.

![document crop](https://www.dynamsoft.com/codepool/img/2022/01/document-crop.jpg)

Afterwards, perspective correction is applied to the document.

![document perspective correction](https://www.dynamsoft.com/codepool/img/2022/01/document-perspective-correction.jpg)

We can also use the filter to improve the image quality.

![improve document image quality](https://www.dynamsoft.com/codepool/img/2022/01/document-filter.jpg)

After closing the camera viewer, you can select a document and save it to the local disk:

```javascript
function downloadDocument() {
    cameraObj.SaveAsJPEG("document", cameraObj.CurrentImageIndexInBuffer);
}
```

![document management](https://www.dynamsoft.com/codepool/img/2022/01/document-management.jpg)

## Source Code
[https://github.com/yushulx/javascript-document-scanning-desktop-mobile-capture](https://github.com/yushulx/javascript-document-scanning-desktop-mobile-capture)