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('$')) { // from node feedback 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 { // from clipspace 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()]; // placeholder image.onload = function(v) { set_img_act([image]); }; } catch { } } return this._img; } }); } } })