Files
1hew-ComfyUI-1hewNodes/web/js/load_image_from_folder.js
T

169 lines
8.1 KiB
JavaScript

import { app } from "../../../scripts/app.js";
import { api } from "../../../scripts/api.js";
app.registerExtension({
name: "ComfyUI-1hewNodes.LoadImageFromFolder",
async beforeRegisterNodeDef(nodeType, nodeData, app) {
if (nodeData.name !== "1hew_LoadImageFromFolder") {
return;
}
const onConfigure = nodeType.prototype.onConfigure;
nodeType.prototype.onConfigure = function () {
const r = onConfigure ? onConfigure.apply(this, arguments) : undefined;
if (this.widgets) {
const folderWidget = this.widgets.find((w) => w.name === "folder");
if (folderWidget && folderWidget.value) {
// 延迟一点执行,确保节点完全初始化
setTimeout(() => {
const update = this.updatePreview;
if (update) update();
}, 100);
}
}
return r;
};
const onNodeCreated = nodeType.prototype.onNodeCreated;
nodeType.prototype.onNodeCreated = function () {
const r = onNodeCreated ? onNodeCreated.apply(this, arguments) : undefined;
const folderWidget = this.widgets.find((w) => w.name === "folder");
const indexWidget = this.widgets.find((w) => w.name === "index");
const includeSubfolderWidget = this.widgets.find((w) => w.name === "include_subfolder");
const allWidget = this.widgets.find((w) => w.name === "all");
this.updatePreview = async () => {
const folder = folderWidget.value;
const index = indexWidget.value;
const includeSubfolder = includeSubfolderWidget.value;
const all = allWidget ? allWidget.value : false;
if (!folder) return;
if (all) {
// 批量模式:获取图片列表并加载多张图片,模拟 Preview Image 节点的行为
try {
const params = new URLSearchParams({
folder: folder,
include_subfolder: includeSubfolder,
return_list: "true"
});
const res = await api.fetchApi(`/1hew/view_image_from_folder?${params.toString()}`);
if (res.status === 200) {
const data = await res.json();
const count = data.count;
// 限制预览数量,防止过多请求
const maxPreview = 200;
const loadCount = Math.min(count, maxPreview);
// 并行加载图片
const promises = [];
for (let i = 0; i < loadCount; i++) {
const p = new Promise((resolve) => {
const img = new Image();
img.onload = () => {
resolve(img);
};
img.onerror = () => {
resolve(null);
}
// 请求单张图片 (all=false),利用 index 获取特定图片
const imgParams = new URLSearchParams({
folder: folder,
index: i,
include_subfolder: includeSubfolder,
all: "false"
});
img.src = `/1hew/view_image_from_folder?${imgParams.toString()}`;
});
promises.push(p);
}
const loadedImgs = await Promise.all(promises);
this.imgs = loadedImgs.filter(img => img !== null);
// 调整节点尺寸(基于第一张图)
if (this.imgs.length > 0) {
const img = this.imgs[0];
if (img.naturalWidth > 0 && img.naturalHeight > 0) {
const headerHeight = 30;
const widgetMargin = 10;
const widgetHeight = this.widgets.reduce((acc, w) => acc + (w.computeSize ? w.computeSize()[1] : 20), 0) + headerHeight + widgetMargin;
const availableWidth = this.size[0];
const ratio = img.naturalWidth / img.naturalHeight;
const drawHeight = availableWidth / ratio;
const totalHeight = widgetHeight + drawHeight + 10;
if (this.size[1] < totalHeight) {
this.setSize([this.size[0], totalHeight]);
}
}
}
app.graph.setDirtyCanvas(true);
}
} catch (e) {
console.error("Failed to load image list", e);
}
} else {
// 单张模式
// 构建 API URL
const params = new URLSearchParams({
folder: folder,
index: index,
include_subfolder: includeSubfolder,
all: "false"
});
const url = `/1hew/view_image_from_folder?${params.toString()}&t=${Date.now()}`;
// 创建图片对象并加载
const img = new Image();
img.onload = () => {
this.imgs = [img];
// 自动调整节点尺寸
if (img.naturalWidth > 0 && img.naturalHeight > 0) {
const headerHeight = 30;
const widgetMargin = 10;
const widgetHeight = this.widgets.reduce((acc, w) => acc + (w.computeSize ? w.computeSize()[1] : 20), 0) + headerHeight + widgetMargin;
const availableWidth = this.size[0];
const ratio = img.naturalWidth / img.naturalHeight;
const drawHeight = availableWidth / ratio;
const totalHeight = widgetHeight + drawHeight + 10;
if (this.size[1] < totalHeight) {
this.setSize([this.size[0], totalHeight]);
}
}
app.graph.setDirtyCanvas(true);
};
img.src = url;
}
};
// 监听 widget 变化
if (folderWidget) folderWidget.callback = this.updatePreview;
if (indexWidget) indexWidget.callback = this.updatePreview;
if (includeSubfolderWidget) includeSubfolderWidget.callback = this.updatePreview;
if (allWidget) allWidget.callback = this.updatePreview;
// 初始加载
if (folderWidget && folderWidget.value) {
this.updatePreview();
}
return r;
};
// 移除手动绘制,使用 ComfyUI 原生 this.imgs 机制避免重叠
// const onDrawForeground = nodeType.prototype.onDrawForeground;
// nodeType.prototype.onDrawForeground = function (ctx) { ... };
},
});