Building a Cross-platform Document Scanning and Management Application with Electron
Electron is a framework for building cross-platform desktop applications with HTML, JavaScript, and CSS. Since Dynamic Web TWAIN is also a cross-platform JavaScript library for document scanning and management, we can combine Electron and Dynamic Web TWAIN to implement a desktop document scanning and management application for Windows, Linux, and macOS.
Prerequisites
Install Electron and Dynamic Web TWAIN
npm install -g electron
npm install dwt
References
Electron Application for Document Scanning and Management
Step 1. Electron Quick Start
Let’s get started with electron-quick-start:
git clone https://github.com/electron/electron-quick-start
cd electron-quick-start
npm install
npm start
Here is the basic structure of an Electron project:
app/
├── package.json
├── main.js
└── index.html
The main.js
file is the entry point of Electron, defined in the package.json
file:
"main": "main.js",
"scripts": {
"start": "electron main.js"
},
The index.html
file is loaded in the main.js
file:
mainWindow.loadURL('file://' + __dirname + '/index.htm');
// or
mainWindow.loadFile('index.html');
Although the default code works fine, if you want to make the window bigger and resizable, you can change the code:
mainWindow = new BrowserWindow({ width: 1024, height: 1024, resizable: true });
Step 2. Include Dynamic Web TWAIN JavaScript Library
To implement document scanning and document management, we just need to put some effort into the HTML5 code in index.html
. There is no difference compared to building a web application.
The JavaScript library files of Dynamic Web TWAIN are located in the node_modules
folder. We can include the library in the HTML file:
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Document Scanner</title>
<script src="node_modules/dwt/dist/dynamsoft.webtwain.min.js"></script>
</head>
To make the SDK work, you must set the product key and specify the path of the resources:
Dynamsoft.DWT.ProductKey = 'LICENSE-KEY';
Dynamsoft.DWT.ResourcesPath = "node_modules/dwt/dist/";
Step 3. Added UI Elements
Create a select
element for selecting connected document scanners, a div
element as the document image container, and three buttons for scanning, loading, and saving images:
<select size="1" id="source"></select>
<div id="dwtcontrolContainer"></div>
<input type="button" value="Scan" onclick="scanImage();" />
<input type="button" value="Load" onclick="loadImage();" />
<div class="row">
<label style="font-size: x-large;">
<input type="radio" value="jpg" name="ImageType" id="imgTypejpeg" />JPEG</label>
<label style="font-size: x-large;">
<input type="radio" value="tif" name="ImageType" id="imgTypetiff" />TIFF</label>
<label style="font-size: x-large;">
<input type="radio" value="pdf" name="ImageType" id="imgTypepdf" checked="checked" />PDF</label>
<input type="button" value="Save" onclick="saveImage();" />
</div>
The radio buttons are used to select the image format for saving. The default format is PDF.
Step 4. Implement document scanning: button events
The following JavaScript code implementation includes the initialization of the Dynamic Web TWAIN object and the corresponding button events:
var dwtObject;
var selectSources = document.getElementById("source");
Dynamsoft.DWT.CreateDWTObjectEx({ "WebTwainId": "container" }, (obj) => {
dwtObject = obj;
dwtObject.Viewer.bind(document.getElementById("dwtcontrolContainer"));
dwtObject.Viewer.width = 640;
dwtObject.Viewer.height = 640;
dwtObject.Viewer.show();
onReady();
}, (errorString) => {
console.log(errorString);
});
function onReady() {
if (dwtObject) {
dwtObject.IfShowUI = false;
dwtObject.GetDevicesAsync(Dynamsoft.DWT.EnumDWT_DeviceType.TWAINSCANNER | Dynamsoft.DWT.EnumDWT_DeviceType.TWAINX64SCANNER | Dynamsoft.DWT.EnumDWT_DeviceType.ESCLSCANNER).then((sources) => {
sourceList = sources;
selectSources.options.length = 0;
for (let i = 0; i < sources.length; i++) {
let option = document.createElement("option");
option.text = sources[i].displayName;
option.value = i.toString();
selectSources.add(option);
}
});
}
}
function scanImage() {
if (!dwtObject)
return;
if (selectSources) {
var pixelTypeInputs = document.getElementsByName("PixelType");
for (var i = 0; i < pixelTypeInputs.length; i++) {
if ((pixelTypeInputs[i]).checked) {
pixelType = (pixelTypeInputs[i]).value;
break;
}
}
dwtObject.SelectDeviceAsync(sourceList[selectSources.selectedIndex]).then(() => {
return dwtObject.OpenSourceAsync()
}).then(() => {
return dwtObject.AcquireImageAsync({
IfDisableSourceAfterAcquire: true
})
}).then(() => {
if (dwtObject) {
dwtObject.CloseSource();
}
}).catch(
(e) => {
console.error(e)
}
)
} else {
alert("No Source Available!");
}
}
function loadImage() {
if (!dwtObject) return;
let onSuccess = function () { };
let onFailure = function (errorCode, errorString) { };
dwtObject.IfShowFileDialog = true;
dwtObject.LoadImageEx("", Dynamsoft.DWT.EnumDWT_ImageType.IT_ALL, onSuccess, onFailure);
}
function saveImage() {
if (dwtObject) {
if ((document.getElementById("imgTypejpeg")).checked == true) {
if (dwtObject.GetImageBitDepth(dwtObject.CurrentImageIndexInBuffer) == 1)
dwtObject.ConvertToGrayScale(dwtObject.CurrentImageIndexInBuffer);
dwtObject.SaveAsJPEG("DynamicWebTWAIN.jpg", dwtObject.CurrentImageIndexInBuffer);
}
else if ((document.getElementById("imgTypetiff")).checked == true)
dwtObject.SaveAllAsMultiPageTIFF("DynamicWebTWAIN.tiff");
else if ((document.getElementById("imgTypepdf")).checked == true)
dwtObject.SaveAllAsPDF("DynamicWebTWAIN.pdf");
}
}
Now save the changes and reload the UI. A simple desktop document scanning application is complete.
Electron Application Packaging and Distribution
To package and distribute the Electron project:
-
Install asar to pack the application into an archive file:
npm install -g asar asar pack app app.asar
-
Download the Electron prebuilt package and place app.asar into the
recourses
folder. - Double-click
electron.exe
to check whether your application runs successfully. - Compress the entire folder into a zip file for distribution.
Source Code
https://github.com/yushulx/web-twain-document-scan-management/tree/main/examples/electron