|
import { ComfyApp, app } from "../../scripts/app.js"; |
|
import { api } from "../../scripts/api.js"; |
|
|
|
function load_image(str) { |
|
let base64String = canvas.toDataURL('image/png'); |
|
let img = new Image(); |
|
img.src = base64String; |
|
} |
|
|
|
function getFileItem(baseType, path) { |
|
try { |
|
let pathType = baseType; |
|
|
|
if (path.endsWith("[output]")) { |
|
pathType = "output"; |
|
path = path.slice(0, -9); |
|
} else if (path.endsWith("[input]")) { |
|
pathType = "input"; |
|
path = path.slice(0, -8); |
|
} else if (path.endsWith("[temp]")) { |
|
pathType = "temp"; |
|
path = path.slice(0, -7); |
|
} |
|
|
|
const subfolder = path.substring(0, path.lastIndexOf('/')); |
|
const filename = path.substring(path.lastIndexOf('/') + 1); |
|
|
|
return { |
|
filename: filename, |
|
subfolder: subfolder, |
|
type: pathType |
|
}; |
|
} |
|
catch(exception) { |
|
return null; |
|
} |
|
} |
|
|
|
async function loadImageFromUrl(image, node_id, v, need_to_load) { |
|
let item = getFileItem('temp', v); |
|
|
|
if(item) { |
|
let params = `?node_id=${node_id}&filename=${item.filename}&type=${item.type}&subfolder=${item.subfolder}`; |
|
|
|
let res = await api.fetchApi('/impact/set/pb_id_image'+params, { cache: "no-store" }); |
|
if(res.status == 200) { |
|
let pb_id = await res.text(); |
|
if(need_to_load) {; |
|
image.src = api.apiURL(`/view?filename=${item.filename}&type=${item.type}&subfolder=${item.subfolder}`); |
|
} |
|
return pb_id; |
|
} |
|
else { |
|
return `$${node_id}-0`; |
|
} |
|
} |
|
else { |
|
return `$${node_id}-0`; |
|
} |
|
} |
|
|
|
async function loadImageFromId(image, v) { |
|
let res = await api.fetchApi('/impact/get/pb_id_image?id='+v, { cache: "no-store" }); |
|
if(res.status == 200) { |
|
let item = await res.json(); |
|
image.src = api.apiURL(`/view?filename=${item.filename}&type=${item.type}&subfolder=${item.subfolder}`); |
|
return true; |
|
} |
|
|
|
return false; |
|
} |
|
|
|
app.registerExtension({ |
|
name: "Comfy.Impact.img", |
|
|
|
nodeCreated(node, app) { |
|
if(node.comfyClass == "PreviewBridge" || node.comfyClass == "PreviewBridgeLatent") { |
|
let w = node.widgets.find(obj => obj.name === 'image'); |
|
node._imgs = [new Image()]; |
|
node.imageIndex = 0; |
|
|
|
Object.defineProperty(w, 'value', { |
|
async set(v) { |
|
if(w._lock) |
|
return; |
|
|
|
const stackTrace = new Error().stack; |
|
if(stackTrace.includes('presetText.js')) |
|
return; |
|
|
|
var image = new Image(); |
|
if(v && v.constructor == String && v.startsWith('$')) { |
|
|
|
let need_to_load = node._imgs[0].src == ''; |
|
if(await loadImageFromId(image, v, need_to_load)) { |
|
w._value = v; |
|
if(node._imgs[0].src == '') { |
|
node._imgs = [image]; |
|
} |
|
} |
|
else { |
|
w._value = `$${node.id}-0`; |
|
} |
|
} |
|
else { |
|
|
|
w._lock = true; |
|
w._value = await loadImageFromUrl(image, node.id, v, false); |
|
w._lock = false; |
|
} |
|
}, |
|
get() { |
|
if(w._value == undefined) { |
|
w._value = `$${node.id}-0`; |
|
} |
|
return w._value; |
|
} |
|
}); |
|
|
|
Object.defineProperty(node, 'imgs', { |
|
set(v) { |
|
const stackTrace = new Error().stack; |
|
if(v && v.length == 0) |
|
return; |
|
else if(stackTrace.includes('pasteFromClipspace')) { |
|
let sp = new URLSearchParams(v[0].src.split("?")[1]); |
|
let str = ""; |
|
if(sp.get('subfolder')) { |
|
str += sp.get('subfolder') + '/'; |
|
} |
|
str += `${sp.get("filename")} [${sp.get("type")}]`; |
|
|
|
w.value = str; |
|
} |
|
|
|
node._imgs = v; |
|
}, |
|
get() { |
|
return node._imgs; |
|
} |
|
}); |
|
} |
|
|
|
if(node.comfyClass == "ImageReceiver") { |
|
let path_widget = node.widgets.find(obj => obj.name === 'image'); |
|
let w = node.widgets.find(obj => obj.name === 'image_data'); |
|
let stw_widget = node.widgets.find(obj => obj.name === 'save_to_workflow'); |
|
w._value = ""; |
|
|
|
Object.defineProperty(w, 'value', { |
|
set(v) { |
|
if(v != '[IMAGE DATA]') |
|
w._value = v; |
|
}, |
|
get() { |
|
const stackTrace = new Error().stack; |
|
if(!stackTrace.includes('draw') && !stackTrace.includes('graphToPrompt') && stackTrace.includes('app.js')) { |
|
return "[IMAGE DATA]"; |
|
} |
|
else { |
|
if(stw_widget.value) |
|
return w._value; |
|
else |
|
return ""; |
|
} |
|
} |
|
}); |
|
|
|
let set_img_act = (v) => { |
|
node._img = v; |
|
var canvas = document.createElement('canvas'); |
|
canvas.width = v[0].width; |
|
canvas.height = v[0].height; |
|
|
|
var context = canvas.getContext('2d'); |
|
context.drawImage(v[0], 0, 0, v[0].width, v[0].height); |
|
|
|
var base64Image = canvas.toDataURL('image/png'); |
|
w.value = base64Image; |
|
}; |
|
|
|
Object.defineProperty(node, 'imgs', { |
|
set(v) { |
|
if (v && !v[0].complete) { |
|
let orig_onload = v[0].onload; |
|
v[0].onload = function(v2) { |
|
if(orig_onload) |
|
orig_onload(); |
|
set_img_act(v); |
|
}; |
|
} |
|
else { |
|
set_img_act(v); |
|
} |
|
}, |
|
get() { |
|
if(this._img == undefined && w.value != '') { |
|
this._img = [new Image()]; |
|
if(stw_widget.value && w.value != '[IMAGE DATA]') |
|
this._img[0].src = w.value; |
|
} |
|
else if(this._img == undefined && path_widget.value) { |
|
let image = new Image(); |
|
image.src = path_widget.value; |
|
|
|
try { |
|
let item = getFileItem('temp', path_widget.value); |
|
let params = `?filename=${item.filename}&type=${item.type}&subfolder=${item.subfolder}`; |
|
|
|
let res = api.fetchApi('/view/validate'+params, { cache: "no-store" }).then(response => response); |
|
if(res.status == 200) { |
|
image.src = api.apiURL('/view'+params); |
|
} |
|
|
|
this._img = [new Image()]; |
|
image.onload = function(v) { |
|
set_img_act([image]); |
|
}; |
|
} |
|
catch { |
|
|
|
} |
|
} |
|
return this._img; |
|
} |
|
}); |
|
} |
|
} |
|
}) |
|
|