Image editor

This commit is contained in:
space-nuko
2023-05-13 14:54:07 -05:00
parent 4d90623505
commit f66df94c36
9 changed files with 272 additions and 123 deletions

View File

@@ -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;
})

View File

@@ -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 {

View File

@@ -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 {