feat: add ComfyUI integration for image generation and management
- Implemented ComfyGenerateRequest type and associated functions for generating images using various architectures and modes. - Added functions for listing generation options and handling image uploads. - Created workflows for different generation modes including SDXL, Z-Image, Z-Image Turbo, and Anima. - Introduced GenerationJobStatus component to display the status of ongoing generation jobs. - Developed MaskControls for managing mask operations and displaying mask analysis. - Created palette items for tool selection, layer management, and generation settings.
This commit is contained in:
@@ -1,57 +1,15 @@
|
||||
import { useCallback, useEffect, useRef } from "react";
|
||||
import { commandIds } from "@commands/ids";
|
||||
import type { AppStore } from "@editor/store";
|
||||
import { importImageAsLayer } from "@operations/import/importImage";
|
||||
import { decodeBrowserImageFile } from "@platform/browser/imageFiles";
|
||||
|
||||
export function useImageImport(store: AppStore) {
|
||||
const inputRef = useRef<HTMLInputElement | null>(null);
|
||||
|
||||
const importFile = useCallback(
|
||||
async (file: File) => {
|
||||
if (!file.type.startsWith("image/")) return;
|
||||
|
||||
const source = URL.createObjectURL(file);
|
||||
const intrinsicSize = await loadImageSize(source);
|
||||
const state = store.getState();
|
||||
const artboard = state.editor.selection.artboardId
|
||||
? state.document.artboards.find((candidate) => candidate.id === state.editor.selection.artboardId)
|
||||
: state.document.artboards[0];
|
||||
|
||||
if (!artboard) {
|
||||
URL.revokeObjectURL(source);
|
||||
return;
|
||||
}
|
||||
|
||||
const assetId = crypto.randomUUID();
|
||||
const layerId = crypto.randomUUID();
|
||||
const center = state.editor.viewport.center;
|
||||
|
||||
store.dispatch(commandIds.documentAddAsset, {
|
||||
asset: {
|
||||
id: assetId,
|
||||
name: file.name,
|
||||
mimeType: file.type,
|
||||
source,
|
||||
intrinsicSize,
|
||||
},
|
||||
});
|
||||
store.dispatch(commandIds.documentAddImageLayer, {
|
||||
artboardId: artboard.id,
|
||||
layer: {
|
||||
id: layerId,
|
||||
type: "image",
|
||||
name: file.name,
|
||||
visible: true,
|
||||
locked: false,
|
||||
opacity: 1,
|
||||
assetId,
|
||||
transform: {
|
||||
position: { x: center.x - intrinsicSize.w / 2, y: center.y - intrinsicSize.h / 2 },
|
||||
scale: { x: 1, y: 1 },
|
||||
rotation: 0,
|
||||
},
|
||||
},
|
||||
});
|
||||
store.dispatch(commandIds.selectionSet, { artboardId: artboard.id, layerIds: [layerId] });
|
||||
const image = await decodeBrowserImageFile(file);
|
||||
if (image) importImageAsLayer(store, image);
|
||||
},
|
||||
[store],
|
||||
);
|
||||
@@ -97,12 +55,3 @@ export function useImageImport(store: AppStore) {
|
||||
|
||||
return { input, openFilePicker, importFile };
|
||||
}
|
||||
|
||||
function loadImageSize(source: string): Promise<{ w: number; h: number }> {
|
||||
return new Promise((resolve, reject) => {
|
||||
const image = new Image();
|
||||
image.onload = () => resolve({ w: image.naturalWidth, h: image.naturalHeight });
|
||||
image.onerror = () => reject(new Error("Failed to load image"));
|
||||
image.src = source;
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user