前言
最近在使用electron制作桌面客户端, 其中有个需求是截图并上传, 截图只截应用内部分区域, 上传接口只接受文件类型。 由于此前并没有这方面经验, 在此记录一下实现方式。
实现
- 使用electron截图
首先使用electron本身提供的能力进行截图,此处使用渲染进程desktopCapturer方法抓取应用当前状态屏幕显示内容,具体实现为:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| const { desktopCapturer } = require('electron')
desktopCapturer.getSources({types: ['window'], (error, sources) => { if (error) throw error let imgSrc = null for(let i = 0; i < sources.length; i++) { if(sources[i].name === 'Electron') { imgSrc = sources[i].thumbnail.toDataURL() break } } if (imgSrc) { const canvas$ = document.createElement('canvas') const img$ = document.createElement('img') const ctx = canvas$.getContext('2d') canvas$.setAttribute('width', 1220) canvas$.setAttribute('height', 634) img$.src = imgSrc img$.onload = () => { canvas$.drawImage(img$) } } }})
|
- 使用canvas裁剪图片
之前想到的裁剪方法都是使用drawImage方法进行裁剪, 但是一直不能达到想要的后果, 后来查到canvas还有一对getImageData 和 putImageData的方法,更加适合来做图片裁剪, 故此处使用此方法进行裁剪
1 2 3 4 5 6 7 8 9
| const imgData = canvas$.getImageData(0, 44, 960, 540) canvas$.clearRect(0, 0, 1220, 634) canvas$.setAttribute('width', 960) canvas$.setAttribute('height', 540) canvas$.putImageData(imgData, 0, 0)
const imgUrl = canvas$.toDataURL('image/png')
uploadHandler(imgUrl)
|
- 将base64转化为file文件上传至服务器
base64利用h5新特性Blob FormData等属性进行文件上传
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| import axios from 'axios'
function base64UrlToBlob(imgUrl) { const bytes = window.atob(imgUrl.split(',')[1]) const arrayBuffer = new ArrayBuffer(bytes.length) const unitArray = new Uint8Array(arrayBuffer) for (let i = 0; i < bytes.length; i++) { unitArray[i] = bytes[i].charCodeAt(i) } return new Blob([arrayBuffer], { type: 'image/png' }) }
const uploadHandler = async (imgUrl) => { const formData = new FormData() const file = base64UrlToBlob(imgUrl) formData.append('file', file, 'image.png') try { const { data } = await axios.post('/upload', formData, { headers: { 'Content-Type': 'multipart/form-data' } }) console.log(data) } catch (e) { console.error(e) } }
|
写到最后
此功能虽然为小功能, 但是在客户端开发中还是比较常见的一个需求, 对自己的技术盲点也是一次查漏补缺。