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
Open <Dynamic Web TWAIN version>/Resources/dynamsoft.webtwain.config.js
to configure the license key:
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:
<!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>
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>
The JavaScript camera API requires HTTPS. HTTP only works with localhost
:
python -m http.server
To test the local web project over HTTPS, you can use ngrok to create a secure tunnel:
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() 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'));
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);
});
}
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.
Once a document is auto-captured, we can enter the editing mode to adjust the document edge.
Afterwards, perspective correction is applied to the document.
We can also use the filter to improve the 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);
}
Source Code
https://github.com/yushulx/javascript-document-scanning-desktop-mobile-capture
Top comments (2)
There's an open source JS library that does this for free now: jscanify
Excellent! But a pure JS library cannot acquire images from a document scanner (MFP).