Electron是一个用于与HTML,JavaScript和CSS一起构建跨平台桌面应用程序的框架。 由于Dynamic Web TWAIN也是一个用于扫描文档的跨平台JavaScript库,因此使用Electron for Windows,Linux和macOS实现桌面文档扫描应用程序非常容易。
安装准备:
• Dynamic Web TWAIN SDK
• Electron:
npm install -g electron
使用electron构建应用程序:
Electron 应用程序的结构
一个Electron应用程序的结构如下:
app/
├── package.json
├── main.js
└── index.html
你知道如何为Node.js模块编写package.json文件吗? 步骤完全相同。 我是这么做的:
{
"name": "docscanner",
"version": "1.0.0",
"description": "Cross-platform document scanning application for Windows, Linux and macOS",
"main": "main.js",
"scripts": {
"start": "electron main.js"
},
"repository": {
"type": "git",
"url": "git+https://github.com/yushulx/electron-document-scan.git"
},
"keywords": [
"Dynamsoft",
"document scan",
"web twain",
"SDK"
],
"author": "yushulx",
"homepage": "http://www.dynamsoft.com/Products/WebTWAIN_Overview.aspx",
"devDependencies": {
"electron-prebuilt": "^1.6.1"
}
}
使用将由Electron加载的JavaScript文件指定主字段。 此外,您需要创建index.html以使用HTML和CSS呈现UI。 阅读Electron API参考时,您可能会看到主进程和渲染进程。 它们是什么以及如何使用相关API?
电子主要进程
主进程是运行main.js的入口点。 它创建渲染进程并管理本机元素。 完整的Node API是内置的。
电子渲染进程
渲染进程是运行index.html的浏览器窗口。 Electron使开发人员能够在网页中使用Node.js API。
文档扫描应用程序
根据Electron文档,我们只需要将所有工作放在index.html中并使用main.js加载它。
index.html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Document Scanner</title>
<script type="text/javascript" src="http://www.dynamsoft.com/library/dwt/dynamsoft.webtwain.min.js"></script>
<style>
h1 {
font-size: 2em;
font-weight: bold;
color: #777777;
text-align: center
}
table {
margin: auto;
}
</style>
</head>
<body>
<h1>
Document Scanner
</h1>
We are using node
<script>
document.write(process.versions.node)
</script>, Chrome
<script>
document.write(process.versions.chrome)
</script>, and Electron
<script>
document.write(process.versions.electron)
</script>.
<table>
<tr>
<td>
<!-- dwtcontrolContainer is the default div id for Dynamic Web TWAIN control.
If you need to rename the id, you should also change the id in dynamsoft.webtwain.config.js accordingly. -->
<div id="dwtcontrolContainer"></div>
</td>
</tr>
<tr>
<td>
<input type="button" value="Scan" "scanImage();" />
<input type="button" value="Load" "loadImage();" />
<input type="button" value="Save" "saveImage();" />
</td>
</tr>
</table>
<script type="text/javascript">
var console = window['console'] ? window['console'] : {
'log': function() {}
};
Dynamsoft.WebTwainEnv.RegisterEvent('OnWebTwainReady', Dynamsoft_OnReady); // Register OnWebTwainReady event. This event fires as soon as Dynamic Web TWAIN is initialized and ready to be used
var DWObject;
function Dynamsoft_OnReady() {
DWObject = Dynamsoft.WebTwainEnv.GetWebTwain('dwtcontrolContainer'); // Get the Dynamic Web TWAIN object that is embeded in the div with id 'dwtcontrolContainer'
if (DWObject) {
DWObject.RegisterEvent('OnPostAllTransfers', SaveWithFileDialog);
}
}
function scanImage() {
if (DWObject) {
var bSelected = DWObject.SelectSource();
if (bSelected) {
var OnAcquireImageSuccess, OnAcquireImageFailure;
OnAcquireImageSuccess = OnAcquireImageFailure = function() {
DWObject.CloseSource();
};
DWObject.OpenSource();
DWObject.IfDisableSourceAfterAcquire = true; // Scanner source will be disabled/closed automatically after the scan.
DWObject.AcquireImage(OnAcquireImageSuccess, OnAcquireImageFailure);
}
}
}
//Callback functions for async APIs
function OnSuccess() {
console.log('successful');
}
function OnFailure(errorCode, errorString) {
alert(errorString);
}
function loadImage() {
if (DWObject) {
DWObject.IfShowFileDialog = true; // Open the system's file dialog to load image
DWObject.LoadImageEx("", EnumDWT_ImageType.IT_ALL, OnSuccess, OnFailure); // Load images in all supported formats (.bmp, .jpg, .tif, .png, .pdf). OnSuccess or OnFailure will be called after the operation
}
}
function saveImage() {
if (DWObject) {
if (DWObject.HowManyImagesInBuffer > 0) {
DWObject.IfShowFileDialog = true;
if (DWObject.GetImageBitDepth(DWObject.CurrentImageIndexInBuffer) == 1) {
DWObject.ConvertToGrayScale(DWObject.CurrentImageIndexInBuffer);
}
DWObject.SaveAsJPEG("DynamicWebTWAIN.jpg", DWObject.CurrentImageIndexInBuffer);
}
}
}
</script>
</body>
</html>
main.js
'use strict';
const { app, BrowserWindow } = require('electron');
// Keep a global reference of the window object, if you don't, the window will
// be closed automatically when the JavaScript object is garbage collected.
let mainWindow;
function createWindow() {
// Create the browser window.
mainWindow = new BrowserWindow({ width: 480, height: 640, resizable: false });
// and load the index.html of the app.
mainWindow.loadURL('file://' + __dirname + '/index.htm');
// Open the DevTools.
// mainWindow.webContents.openDevTools();
// Emitted when the window is closed.
mainWindow.on('closed', function() {
// Dereference the window object, usually you would store windows
// in an array if your app supports multi windows, this is the time
// when you should delete the corresponding element.
mainWindow = null;
});
}
// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
app.on('ready', createWindow);
// Quit when all windows are closed.
app.on('window-all-closed', function() {
// On OS X it is common for applications and their menu bar
// to stay active until the user quits explicitly with Cmd + Q
if (process.platform !== 'darwin') {
app.quit();
}
});
app.on('activate', function() {
// On OS X it's common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open.
if (mainWindow === null) {
createWindow();
}
});
运行应用程序
应用分发
要分发应用程序,有两个步骤:
第一步,用asar打包应用程序。
npm install -g asar
asar pack your-app app.asar
第二步,下载Electron prebuilt package 并将app.asar放入资源文件夹。
默认情况下有两个asar文件,可以将它们留在那里。 您可以双击electron.exe在Windows上运行该应用程序。