Electron是一个用于与HTML,JavaScript和CSS一起构建跨平台桌面应用程序的框架。 由于Dynamic Web TWAIN也是一个用于扫描文档的跨平台JavaScript库,因此使用Electron for Windows,Linux和macOS实现桌面文档扫描应用程序非常容易。
• Dynamic Web TWAIN SDK
• Electron:
npm install -g 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上运行该应用程序。