在Electron中实现右键保存图片到本地Electron是开发跨平台pc客户端的利器,最近在使用它时遇到一个需要右键保
Electron
是开发跨平台pc客户端的利器,最近在使用它时遇到一个需要右键保存页面中图片的功能,我们知道Chrome
浏览器本身在图片上右键保存图片即可,但Electron
虽使用了Chromium
内核但却无法直接使用系统右键,需要自定义右键菜单,然后添加图片保存功能。以下是我的使用方法。
Electron
是双进程模式,即用于页面渲染的渲染器进程,和作为程序入口及窗口管理的主进程,想必大家都晓得。
保存图片的核心原理即: 在渲染进程中监听右键context
事件,获取到图片的src
,然后将src
发送到主进程,主进程监听到发送事件后,获取src
地址,然后调用axios
等http请求图片下载图片数据,复制到粘贴板并保存到计算机中。
听起来很简单对吧,事实上也确实简单。就是一个渲染进程和主进程进行一次通信,就ok。
渲染进程监听context事件获取图片地址
和普通网页中监听一样,使用window.addEventListen('context'
,唯一需要注意的是获取electron
的方式,可以通过preload
脚本将electron
注入到网页,也可以直接在创建主窗口时 nodeIntegration
设为true
,contextIsolation
设为false
从而在网页中直接使用,当然后者并不安全,不建议使用。
window.addEventListener('contextmenu',function(e){
let Renderer = (window.require && window.require('electron')) || window.electron || {};
const ipc = Renderer.ipcRenderer || undefined;
if(ipc){
ipc.invoke('saveimg', {src:e.srcElement && e.srcElement.currentSrc?e.srcElement.currentSrc:''}).then(r => {
// r为返回的数据
console.log(r);
})
e.preventDefault();
}
});
如上代码,当在图片上右键时,可通过e.srtElement.currentSrc
取得图片地址,然后使用 Render.ipcRenderer.invoke
发送给主进程,当然如果不需要接收返回数据,使用 send
也是可以
主进程接收数据并保存图片
主进程通过 ipcMain.handle
监听渲染进程发来的数据,第二个参数args
即是渲染进程发送的数据,通过args.src
可获取到图片地址,然后调用 saveImage
函数保存图片到本地。
为方便使用,可在接到该事件时,添加一个右键菜单,只有当点击右键菜单中的“保存图片到本地”才真正执行保存动作。
const { app, BrowserWindow, ipcMain,nativeImage, dialog,Menu, MenuItem } = require('electron')
ipcMain.handle(event,args){
const template = [
{
label: '保存图片到本地',
accelerator: 'CmdOrCtrl+I',
enabled: args.src?true:false,
click: () => {
if(args.src){
saveImage(mainWindow,args.src)
}
}
}
]
const menu=Menu.buildFromTemplate(template);
menu.popup()
}
获取图片数据并保存
这一步就比较简单了,使用axios
请求图片数据,然后调用fs.writeFile
写入本地文件即可
const axios =require('axios');
const fs =require('fs');
const path = require('path');
async function saveImage(mainWindow,imageUrl) {
try {
const { filePath } = await dialog.showSaveDialog(mainWindow, {
title: '保存图片',
defaultPath: path.join(app.getPath('downloads'), (new Date()).getTime()+'image.jpg'), // 默认保存路径
});
if (!filePath) {
throw new Error('用户取消了保存操作');
}
// 使用 axios 获取图片数据
const response = await axios({
url: imageUrl,
method: 'GET',
responseType: 'arraybuffer',
});
if (!response || response.status !== 200) {
throw new Error(`图片下载失败,状态码:${response.status}`);
}
// 将响应数据写入文件
const buffer = Buffer.from(response.data);
fs.writeFile(filePath, buffer, (err) => {
if (err) {
throw err;
}
console.log('图片保存成功');
});
} catch (error) {
console.error('保存图片时发生错误:', error.message);
}
}
最终效果如右图,额外加了复制和粘贴等功能
转载自:https://juejin.cn/post/7395866692771282984