我的GitHub
0%

无星的electron之旅(十三)—— 复制图片到剪切板

一、背景

需求变更。。。仅此而已

二、如何实现

通过上一篇,我们已经知道了如何获取dom节点

接下来要做的,则是将图片复制到剪切板

我们从文档可以看到

clipboard.writeImage
clipboard支持读写图片到剪切板,但必须是nativeimage

nativeimage.createFromDataURL
nativeimage可以支持从base64创建

那么配合上一篇,我们拿到base64以后,通过这个操作,就可以复制图片到剪切板了

代码如下

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
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
// html 入口文件
///////////
window.addEventListener("contextmenu", (e) => {
e.preventDefault();
const domName = e.target.localName;
if (domName === "img") {
if (e.target.id === "") {
const date = new Date().valueOf();
e.target.id = date;
}
window.rightMenu.show(e.target.id, e.target.currentSrc);
}
});
///////////

// background.js
///////////
const rightMenu = initRightMenu();
function initRightMenu() {
const rightTemplate = [
{
label: "复制图片",
click: () => {
console.log("复制图片");
mainWindow.webContents.send("copyImage", {
domId: clickDomId,
imageUrl:clickImageUrl
});
},
}
];
const menu = Menu.buildFromTemplate(rightTemplate);
return menu;
}

let clickDomId = null
let clickImageUrl = null
ipcMain.handle("show-context-menu", (event, args) => {
const { domId,imageUrl } = args;
clickDomId = domId;
clickImageUrl = imageUrl;
rightMenu.popup({
window: mainWindow.webContents,
callback: () => (clickDomId = null),
});
});
///////////

// preload.js
///////////
// 注入时使用,可不在html入口处添加监听
// document.addEventListener("DOMContentLoaded", () => {
// window.addEventListener("contextmenu", (e) => {
// e.preventDefault();
// const domName = e.target.localName;
// if (domName === "img") {
// if (e.target.id === "") {
// const date = new Date().valueOf();
// e.target.id = date;
// }
// ipcRenderer.invoke("show-context-menu", {
// domId: e.target.id,
// imageUrl: e.target.currentSrc
// });
// }
// });
// });
contextBridge.exposeInMainWorld("rightMenu", {
show: (domId,currentSrc) =>
ipcRenderer.invoke("show-context-menu", {
domId,currentSrc
}),
});

ipcRenderer.on("copyImage", (event, args) => {
const { domId,imageUrl } = args;
imageToBase64(imageUrl)
});

const imageToBase64 = (url) => {
let image = new Image();
image.crossOrigin = "";
image.src = url;
image.onload = function () {
const base64 = getBase64Image(image);
const img = nativeImage.createFromDataURL(base64)
clipboard.writeImage(img)
};
};

const getBase64Image = (img) => {
const canvas = document.createElement("canvas");
canvas.width = img.width;
canvas.height = img.height;
const ctx = canvas.getContext("2d");
ctx.drawImage(img, 0, 0, img.width, img.height);
let ext = img.src.substring(img.src.lastIndexOf(".") + 1).toLowerCase();
if (ext === "jpg") {
ext = "jpeg"; //这个地方是由于如果是jpg, 他会识别成image/png
}
const dataURL = canvas.toDataURL("image/" + ext);
return dataURL;
};
///////////



效果

1