背景

前段时间一直在做一款 electron 的 IM 聊天应用,其中需要实现 “截屏并发送截屏文件” 的功能。因此,翻阅了资料并且进行了对比研究,发现有两种可以实现的方案,下面来给大家介绍一下。


一、electron 自带的API:desktopCapture

这种方法是最简单易用的,但由于 electron 是自带的,对其要求不能太高,只能单纯地把整个屏幕截图返回,而且可能会有一些卡顿。

范例代码如下:

// In the renderer process.
const { desktopCapturer } = require('electron')

desktopCapturer.getSources({ types: ['window', 'screen'] }).then(async sources => {
for (const source of sources) {
if (source.name === 'Electron') {
try {
const stream = await navigator.mediaDevices.getUserMedia({
audio: false,
video: {
mandatory: {
chromeMediaSource: 'desktop',
chromeMediaSourceId: source.id,
minWidth: 1280,
maxWidth: 1280,
minHeight: 720,
maxHeight: 720
}
}
})
handleStream(stream)
} catch (e) {
handleError(e)
}
return
}
}
})

有兴趣的小伙伴,可以查看一下API文档​。


二、集成截图软件:exe

在百度找了两款能使用的截图应用程序(链接分享在文章尾部),利用 node 的child_process 的 execFile 方法启动应用,并在应用关闭的时候去获取粘贴板上的图片。

具体代码如下:

1、启动应用,并监听应用关闭

let imageObj: any;
const child = execFile(exeurl, ['--unhandled-rejections=strict'], (error: any, stdout: any, stderr: any) => {
console.log('ERROR', error, stdout, stderr);
if (error) {
console.log('系统错误或取消截图');
return
}
let imageObj: any = clipboard.readImage();
if(!imageObj.isEmpty()) {
imageObj = imageObj.toDataURL();
if(imageObj !== oldShotImg) {
oldShotImg = imageObj;
}
}
});

这里会有一个问题:启动应用之后,用户可以取消截图,就是我们在应用关闭之后,可能会出现 “取不到截图” 或者 “取到的截图跟上一次截图一样” 的情况。

为了解决这个问题,就需要先判断粘贴板是否有图片(这个很好处理,可参考 electron 的API)。

另外,可以先存储上一次的截图,然后跟最新的做对比,不一样的才是现有的。


总结

总的来说,两种方式都是可以实现截图的,但实现效果是不一样的。

第一种是简单简约型,基本就是生成截图。

第二种是根据所采用应用程序的功能丰富程度而定,类似我找到的两款应用,基本上涵盖了像QQ截图的所有功能,例如:截图之后的标点、圈圈、注释、保存等功能,相对丰富,使用上也是比较简单的。

最终选择哪种方式,我们还是要看具体项目的需求而定,个人会比较倾向第二种方式。


最后,分享两款应用的链接:

1、https://www.qqxiazai.com/down/44428.html
2、https://dl.pconline.com.cn/download/2272902.html


给大家分享更多 electron 实战中的点滴,如果大家对此感兴趣,欢迎各位关注、留言,大家的支持就是我的动力!