Fix image upload
This commit is contained in:
@@ -339,6 +339,7 @@
|
|||||||
border-bottom: 1px solid var(--block-border-color);
|
border-bottom: 1px solid var(--block-border-color);
|
||||||
border-top: 1px solid var(--table-border-color);
|
border-top: 1px solid var(--table-border-color);
|
||||||
background: var(--panel-background-fill);
|
background: var(--panel-background-fill);
|
||||||
|
max-height: 14rem;
|
||||||
|
|
||||||
&:hover:not(:has(img:hover)) {
|
&:hover:not(:has(img:hover)) {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
@@ -387,6 +388,7 @@
|
|||||||
column-gap: 1px;
|
column-gap: 1px;
|
||||||
row-gap: 1px;
|
row-gap: 1px;
|
||||||
vertical-align: top;
|
vertical-align: top;
|
||||||
|
flex: 1 1 40%;
|
||||||
|
|
||||||
img {
|
img {
|
||||||
aspect-ratio: 1 / 1;
|
aspect-ratio: 1 / 1;
|
||||||
|
|||||||
@@ -25,13 +25,13 @@
|
|||||||
let _value: GradioFileData[] | null = null;
|
let _value: GradioFileData[] | null = null;
|
||||||
const root = "comf"
|
const root = "comf"
|
||||||
const root_url = "https//ComfyUI!"
|
const root_url = "https//ComfyUI!"
|
||||||
|
let uploaded: boolean = false;
|
||||||
|
|
||||||
const dispatch = createEventDispatcher<{
|
const dispatch = createEventDispatcher<{
|
||||||
change: GalleryOutputEntry[];
|
change: GalleryOutputEntry[];
|
||||||
uploading: undefined;
|
uploading: undefined;
|
||||||
uploaded: GalleryOutputEntry[];
|
uploaded: GalleryOutputEntry[];
|
||||||
upload_error: any;
|
upload_error: any;
|
||||||
load: undefined;
|
|
||||||
clear: undefined;
|
clear: undefined;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
@@ -58,10 +58,6 @@
|
|||||||
dispatch("clear")
|
dispatch("clear")
|
||||||
}
|
}
|
||||||
|
|
||||||
function onLoad() {
|
|
||||||
dispatch("load")
|
|
||||||
}
|
|
||||||
|
|
||||||
interface GradioUploadResponse {
|
interface GradioUploadResponse {
|
||||||
error?: string;
|
error?: string;
|
||||||
files?: Array<GalleryOutputEntry>;
|
files?: Array<GalleryOutputEntry>;
|
||||||
@@ -114,7 +110,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
$: {
|
$: {
|
||||||
if (JSON.stringify(_value) !== JSON.stringify(old_value)) {
|
if (JSON.stringify(_value) !== JSON.stringify(old_value) || uploaded) {
|
||||||
|
uploaded = false;
|
||||||
pending_upload = true;
|
pending_upload = true;
|
||||||
|
|
||||||
old_value = _value;
|
old_value = _value;
|
||||||
@@ -128,11 +125,14 @@
|
|||||||
|
|
||||||
if (allBlobs == null || allBlobs.length === 0) {
|
if (allBlobs == null || allBlobs.length === 0) {
|
||||||
_value = null;
|
_value = null;
|
||||||
|
value = null;
|
||||||
onChange();
|
onChange();
|
||||||
pending_upload = false;
|
pending_upload = false;
|
||||||
}
|
}
|
||||||
else if (!allBlobs.every(b => b != null)) {
|
else if (!allBlobs.every(b => b != null)) {
|
||||||
_value = null;
|
_value = null;
|
||||||
|
value = null;
|
||||||
|
onChange();
|
||||||
pending_upload = false;
|
pending_upload = false;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -155,7 +155,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
value = response.files;
|
value = response.files;
|
||||||
dispatch("change")
|
dispatch("change", value)
|
||||||
dispatch("uploaded", value)
|
dispatch("uploaded", value)
|
||||||
}).
|
}).
|
||||||
catch(err => {
|
catch(err => {
|
||||||
@@ -166,26 +166,22 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function handle_upload({ detail }: CustomEvent<GradioFileData | Array<GradioFileData>>) {
|
async function handle_upload({ detail }: CustomEvent<GradioFileData | Array<GradioFileData>>) {
|
||||||
|
// Received Gradio-format file data from the Upload component.
|
||||||
|
// In the reactive block above it will be uploaded to ComfyUI.
|
||||||
_value = Array.isArray(detail) ? detail : [detail];
|
_value = Array.isArray(detail) ? detail : [detail];
|
||||||
await tick();
|
uploaded = true;
|
||||||
dispatch("change")
|
|
||||||
dispatch("load")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function handle_clear(_e: CustomEvent<null>) {
|
function handle_clear(_e: CustomEvent<null>) {
|
||||||
_value = null;
|
_value = null;
|
||||||
value = [];
|
value = [];
|
||||||
dispatch("change")
|
dispatch("change", value)
|
||||||
dispatch("clear")
|
dispatch("clear")
|
||||||
}
|
}
|
||||||
|
|
||||||
function convertGradioUpload(e: CustomEvent<GradioFileData[]>) {
|
function convertGradioUpload(e: CustomEvent<GradioFileData[]>) {
|
||||||
_value = e.detail
|
_value = e.detail
|
||||||
}
|
}
|
||||||
|
|
||||||
function convertNodeValue(nodeValue: GalleryOutputEntry[]): GradioFileData[] {
|
|
||||||
return nodeValue.map(convertComfyOutputEntryToGradio);
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="image-upload" {style}>
|
<div class="image-upload" {style}>
|
||||||
|
|||||||
@@ -913,16 +913,34 @@ export class ComfyImageUploadNode extends ComfyWidgetNode<GalleryOutputEntry[]>
|
|||||||
override svelteComponentType = ImageUploadWidget;
|
override svelteComponentType = ImageUploadWidget;
|
||||||
override defaultValue = [];
|
override defaultValue = [];
|
||||||
override outputIndex = null;
|
override outputIndex = null;
|
||||||
override changedIndex = 3;
|
override changedIndex = 4;
|
||||||
override storeActionName = "store";
|
override storeActionName = "store";
|
||||||
override saveUserState = false;
|
override saveUserState = false;
|
||||||
|
|
||||||
imageSize: Vector2 = [1, 1];
|
imageSize: Vector2 = [0, 0];
|
||||||
|
|
||||||
constructor(name?: string) {
|
constructor(name?: string) {
|
||||||
super(name, [])
|
super(name, [])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override onExecute(param: any, options: object) {
|
||||||
|
super.onExecute(param, options);
|
||||||
|
|
||||||
|
const value = get(this.value)
|
||||||
|
if (value.length > 0) {
|
||||||
|
this.setOutputData(0, value[0].filename) // TODO when ComfyUI LoadImage supports loading an image batch
|
||||||
|
this.setOutputData(1, this.imageSize[0])
|
||||||
|
this.setOutputData(2, this.imageSize[1])
|
||||||
|
this.setOutputData(3, value.length)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.setOutputData(0, "")
|
||||||
|
this.setOutputData(1, 0)
|
||||||
|
this.setOutputData(2, 0)
|
||||||
|
this.setOutputData(3, 0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override parseValue(value: any): GalleryOutputEntry[] {
|
override parseValue(value: any): GalleryOutputEntry[] {
|
||||||
if (value == null)
|
if (value == null)
|
||||||
return []
|
return []
|
||||||
@@ -949,24 +967,6 @@ export class ComfyImageUploadNode extends ComfyWidgetNode<GalleryOutputEntry[]>
|
|||||||
return []
|
return []
|
||||||
}
|
}
|
||||||
|
|
||||||
override onExecute(param: any, options: object) {
|
|
||||||
super.onExecute(param, options);
|
|
||||||
|
|
||||||
const value = get(this.value)
|
|
||||||
if (value.length > 0) {
|
|
||||||
this.setOutputData(0, value[0].filename) // TODO when ComfyUI LoadImage supports loading an image batch
|
|
||||||
this.setOutputData(1, this.imageSize[0])
|
|
||||||
this.setOutputData(2, this.imageSize[1])
|
|
||||||
this.setOutputData(3, value.length)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
this.setOutputData(0, "")
|
|
||||||
this.setOutputData(1, 1)
|
|
||||||
this.setOutputData(2, 1)
|
|
||||||
this.setOutputData(3, 0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override formatValue(value: GalleryOutputEntry[]): string {
|
override formatValue(value: GalleryOutputEntry[]): string {
|
||||||
return `Images: ${value?.length || 0}`
|
return `Images: ${value?.length || 0}`
|
||||||
}
|
}
|
||||||
@@ -996,13 +996,18 @@ export class ComfyImageEditorNode extends ComfyWidgetNode<GalleryOutputEntry[]>
|
|||||||
{ name: "store", type: BuiltInSlotType.ACTION }
|
{ name: "store", type: BuiltInSlotType.ACTION }
|
||||||
],
|
],
|
||||||
outputs: [
|
outputs: [
|
||||||
|
{ name: "filename", type: "string" }, // TODO support batches
|
||||||
|
{ name: "width", type: "number" },
|
||||||
|
{ name: "height", type: "number" },
|
||||||
|
{ name: "image_count", type: "number" },
|
||||||
|
{ name: "changed", type: BuiltInSlotType.EVENT },
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
override svelteComponentType = ImageEditorWidget;
|
override svelteComponentType = ImageEditorWidget;
|
||||||
override defaultValue: GalleryOutputEntry[] = [];
|
override defaultValue: GalleryOutputEntry[] = [];
|
||||||
override outputIndex = null;
|
override outputIndex = null;
|
||||||
override changedIndex = null;
|
override changedIndex = 4;
|
||||||
override storeActionName = "store";
|
override storeActionName = "store";
|
||||||
override saveUserState = false;
|
override saveUserState = false;
|
||||||
|
|
||||||
@@ -1010,7 +1015,25 @@ export class ComfyImageEditorNode extends ComfyWidgetNode<GalleryOutputEntry[]>
|
|||||||
super(name, [])
|
super(name, [])
|
||||||
}
|
}
|
||||||
|
|
||||||
_value = null;
|
imageSize: Vector2 = [0, 0];
|
||||||
|
|
||||||
|
override onExecute(param: any, options: object) {
|
||||||
|
super.onExecute(param, options);
|
||||||
|
|
||||||
|
const value = get(this.value)
|
||||||
|
if (value.length > 0) {
|
||||||
|
this.setOutputData(0, value[0].filename) // TODO when ComfyUI LoadImage supports loading an image batch
|
||||||
|
this.setOutputData(1, this.imageSize[0])
|
||||||
|
this.setOutputData(2, this.imageSize[1])
|
||||||
|
this.setOutputData(3, value.length)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.setOutputData(0, "")
|
||||||
|
this.setOutputData(1, 0)
|
||||||
|
this.setOutputData(2, 0)
|
||||||
|
this.setOutputData(3, 0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override parseValue(value: any): GalleryOutputEntry[] {
|
override parseValue(value: any): GalleryOutputEntry[] {
|
||||||
if (value == null)
|
if (value == null)
|
||||||
|
|||||||
@@ -18,15 +18,22 @@
|
|||||||
let node: ComfyImageEditorNode | null = null;
|
let node: ComfyImageEditorNode | null = null;
|
||||||
let nodeValue: Writable<GalleryOutputEntry[]> | null = null;
|
let nodeValue: Writable<GalleryOutputEntry[]> | null = null;
|
||||||
let attrsChanged: Writable<number> | null = null;
|
let attrsChanged: Writable<number> | null = null;
|
||||||
let leftUrl: string = ""
|
|
||||||
let rightUrl: string = ""
|
|
||||||
|
|
||||||
let imgElem: HTMLImageElement | null = null
|
|
||||||
let imgWidth: number = 0;
|
let imgWidth: number = 0;
|
||||||
let imgHeight: number = 0;
|
let imgHeight: number = 0;
|
||||||
|
|
||||||
$: widget && setNodeValue(widget);
|
$: widget && setNodeValue(widget);
|
||||||
|
|
||||||
|
$: if (!(node && $nodeValue && $nodeValue.length > 0)) {
|
||||||
|
node.imageSize = [0, 0]
|
||||||
|
}
|
||||||
|
else if (imgWidth > 0 && imgHeight > 0) {
|
||||||
|
node.imageSize = [imgWidth, imgHeight]
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
node.imageSize = [0, 0]
|
||||||
|
}
|
||||||
|
|
||||||
function setNodeValue(widget: WidgetLayout) {
|
function setNodeValue(widget: WidgetLayout) {
|
||||||
if (widget) {
|
if (widget) {
|
||||||
node = widget.node as ComfyImageEditorNode
|
node = widget.node as ComfyImageEditorNode
|
||||||
@@ -224,7 +231,6 @@
|
|||||||
<ImageUpload value={$nodeValue}
|
<ImageUpload value={$nodeValue}
|
||||||
bind:imgWidth
|
bind:imgWidth
|
||||||
bind:imgHeight
|
bind:imgHeight
|
||||||
bind:imgElem
|
|
||||||
fileCount={"single"}
|
fileCount={"single"}
|
||||||
elem_classes={[]}
|
elem_classes={[]}
|
||||||
style={""}
|
style={""}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
import type { WidgetLayout } from "$lib/stores/layoutState";
|
import type { WidgetLayout } from "$lib/stores/layoutState";
|
||||||
import type { Writable } from "svelte/store";
|
import type { Writable } from "svelte/store";
|
||||||
import type { ComfyGalleryNode, ComfyImageUploadNode, GalleryOutputEntry, MultiImageData } from "$lib/nodes/ComfyWidgetNodes";
|
import type { ComfyGalleryNode, ComfyImageUploadNode, GalleryOutputEntry, MultiImageData } from "$lib/nodes/ComfyWidgetNodes";
|
||||||
|
import notify from "$lib/notify";
|
||||||
|
|
||||||
export let widget: WidgetLayout | null = null;
|
export let widget: WidgetLayout | null = null;
|
||||||
export let isMobile: boolean = false;
|
export let isMobile: boolean = false;
|
||||||
@@ -32,11 +33,27 @@
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function onUploading() {
|
||||||
|
console.warn("ONUPLOAD!!!")
|
||||||
|
$nodeValue = []
|
||||||
|
}
|
||||||
|
|
||||||
function onChange(e: CustomEvent<GalleryOutputEntry[]>) {
|
function onChange(e: CustomEvent<GalleryOutputEntry[]>) {
|
||||||
console.warn("ONCHANGE!!!", e.detail)
|
console.warn("ONCHANGE!!!", e.detail)
|
||||||
$nodeValue = e.detail || []
|
$nodeValue = e.detail || []
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function onUploaded(e: CustomEvent<GalleryOutputEntry[]>) {
|
||||||
|
console.warn("ONUPLOADED!!!", e.detail)
|
||||||
|
$nodeValue = e.detail || []
|
||||||
|
}
|
||||||
|
|
||||||
|
function onUploadError(e: CustomEvent<any>) {
|
||||||
|
console.warn("ONUPLOADERRO!!!", e.detail)
|
||||||
|
notify(`Error uploading image to ComfyUI: ${e.detail}`)
|
||||||
|
$nodeValue = []
|
||||||
|
}
|
||||||
|
|
||||||
function onClear(e: CustomEvent<GalleryOutputEntry[]>) {
|
function onClear(e: CustomEvent<GalleryOutputEntry[]>) {
|
||||||
console.warn("ONCLEAR!!!", e.detail)
|
console.warn("ONCLEAR!!!", e.detail)
|
||||||
$nodeValue = []
|
$nodeValue = []
|
||||||
@@ -44,16 +61,19 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="wrapper gradio-file comfy-image-upload" style={widget.attrs.style}>
|
<div class="wrapper gradio-file comfy-image-upload" style={widget.attrs.style}>
|
||||||
{#if widget && node && nodeValue}
|
{#if widget && node}
|
||||||
<ImageUpload value={$nodeValue}
|
<ImageUpload value={$nodeValue || []}
|
||||||
bind:imgWidth
|
bind:imgWidth
|
||||||
bind:imgHeight
|
bind:imgHeight
|
||||||
bind:fileCount={node.properties.fileCount}
|
bind:fileCount={node.properties.fileCount}
|
||||||
elem_classes={widget.attrs.classes.split(",")}
|
elem_classes={widget.attrs.classes.split(",")}
|
||||||
style={widget.attrs.style}
|
style={widget.attrs.style}
|
||||||
label={widget.attrs.title}
|
label={widget.attrs.title}
|
||||||
on:change={onChange}
|
on:uploading={onUploading}
|
||||||
on:clear={onClear}/>
|
on:uploaded={onUploaded}
|
||||||
|
on:upload_error={onUploadError}
|
||||||
|
on:clear={onClear}
|
||||||
|
on:change={onChange}/>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user