65 lines
2.1 KiB
JavaScript
65 lines
2.1 KiB
JavaScript
const SUPPORTED_IMAGE = /\.(png|jpe?g|webp|bmp)$/i;
|
|
|
|
export function parseImageWidgetValue(value) {
|
|
if (typeof value !== "string") return null;
|
|
let path = value.trim();
|
|
if (!path) return null;
|
|
|
|
let type = "input";
|
|
const annotation = path.match(/\s+\[(input|output|temp)\]$/i);
|
|
if (annotation) {
|
|
type = annotation[1].toLowerCase();
|
|
path = path.slice(0, annotation.index).trim();
|
|
}
|
|
if (!SUPPORTED_IMAGE.test(path)) return null;
|
|
|
|
const separator = path.lastIndexOf("/");
|
|
return {
|
|
filename: separator >= 0 ? path.substring(separator + 1) : path,
|
|
subfolder: separator >= 0 ? path.substring(0, separator) : "",
|
|
type,
|
|
};
|
|
}
|
|
|
|
function graphLink(graph, linkId) {
|
|
return graph?.links?.get?.(linkId) || graph?.links?.[linkId] || null;
|
|
}
|
|
|
|
function imageRefFromNode(node) {
|
|
if (!node) return null;
|
|
const widgets = node.widgets || [];
|
|
const preferred = widgets.find((widget) => widget.name?.toLowerCase() === "image");
|
|
const candidates = preferred ? [preferred, ...widgets.filter((widget) => widget !== preferred)] : widgets;
|
|
for (const widget of candidates) {
|
|
const imageRef = parseImageWidgetValue(widget.value);
|
|
if (imageRef) return imageRef;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
function resolveLink(graph, linkId, visited) {
|
|
if (linkId == null || visited.has(linkId)) return null;
|
|
visited.add(linkId);
|
|
|
|
const link = graphLink(graph, linkId);
|
|
if (!link) return null;
|
|
const sourceNode = graph?.getNodeById?.(link.origin_id);
|
|
if (!sourceNode) return null;
|
|
|
|
const imageRef = imageRefFromNode(sourceNode);
|
|
if (imageRef) return { imageRef, sourceNode };
|
|
|
|
const isReroute = /reroute/i.test(`${sourceNode.type || ""} ${sourceNode.comfyClass || ""}`);
|
|
if (isReroute) {
|
|
const upstream = sourceNode.inputs?.find((input) => input.link != null);
|
|
if (upstream) return resolveLink(graph, upstream.link, visited);
|
|
}
|
|
return null;
|
|
}
|
|
|
|
export function resolveConnectedImageSource(node, inputName = "image") {
|
|
const input = node?.inputs?.find((candidate) => candidate.name === inputName);
|
|
if (input?.link == null) return null;
|
|
return resolveLink(node.graph, input.link, new Set());
|
|
}
|