背景

之前看了下face++的接口,做了人脸融合简单demo,顺便瞧了瞧其他的接口,看到一个识别图片文字的接口,突然灵机一动。

平时自己看到一些有趣的图文,里面的文字就想敲下来放印象笔记里或者朋友圈里装一下文艺。但是关键这里还要手动敲,如果截图的时候,直接就把文字复制到剪贴板就好了。于是就有了这个应用,实现并不复杂。大家跟我一起过一遍吧,喜欢的可以star~

开始

初始化一个electron应用

参考electron官网,打造你的第一个electron应用

$ yarn add electron -D
复制代码

目录结构

├─ src
│  └─ main.js    #入口文件,主进程
│  └─ index.html # 渲染进程的页面
复制代码

package.json的scripts字段添加以下

"start": "electron src/main.js"
复制代码

入口文件

electron进程分为主进程和渲染进程。渲染进程相当于前端的UI渲染,可以类比成chrome的一个tab页,一个tab就是一个进程。渲染进程由主进程管理,主进程相当于chrome的窗口,关闭所有tab页面还在的那个窗口。有些功能模块只能由主进程来调用,渲染进程同理(比如截屏这个就只能在渲染进程)

我们的需求是

  • 只需要一个托盘叫做tray(mac右上角,win右下角),不需要打开具体的窗口界面
  • CmdOrCtrl+Shift+V为截图快捷键
const { app, BrowserWindow,  globalShortcut ,Tray,Menu,ipcMain} = require('electron')const shell = require('electron').shell;const path=require('path')let winlet 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().boundswin = new BrowserWindow({ fullscreen: process.platform !== 'darwin' || undefined, // winwidth,height,x: 0,y: 0,transparent: true,frame: false,skipTaskbar: true,autoHideMenuBar: true,movable: false,resizable: false,enableLargerThanScreen: true, // machasShadow: false,webPreferences: {webSecurity: false //可以加载本地文件,这里不写的话,打包后会报错:不允许你加载本地文件}})win.setAlwaysOnTop(true, 'screen-saver') // macwin.setVisibleOnAllWorkspaces(true) // macwin.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()}
}
复制代码

编写index.html

上面我们通过主进程loadfile打开了index.html。这里我们可以做一个粗浅的UI,需要有尺寸信息,工具栏等。是基于全屏的html,为什么要这么做?你可以思考一下~

<!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看到这个页面了,并且托盘也已经现在左上角。如果报错,请审视上述之流程。

截屏功能实现

我们把逻辑写在capture.js里面

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() //获取dataURLlet 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的数据通过位置定位到具体,然后导入。

如果我们点击工具栏中的关闭,其实是需要销毁整个窗口的。这里涉及到了渲染进程和主进程间通信的问题,需要IPC模块——IPCMain和ipcRenderer ~

//渲染进程发送消息
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),点击识别~

然后复制到剪贴板试试,效果还是可以的~

后续

当然一个截图工具的工具栏怎么会那么简单呢?

  • 工具栏完善,会包括下载等功能
  • 支持多窗口截屏
  • 拖拽节点

转载于:https://juejin.im/post/5ca0aba1e51d4533183660fd

如何实现基于Electron的截图识字App(一)相关推荐

  1. 基于 Electron 实现 uTools 的超级面板

    点击上方 前端瓶子君,关注公众号 回复算法,加入前端编程面试算法每日一题群 前言 为了进一步提高开发工作效率,最近我们基于 electron 开发了一款媲美 uTools 的开源工具箱 rubick[ ...

  2. 基于 Electron + ES6 实现的桌面计算器应用

    清理GitHub老旧仓库时发现了一个有趣的app:用electron写的计算器.虽然现在已经无法运行了(因为package.json中依赖的版本都写的是"latest"),但还是发 ...

  3. 【项目精选】基于Electron + Vue的桌面音乐助手的设计与实现

    1. 使用技术 JavaScript框架 Electron和Vue框架 如果想开发一个桌面 GUI 应用软件,希望其能同时在 Windows.Linux 和 Mac 平台上运行,可选的技术框架并不多, ...

  4. 基于Paddle的截图OCR文字识别的实现

    基于Paddle的截图&OCR文字识别的实现 一款截图识别文字的OCR工具主要涉及2个环境: 截图 OCR识别 前要 OCR的应用场景 根据OCR的应用场景而言,我们可以大致分成识别特定场景下 ...

  5. 使用Squirrel创建基于Electron开发的Windows 应用安装包

    我们把自己开发的Electron应用发布之前,需要把app打包成简单的安装包,这样app更容易被获取,以此来发布我们的应用.我们可以参考Wix或其他的安装程序,但是对于Electron应用更好的打包程 ...

  6. 基于Java实现的新闻App

    基于Java实现的新闻App 功能实现 功能 子功能 百分比(%) 是否:实现 基础:功能 系统支持 要保证程序在安卓机上正常运行,测试过程中程序不崩溃. 5 是 基础:功能 页面布局 布局合理,点击 ...

  7. Sugar-Electron 基于Electron的轻量级开发框架

    Sugar-Electron 基于Electron的轻量级开发框架 前言 关于应用稳定性 关于开发效率低 特性 设计原则 安装 脚手架 核心功能 基础进程类--BaseWindow 举个例子 服务进程 ...

  8. Beaker:一个基于Electron的点对点Web浏览器

    Beaker是一个基于Electron.Chromium和Node.js的实验性.点对点Web浏览器.Beaker包含新的基于Dat的API,用于构建无主机应用程序,同时又保持与传统Web的兼容性. ...

  9. Today:基于 Electron 和 Vue.js 的 GTD 应用

    这是我的一个 side project.今天发布了第一个预览版本 v0.0.2,欢迎访问 GitHub 上面的 Repo 获取试用下载(目前仅为 Mac 用户提供 build),并提供你们的宝贵意见和 ...

  10. android+录像中截图软件下载,录屏截图大师app

    录屏截图大师app是一款专业录屏软件,不少用户可能会有使用手机录屏的需求,尤其是在手机内置没有录屏功能的时候,这款软件就非常值得大家考虑,支持自定义设置录屏的大小和画质,还没有水印,还支持后期的简单编 ...

最新文章

  1. Rera1N环境Linux,降级工具ReRa1n发布,降级真的来了?
  2. 最好的船_“船”说中的美丽陶瓷
  3. HDU 2063 过山车【二分图最大匹配】
  4. 某计算机系统20位地址线 8位数据线,同济大学2009-2010(1)微机原理期终考试试题(B卷)...
  5. c++11特性move和forward区别
  6. oracle查zw001密码,【Oracle错误集锦】:ORA-00119amp;ORA-00132-一团网
  7. 源代码 oa办公系统jsp_【程序源代码】经典的办公系统开发框架
  8. PHP查看内存使用量
  9. 与秦岭有关的诗词146首
  10. Fruits 360(水果数据集)
  11. Unity中下载图片、音频和视频
  12. 公众号、小程序、短信消息推送的区别
  13. Android-模块化-面向接口编程深度解析,值得收藏
  14. ROS运行时出现Couldn‘t find executable错误
  15. 【并发编程】map 基本用法和常见错误以及如何实现线程安全的map类型
  16. week8—多线程下载多个网页文件
  17. BZOJ3238[Ahoi2013]差异
  18. GSM系统信令接续流程
  19. mysql编码修改utf8_修改数据库mysql字符编码为UTF8
  20. php后期维护麻烦,太吾绘卷维护费太高怎么办 后期建筑太耗资源解决方法介绍...

热门文章

  1. python曲线镜像_在Python中以对角方式镜像图像
  2. Python 之 解析xml
  3. Win10系统安装SQL2008 R2详细步骤+图片+常见问题及解决方法
  4. python人狗大战游戏_6.5 人狗大战.py
  5. smartPrinter 安装时1722错误
  6. 如何查看、检测Windows XP-Windows10系统是否为正版
  7. java 保存图片_java后台接受到图片后保存方法
  8. 开根号的笔算算法图解_用笔算开根号
  9. 网络安全技术复习资料
  10. shell脚本——系统工具箱(SystemToolbox)