Add custom nodes, Civitai loras (LFS), and vast.ai setup script
Some checks failed
Python Linting / Run Ruff (push) Has been cancelled
Python Linting / Run Pylint (push) Has been cancelled
Full Comfy CI Workflow Runs / test-stable (12.1, , linux, 3.10, [self-hosted Linux], stable) (push) Has been cancelled
Full Comfy CI Workflow Runs / test-stable (12.1, , linux, 3.11, [self-hosted Linux], stable) (push) Has been cancelled
Full Comfy CI Workflow Runs / test-stable (12.1, , linux, 3.12, [self-hosted Linux], stable) (push) Has been cancelled
Full Comfy CI Workflow Runs / test-unix-nightly (12.1, , linux, 3.11, [self-hosted Linux], nightly) (push) Has been cancelled
Execution Tests / test (macos-latest) (push) Has been cancelled
Execution Tests / test (ubuntu-latest) (push) Has been cancelled
Execution Tests / test (windows-latest) (push) Has been cancelled
Test server launches without errors / test (push) Has been cancelled
Unit Tests / test (macos-latest) (push) Has been cancelled
Unit Tests / test (ubuntu-latest) (push) Has been cancelled
Unit Tests / test (windows-2022) (push) Has been cancelled
Some checks failed
Python Linting / Run Ruff (push) Has been cancelled
Python Linting / Run Pylint (push) Has been cancelled
Full Comfy CI Workflow Runs / test-stable (12.1, , linux, 3.10, [self-hosted Linux], stable) (push) Has been cancelled
Full Comfy CI Workflow Runs / test-stable (12.1, , linux, 3.11, [self-hosted Linux], stable) (push) Has been cancelled
Full Comfy CI Workflow Runs / test-stable (12.1, , linux, 3.12, [self-hosted Linux], stable) (push) Has been cancelled
Full Comfy CI Workflow Runs / test-unix-nightly (12.1, , linux, 3.11, [self-hosted Linux], nightly) (push) Has been cancelled
Execution Tests / test (macos-latest) (push) Has been cancelled
Execution Tests / test (ubuntu-latest) (push) Has been cancelled
Execution Tests / test (windows-latest) (push) Has been cancelled
Test server launches without errors / test (push) Has been cancelled
Unit Tests / test (macos-latest) (push) Has been cancelled
Unit Tests / test (ubuntu-latest) (push) Has been cancelled
Unit Tests / test (windows-2022) (push) Has been cancelled
Includes 30 custom nodes committed directly, 7 Civitai-exclusive loras stored via Git LFS, and a setup script that installs all dependencies and downloads HuggingFace-hosted models on vast.ai. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
229
custom_nodes/ComfyUI-Impact-Pack/js/impact-image-util.js
Normal file
229
custom_nodes/ComfyUI-Impact-Pack/js/impact-image-util.js
Normal file
@@ -0,0 +1,229 @@
|
||||
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;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
})
|
||||
Reference in New Issue
Block a user