mirror of
https://github.com/comfyanonymous/ComfyUI.git
synced 2025-04-19 10:53:29 +00:00
Adds copy image option if browser feature available (#2544)
* Adds copy image option if browser feature available * refactor
This commit is contained in:
parent
432ba1c179
commit
270daa02a8
@ -269,6 +269,71 @@ export class ComfyApp {
|
|||||||
* @param {*} node The node to add the menu handler
|
* @param {*} node The node to add the menu handler
|
||||||
*/
|
*/
|
||||||
#addNodeContextMenuHandler(node) {
|
#addNodeContextMenuHandler(node) {
|
||||||
|
function getCopyImageOption(img) {
|
||||||
|
if (typeof window.ClipboardItem === "undefined") return [];
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
content: "Copy Image",
|
||||||
|
callback: async () => {
|
||||||
|
const url = new URL(img.src);
|
||||||
|
url.searchParams.delete("preview");
|
||||||
|
|
||||||
|
const writeImage = async (blob) => {
|
||||||
|
await navigator.clipboard.write([
|
||||||
|
new ClipboardItem({
|
||||||
|
[blob.type]: blob,
|
||||||
|
}),
|
||||||
|
]);
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
const data = await fetch(url);
|
||||||
|
const blob = await data.blob();
|
||||||
|
try {
|
||||||
|
await writeImage(blob);
|
||||||
|
} catch (error) {
|
||||||
|
// Chrome seems to only support PNG on write, convert and try again
|
||||||
|
if (blob.type !== "image/png") {
|
||||||
|
const canvas = $el("canvas", {
|
||||||
|
width: img.naturalWidth,
|
||||||
|
height: img.naturalHeight,
|
||||||
|
});
|
||||||
|
const ctx = canvas.getContext("2d");
|
||||||
|
let image;
|
||||||
|
if (typeof window.createImageBitmap === "undefined") {
|
||||||
|
image = new Image();
|
||||||
|
const p = new Promise((resolve, reject) => {
|
||||||
|
image.onload = resolve;
|
||||||
|
image.onerror = reject;
|
||||||
|
}).finally(() => {
|
||||||
|
URL.revokeObjectURL(image.src);
|
||||||
|
});
|
||||||
|
image.src = URL.createObjectURL(blob);
|
||||||
|
await p;
|
||||||
|
} else {
|
||||||
|
image = await createImageBitmap(blob);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
ctx.drawImage(image, 0, 0);
|
||||||
|
canvas.toBlob(writeImage, "image/png");
|
||||||
|
} finally {
|
||||||
|
if (typeof image.close === "function") {
|
||||||
|
image.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
alert("Error copying image: " + (error.message ?? error));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
node.prototype.getExtraMenuOptions = function (_, options) {
|
node.prototype.getExtraMenuOptions = function (_, options) {
|
||||||
if (this.imgs) {
|
if (this.imgs) {
|
||||||
// If this node has images then we add an open in new tab item
|
// If this node has images then we add an open in new tab item
|
||||||
@ -286,16 +351,17 @@ export class ComfyApp {
|
|||||||
content: "Open Image",
|
content: "Open Image",
|
||||||
callback: () => {
|
callback: () => {
|
||||||
let url = new URL(img.src);
|
let url = new URL(img.src);
|
||||||
url.searchParams.delete('preview');
|
url.searchParams.delete("preview");
|
||||||
window.open(url, "_blank")
|
window.open(url, "_blank");
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
...getCopyImageOption(img),
|
||||||
{
|
{
|
||||||
content: "Save Image",
|
content: "Save Image",
|
||||||
callback: () => {
|
callback: () => {
|
||||||
const a = document.createElement("a");
|
const a = document.createElement("a");
|
||||||
let url = new URL(img.src);
|
let url = new URL(img.src);
|
||||||
url.searchParams.delete('preview');
|
url.searchParams.delete("preview");
|
||||||
a.href = url;
|
a.href = url;
|
||||||
a.setAttribute("download", new URLSearchParams(url.search).get("filename"));
|
a.setAttribute("download", new URLSearchParams(url.search).get("filename"));
|
||||||
document.body.append(a);
|
document.body.append(a);
|
||||||
@ -308,33 +374,41 @@ export class ComfyApp {
|
|||||||
}
|
}
|
||||||
|
|
||||||
options.push({
|
options.push({
|
||||||
content: "Bypass",
|
content: "Bypass",
|
||||||
callback: (obj) => { if (this.mode === 4) this.mode = 0; else this.mode = 4; this.graph.change(); }
|
callback: (obj) => {
|
||||||
});
|
if (this.mode === 4) this.mode = 0;
|
||||||
|
else this.mode = 4;
|
||||||
|
this.graph.change();
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
// prevent conflict of clipspace content
|
// prevent conflict of clipspace content
|
||||||
if(!ComfyApp.clipspace_return_node) {
|
if (!ComfyApp.clipspace_return_node) {
|
||||||
options.push({
|
options.push({
|
||||||
content: "Copy (Clipspace)",
|
content: "Copy (Clipspace)",
|
||||||
callback: (obj) => { ComfyApp.copyToClipspace(this); }
|
callback: (obj) => {
|
||||||
});
|
ComfyApp.copyToClipspace(this);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
if(ComfyApp.clipspace != null) {
|
if (ComfyApp.clipspace != null) {
|
||||||
options.push({
|
options.push({
|
||||||
content: "Paste (Clipspace)",
|
content: "Paste (Clipspace)",
|
||||||
callback: () => { ComfyApp.pasteFromClipspace(this); }
|
callback: () => {
|
||||||
});
|
ComfyApp.pasteFromClipspace(this);
|
||||||
|
},
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if(ComfyApp.isImageNode(this)) {
|
if (ComfyApp.isImageNode(this)) {
|
||||||
options.push({
|
options.push({
|
||||||
content: "Open in MaskEditor",
|
content: "Open in MaskEditor",
|
||||||
callback: (obj) => {
|
callback: (obj) => {
|
||||||
ComfyApp.copyToClipspace(this);
|
ComfyApp.copyToClipspace(this);
|
||||||
ComfyApp.clipspace_return_node = this;
|
ComfyApp.clipspace_return_node = this;
|
||||||
ComfyApp.open_maskeditor();
|
ComfyApp.open_maskeditor();
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user