Image upload widget

This commit is contained in:
space-nuko
2023-05-08 18:08:28 -05:00
parent 5feffcfa17
commit 0f50dbae87
15 changed files with 380 additions and 48 deletions

View File

@@ -207,21 +207,29 @@ LiteGraph.registerNodeType({
})
export interface ComfyExecuteSubgraphActionProperties extends ComfyGraphNodeProperties {
tag: string | null,
targetTag: string
}
export class ComfyExecuteSubgraphAction extends ComfyGraphNode {
override properties: ComfyExecuteSubgraphActionProperties = {
tag: null
tags: [],
targetTag: ""
}
static slotLayout: SlotLayout = {
inputs: [
{ name: "execute", type: BuiltInSlotType.ACTION },
{ name: "tag", type: "string" }
{ name: "targetTag", type: "string" }
],
}
displayWidget: ITextWidget;
constructor(title?: string) {
super(title)
this.displayWidget = this.addWidget("text", "targetTag", this.properties.targetTag, "targetTag")
}
override onExecute() {
const tag = this.getInputData(1)
if (tag)
@@ -229,7 +237,7 @@ export class ComfyExecuteSubgraphAction extends ComfyGraphNode {
}
override onAction(action: any, param: any) {
const tag = this.getInputData(1) || this.properties.tag;
const tag = this.getInputData(1) || this.properties.targetTag;
const app = (window as any)?.app;
if (!app)

View File

@@ -12,6 +12,10 @@ export interface ComfyImageCacheNodeProperties extends ComfyGraphNodeProperties
type ImageCacheState = "none" | "uploading" | "failed" | "cached"
interface ComfyUploadImageAPIResponse {
name: string
}
/*
* A node that can act as both an input and output image node by uploading
* the output file into ComfyUI's input folder.
@@ -159,6 +163,7 @@ export default class ComfyImageCacheNode extends ComfyGraphNode {
else {
this.properties.filenames[newIndex] = { filename: null, status: "uploading" }
this.onPropertyChanged("filenames", this.properties.filenames)
const url = `http://${location.hostname}:8188` // TODO make configurable
const params = new URLSearchParams(data)
@@ -176,10 +181,10 @@ export default class ComfyImageCacheNode extends ComfyGraphNode {
)
})
.then((r) => r.json())
.then((json) => {
.then((json: ComfyUploadImageAPIResponse) => {
console.debug("Gottem", json)
if (lastGenNumber === this.properties.genNumber) {
this.properties.filenames[newIndex] = { filename: data.filename, status: "cached" }
this.properties.filenames[newIndex] = { filename: json.name, status: "cached" }
this.onPropertyChanged("filenames", this.properties.filenames)
}
else {

View File

@@ -16,6 +16,7 @@ import GalleryWidget from "$lib/widgets/GalleryWidget.svelte";
import ButtonWidget from "$lib/widgets/ButtonWidget.svelte";
import CheckboxWidget from "$lib/widgets/CheckboxWidget.svelte";
import RadioWidget from "$lib/widgets/RadioWidget.svelte";
import ImageUploadWidget from "$lib/widgets/ImageUploadWidget.svelte";
/*
* NOTE: If you want to add a new widget but it has the same input/output type
@@ -79,6 +80,8 @@ export abstract class ComfyWidgetNode<T = any> extends ComfyGraphNode {
override isBackendNode = false;
override serialize_widgets = true;
// TODO these are bad, create override methods instead
// input slots
inputIndex: number = 0;
@@ -86,6 +89,7 @@ export abstract class ComfyWidgetNode<T = any> extends ComfyGraphNode {
outputIndex: number | null = 0;
changedIndex: number | null = 1;
displayWidget: ITextWidget;
override size: Vector2 = [60, 40];
@@ -203,7 +207,7 @@ export abstract class ComfyWidgetNode<T = any> extends ComfyGraphNode {
): boolean {
const anyConnected = range(this.outputs.length).some(i => this.getOutputLinks(i).length > 0);
if (this.autoConfig && "config" in input && !anyConnected) {
if (this.autoConfig && "config" in input && !anyConnected && (input as IComfyInputSlot).widgetNodeType === this.type) {
this.doAutoConfig(input as IComfyInputSlot)
}
@@ -751,3 +755,52 @@ LiteGraph.registerNodeType({
desc: "Radio that outputs a string and index",
type: "ui/radio"
})
export interface ComfyImageUploadProperties extends ComfyWidgetProperties {
fileCount: "single" | "multiple" // gradio File component format
}
export class ComfyImageUploadNode extends ComfyWidgetNode<Array<GradioFileData>> {
override properties: ComfyImageUploadProperties = {
defaultValue: [],
tags: [],
fileCount: "single",
}
static slotLayout: SlotLayout = {
outputs: [
{ name: "filename", type: "string" }, // TODO support batches
{ name: "changed", type: BuiltInSlotType.EVENT },
]
}
override svelteComponentType = ImageUploadWidget;
override defaultValue = null;
override outputIndex = null;
override changedIndex = 1;
constructor(name?: string) {
super(name, [])
}
override onExecute(param: any, options: object) {
super.onExecute(param, options);
const value = get(this.value)
if (value.length > 0 && value[0].name)
this.setOutputData(0, value[0].name) // TODO when ComfyUI LoadImage supports loading an image batch
else
this.setOutputData(0, "")
}
override formatValue(value: GradioFileData[]): string {
return `Images: ${value.length}`
}
}
LiteGraph.registerNodeType({
class: ComfyImageUploadNode,
title: "UI.ImageUpload",
desc: "Widget that lets you upload images into ComfyUI's input folder",
type: "ui/image_upload"
})