Image editor
This commit is contained in:
@@ -8,7 +8,7 @@ import ComfyGraphNode, { type ComfyGraphNodeProperties } from "./ComfyGraphNode"
|
||||
import type { ComfyWidgetNode, GalleryOutput, GalleryOutputEntry } from "./ComfyWidgetNodes";
|
||||
import type { NotifyOptions } from "$lib/notify";
|
||||
import type { FileData as GradioFileData } from "@gradio/upload";
|
||||
import { convertComfyOutputToGradio, uploadImageToComfyUI, type ComfyUploadImageAPIResponse } from "$lib/utils";
|
||||
import { convertComfyOutputToGradio, reuploadImageToComfyUI, type ComfyUploadImageAPIResponse } from "$lib/utils";
|
||||
|
||||
export class ComfyQueueEvents extends ComfyGraphNode {
|
||||
static slotLayout: SlotLayout = {
|
||||
@@ -638,10 +638,10 @@ export class ComfyUploadImageAction extends ComfyGraphNode {
|
||||
type: this.properties.folderType || "output"
|
||||
}
|
||||
|
||||
this._promise = uploadImageToComfyUI(data)
|
||||
.then((json: ComfyUploadImageAPIResponse) => {
|
||||
console.debug("[UploadImageAction] Succeeded", json)
|
||||
this.properties.lastUploadedImageFile = json.name;
|
||||
this._promise = reuploadImageToComfyUI(data, "input")
|
||||
.then((entry: GalleryOutputEntry) => {
|
||||
console.debug("[UploadImageAction] Succeeded", entry)
|
||||
this.properties.lastUploadedImageFile = entry.filename;
|
||||
this.triggerSlot(1, this.properties.lastUploadedImageFile);
|
||||
this._promise = null;
|
||||
})
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { BuiltInSlotType, LiteGraph, type ITextWidget, type SlotLayout, clamp, type PropertyLayout, type IComboWidget, type SerializedLGraphNode } from "@litegraph-ts/core";
|
||||
import ComfyGraphNode, { type ComfyGraphNodeProperties } from "./ComfyGraphNode";
|
||||
import type { GalleryOutput } from "./ComfyWidgetNodes";
|
||||
import { uploadImageToComfyUI, type ComfyUploadImageAPIResponse } from "$lib/utils";
|
||||
import type { GalleryOutput, GalleryOutputEntry } from "./ComfyWidgetNodes";
|
||||
import { reuploadImageToComfyUI, type ComfyUploadImageAPIResponse } from "$lib/utils";
|
||||
|
||||
export interface ComfyImageCacheNodeProperties extends ComfyGraphNodeProperties {
|
||||
images: GalleryOutput | null,
|
||||
@@ -171,11 +171,11 @@ export default class ComfyImageCacheNode extends ComfyGraphNode {
|
||||
this.properties.filenames[newIndex] = { filename: null, status: "uploading" }
|
||||
this.onPropertyChanged("filenames", this.properties.filenames)
|
||||
|
||||
const promise = uploadImageToComfyUI(data)
|
||||
.then((json: ComfyUploadImageAPIResponse) => {
|
||||
console.debug("Gottem", json)
|
||||
const promise = reuploadImageToComfyUI(data, "input")
|
||||
.then((entry: GalleryOutputEntry) => {
|
||||
console.debug("Gottem", entry)
|
||||
if (lastGenNumber === this.properties.genNumber) {
|
||||
this.properties.filenames[newIndex] = { filename: json.name, status: "cached" }
|
||||
this.properties.filenames[newIndex] = { filename: entry.filename, status: "cached" }
|
||||
this.onPropertyChanged("filenames", this.properties.filenames)
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -4,7 +4,7 @@ import type { SvelteComponentDev } from "svelte/internal";
|
||||
import { Watch } from "@litegraph-ts/nodes-basic";
|
||||
import type IComfyInputSlot from "$lib/IComfyInputSlot";
|
||||
import { writable, type Unsubscriber, type Writable, get } from "svelte/store";
|
||||
import { clamp, convertComfyOutputToGradio, range } from "$lib/utils"
|
||||
import { clamp, convertComfyOutputToGradio, range, type ComfyUploadImageType } from "$lib/utils"
|
||||
import layoutState from "$lib/stores/layoutState";
|
||||
import type { FileData as GradioFileData } from "@gradio/upload";
|
||||
import queueState from "$lib/stores/queueState";
|
||||
@@ -604,7 +604,7 @@ export type GalleryOutput = {
|
||||
export type GalleryOutputEntry = {
|
||||
filename: string,
|
||||
subfolder: string,
|
||||
type: string
|
||||
type: ComfyUploadImageType
|
||||
}
|
||||
|
||||
export interface ComfyGalleryProperties extends ComfyWidgetProperties {
|
||||
@@ -985,7 +985,7 @@ export type MultiImageData = FileNameOrGalleryData[];
|
||||
export interface ComfyImageEditorNodeProperties extends ComfyWidgetProperties {
|
||||
}
|
||||
|
||||
export class ComfyImageEditorNode extends ComfyWidgetNode<MultiImageData> {
|
||||
export class ComfyImageEditorNode extends ComfyWidgetNode<GalleryOutputEntry[]> {
|
||||
override properties: ComfyImageEditorNodeProperties = {
|
||||
defaultValue: [],
|
||||
tags: [],
|
||||
@@ -1000,7 +1000,7 @@ export class ComfyImageEditorNode extends ComfyWidgetNode<MultiImageData> {
|
||||
}
|
||||
|
||||
override svelteComponentType = ImageEditorWidget;
|
||||
override defaultValue: MultiImageData = [];
|
||||
override defaultValue: GalleryOutputEntry[] = [];
|
||||
override outputIndex = null;
|
||||
override changedIndex = null;
|
||||
override storeActionName = "store";
|
||||
@@ -1012,27 +1012,30 @@ export class ComfyImageEditorNode extends ComfyWidgetNode<MultiImageData> {
|
||||
|
||||
_value = null;
|
||||
|
||||
override parseValue(value: any): MultiImageData {
|
||||
if (value == null) {
|
||||
override parseValue(value: any): GalleryOutputEntry[] {
|
||||
if (value == null)
|
||||
return []
|
||||
|
||||
const isComfyImageSpec = (value: any): boolean => {
|
||||
return value && typeof value === "object" && "filename" in value && "type" in value
|
||||
}
|
||||
else if (typeof value === "string" && value !== "") { // Single filename
|
||||
const prevValue = get(this.value)
|
||||
prevValue.push(value)
|
||||
if (prevValue.length > 2)
|
||||
prevValue.splice(0, 1)
|
||||
return prevValue as MultiImageData
|
||||
|
||||
if (typeof value === "string") {
|
||||
// Single filename
|
||||
return [{ filename: value, subfolder: "", type: "input" }]
|
||||
}
|
||||
else if (typeof value === "object" && "images" in value && value.images.length > 0) {
|
||||
const output = value as GalleryOutput
|
||||
else if (isComfyImageSpec(value)) {
|
||||
// Single ComfyUI file
|
||||
return [value]
|
||||
}
|
||||
else if (Array.isArray(value) && value.every(s => typeof s === "string")) {
|
||||
return value as MultiImageData
|
||||
}
|
||||
else {
|
||||
return []
|
||||
else if (Array.isArray(value)) {
|
||||
if (value.every(v => typeof v === "string"))
|
||||
return value.map(filename => { return { filename, subfolder: "", type: "input" } })
|
||||
else if (value.every(isComfyImageSpec))
|
||||
return value
|
||||
}
|
||||
|
||||
return []
|
||||
}
|
||||
|
||||
override formatValue(value: GradioFileData[]): string {
|
||||
|
||||
Reference in New Issue
Block a user