How to Scan Document from Scanner and Camera Using JavaScript

Xiao Ling - Jan 26 '22 - - Dev Community

As the dominant JavaScript document scanning SDK, Dynamic Web TWAIN 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
  • license applciation

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

Dynamsoft.DWT.ProductKey = 'LICENSE KEY';
Enter fullscreen mode Exit fullscreen mode

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:

<!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>

Enter fullscreen mode Exit fullscreen mode

scan document from scanner using JavaScript

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() 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.

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

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

python -m http.server
Enter fullscreen mode Exit fullscreen mode

scan document from camera using JavaScript

To test the local web project over HTTPS, you can use ngrok to create a secure tunnel:

ngrok http 8000
Enter fullscreen mode Exit fullscreen mode

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() 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() method to create a document viewer template and bind it to the container element.

+ template = cameraObj.Viewer.createTemplate("documentScanner");
+ cameraObj.Viewer.bind(document.getElementById('container'), template);
- cameraObj.Viewer.bind(document.getElementById('container'));
Enter fullscreen mode Exit fullscreen mode

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

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

}
Enter fullscreen mode Exit fullscreen mode

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

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

document crop

Afterwards, perspective correction is applied to the document.

document perspective correction

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

improve document image quality

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

function downloadDocument() {
    cameraObj.SaveAsJPEG("document", cameraObj.CurrentImageIndexInBuffer);
}
Enter fullscreen mode Exit fullscreen mode

document management

Source Code

https://github.com/yushulx/javascript-document-scanning-desktop-mobile-capture

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