以前看了下face++的接口,作了人脸融合简单demo,顺便瞧了瞧其余的接口,看到一个识别图片文字的接口,忽然灵机一动。javascript
平时本身看到一些有趣的图文,里面的文字就想敲下来放印象笔记里或者朋友圈里装一下文艺。可是关键这里还要手动敲,若是截图的时候,直接就把文字复制到剪贴板就行了。因而就有了这个应用,实现并不复杂。你们跟我一块儿过一遍吧,喜欢的能够star~css
参考electron官网,打造你的第一个electron应用html
$ yarn add electron -D
复制代码
目录结构前端
├─ src
│ └─ main.js #入口文件,主进程
│ └─ index.html # 渲染进程的页面
复制代码
package.json的scripts字段添加如下java
"start": "electron src/main.js"
复制代码
electron进程分为主进程和渲染进程。渲染进程至关于前端的UI渲染,能够类比成chrome的一个tab页,一个tab就是一个进程。渲染进程由主进程管理,主进程至关于chrome的窗口,关闭全部tab页面还在的那个窗口。有些功能模块只能由主进程来调用,渲染进程同理(好比截屏这个就只能在渲染进程)node
咱们的需求是linux
const { app, BrowserWindow, globalShortcut ,Tray,Menu,ipcMain} = require('electron')
const shell = require('electron').shell;
const path=require('path')
let win
let srcPath=path.join(__dirname,"../src")
let clip=true
//建立托盘
function createTray () {
tray = new Tray(`${srcPath}/images/font.png`) // 指定图片的路径,在github里有
const contextMenu = Menu.buildFromTemplate([ //Menu类型有checkbox,radio,normal等
{ label: 'clip', type: 'checkbox',click(){
clip=!clip
},checked:true },
{ label: 'about', click(){
//打开默认浏览器
shell.openExternal('https://github.com/yokiyokiyoki/clip-font-app');
} },
{ label: 'exit',click(){
app.quit()
}}
])
tray.setToolTip('图图识字')
tray.setContextMenu(contextMenu)
//注册快捷键
globalShortcut.register('CmdOrCtrl+Shift+V', captureScreen)
globalShortcut.register('Esc', () => {
if (win) {
win.close()
win = null
}
})
}
function createCaptureWindow() {
// 建立浏览器窗口,只容许建立一个(必须得建立,由于只有渲染进程才能截图)
if(win)return console.info('只能有一个CaptureWindow')
const { screen } = require('electron') //由于ready才能够引入
let { width, height } = screen.getPrimaryDisplay().bounds
win = new BrowserWindow({
fullscreen: process.platform !== 'darwin' || undefined, // win
width,
height,
x: 0,
y: 0,
transparent: true,
frame: false,
skipTaskbar: true,
autoHideMenuBar: true,
movable: false,
resizable: false,
enableLargerThanScreen: true, // mac
hasShadow: false,
webPreferences: {
webSecurity: false //能够加载本地文件,这里不写的话,打包后会报错:不容许你加载本地文件
}
})
win.setAlwaysOnTop(true, 'screen-saver') // mac
win.setVisibleOnAllWorkspaces(true) // mac
win.setFullScreenable(false) // mac
// 而后加载应用的 index.html。
win.loadFile(path.join(__dirname,'../index.html'))
// 打开开发者工具
win.webContents.openDevTools()
// 当 window 被关闭,这个事件会被触发。
win.on('closed', () => {
win = null
})
}
app.on('ready', createTray)
// 当所有窗口关闭时退出。
app.on('window-all-closed', () => {
// 在 macOS 上,除非用户用 Cmd + Q 肯定地退出,
// 不然绝大部分应用及其菜单栏会保持激活。
if (process.platform !== 'darwin') {
app.quit()
}
})
app.on('activate', () => {
if (win === null) {
createCaptureWindow()
}
})
function captureScreen(){
if(clip){
createCaptureWindow()
}
}
复制代码
上面咱们经过主进程loadfile打开了index.html。这里咱们能够作一个粗浅的UI,须要有尺寸信息,工具栏等。是基于全屏的html,为何要这么作?你能够思考一下~git
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>截屏</title>
</head>
<style> html, body, div { margin: 0; padding: 0; box-sizing: border-box; } .bg { position: absolute; top: 0; left: 0; width: 100%; height: 100%; } .mask { position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0, 0, 0, 0.6); } .rect { position: absolute; display: node; z-index: 1; } .size-info { position: absolute; color: #ffffff; font-size: 12px; background: rgba(40, 40, 40, 0.8); padding: 5px 10px; border-radius: 2px; font-family: Arial Consolas sans-serif; display: none; z-index: 2; } .toolbar { position: absolute; color: #343434; font-size: 12px; background: #f5f5f5; padding: 5px 10px; border-radius: 4px; font-family: Arial Consolas sans-serif; display: none; box-shadow: 0 0 20px rgba(0, 0, 0, 0.4); z-index: 2; align-items: center; } .toolbar>.iconfont{ display: inline-block; cursor: pointer; } </style>
<body>
<!--背景为灰色的遮罩层-->
<div class="bg"></div>
<div id="mask" class="mask"></div>
<canvas class="rect"></canvas>
<!--尺寸信息-->
<div class="size-info">200*200</div>
<!--toolbar-->
<div class="toolbar">
<div class="iconfont icon-close" >关闭</div>
<div class="iconfont icon-check" >确认</div>
<div class="iconfont icon-literacy" >识别</div>
</div>
<script src="./src/js/capture.js"></script> <!--如今还没写-->
</body>
</html>
复制代码
至此咱们已经能够经过npm start
进行开发,经过快捷键CmdOrCtrl+Shift+V
看到这个页面了,而且托盘也已经如今左上角。若是报错,请审视上述之流程。github
咱们把逻辑写在
capture.js
里面web
electron 提供了截取屏幕的 API(desktopCapturer),能够轻松的获取每一个屏幕(存在外接显示器的状况)和每一个窗口的图像信息。能够先去了解一下~
原理(其实很简单,就是两个canvas):
1.经过electron提供截取全屏生成的dataURL,用drawImage存在一个特殊的canvas(姑且称之为全屏canvas)里面(dataURL和cavas的相爱相杀),再把这个dataURL赋给背景,让空白背景图,变成刚刚全屏的样子(假象),再加上半透明的遮罩。
2.经过另一个canvas(选区canvas)来制做选区,鼠标位置来肯定——getImageData(x,y,w,h),这个选区在全屏canvas里的imgData,而后把全屏canvas的数据导过来这个选区canvas——putImageData(imgData, x, y)
const { desktopCapturer, screen } = require('electron')
const { bounds: { width, height } } = screen.getPrimaryDisplay()
const path=require('path')
const {Draw} = require(`${__dirname}/src/js/draw.js`)
desktopCapturer.getSources({
types: ['screen'],
thumbnailSize: {
width, height
}
}, async(error, sources) => {
if (error) return console.log(error)
let screenImgUrl = sources[0].thumbnail.toDataURL() //获取dataURL
let bg=document.querySelector('.bg')
let rect=document.querySelector('.rect')
let sizeInfo=document.querySelector('.size-info')
let toolbar=document.querySelector('.toolbar')
/** * 绘制类 * ScreenImgUrl是整个屏幕base64格式的快照 * bg是背景dom * width是屏幕宽高 * rect是选区canvas * sizeInfo 尺寸信息容器 * toolbar 工具栏 */
let draw=new Draw(screenImgUrl,bg,width,height,rect,sizeInfo,toolbar)
document.addEventListener('mousedown',draw.startRect.bind(draw))
document.addEventListener('mousemove',draw.drawingRect.bind(draw))
document.addEventListener('mouseup',draw.endRect.bind(draw))
})
复制代码
Draw类写了截图选区是如何实现的,这里实在有些长,能够移步github。主要就是经过鼠标画一个矩形,而后把全屏canvas的数据经过位置定位到具体,而后导入。
//渲染进程发送消息
ipcRenderer.send('clip-page', { type: type, message: msg })
//主进程接收
ipcMain.on('clip-page', (event, {type,msg}) => {
if(type==='close'){
if (win) {
win.close()
win = null
}
}
})
复制代码
咱们在开发模式下试了下,以为应该没有问题了。这时候来打包成各平台上的应用,供用户实际使用~
这里咱们选用electron-builder
,在package.json新建一个脚本命令,同时新增一个build字段(electron-builder自动读取)
"scripts": {
"start": "electron src/main.js",
"build": "electron-builder",
},
"build":{
//名字
"productName": "clip-font-app",
"appId": "Personal.DesktopApp.ClipFont.1.0.0",
"directories": {
//打包目录
"output": "dist"
},
"files": [
//全部文件
"./**/**"
],
//win下的安装向导
"nsis": {
"oneClick": false,
"allowElevation": true,
"allowToChangeInstallationDirectory": true,
"installerIcon": "src/images/icon.ico",
"uninstallerIcon": "src/images/icon.ico",
"installerHeaderIcon": "src/images/icon.ico",
"createDesktopShortcut": true,
"createStartMenuShortcut": true,
"shortcutName": "ClipFont"
},
"dmg": {
"contents": [
{
"x": 410,
"y": 150,
"type": "link",
//是否拖到应用目录
"path": "/Applications"
},
{
"x": 130,
"y": 150,
"type": "file"
}
]
},
"mac": {
"icon": "src/images/icon.icns"
},
"win": {
"icon": "src/images/icon.ico",
"target": [
{
"target": "nsis",
"arch": [
"ia32"
]
}
]
},
"linux": {
"icon": "src/images"
},
//下载源为淘宝镜像,国内某些缘由可能会致使失败
"electronDownload": {
"mirror": "http://npm.taobao.org/mirrors/electron/"
}
}
复制代码
而后咱们npm run build
,因为我使用的是mac,而后打包下来的是dmg~,双击dmg安装了。
咱们来使用快捷键(CmdOrCtrl+Shift+V),点击识别~
固然一个截图工具的工具栏怎么会那么简单呢?