From 88b6f37333f2d8eff52706d588d9bd3866427719 Mon Sep 17 00:00:00 2001 From: Jennifer Player Date: Thu, 4 Apr 2024 10:54:02 -0400 Subject: [PATCH 1/7] added initial image to metadata viewer --- .../components/ImageMetadataViewer/ImageMetadataActions.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/invokeai/frontend/web/src/features/gallery/components/ImageMetadataViewer/ImageMetadataActions.tsx b/invokeai/frontend/web/src/features/gallery/components/ImageMetadataViewer/ImageMetadataActions.tsx index 5b9f15c21ad..ce75ea62e02 100644 --- a/invokeai/frontend/web/src/features/gallery/components/ImageMetadataViewer/ImageMetadataActions.tsx +++ b/invokeai/frontend/web/src/features/gallery/components/ImageMetadataViewer/ImageMetadataActions.tsx @@ -33,6 +33,7 @@ const ImageMetadataActions = (props: Props) => { + From a224c6a5af02c6cbecd77b3cb31200c4ecd108a1 Mon Sep 17 00:00:00 2001 From: Jennifer Player Date: Thu, 4 Apr 2024 10:56:25 -0400 Subject: [PATCH 2/7] recall initial image from metadata and set to image2image --- .../web/src/features/metadata/util/handlers.ts | 5 +++++ .../web/src/features/metadata/util/parsers.ts | 5 +++++ .../web/src/features/metadata/util/recallers.ts | 11 +++++++++++ .../src/features/parameters/types/parameterSchemas.ts | 7 +++++++ 4 files changed, 28 insertions(+) diff --git a/invokeai/frontend/web/src/features/metadata/util/handlers.ts b/invokeai/frontend/web/src/features/metadata/util/handlers.ts index b64426b4222..4bf717f6388 100644 --- a/invokeai/frontend/web/src/features/metadata/util/handlers.ts +++ b/invokeai/frontend/web/src/features/metadata/util/handlers.ts @@ -189,6 +189,11 @@ export const handlers = { recaller: recallers.cfgScale, }), height: buildHandlers({ getLabel: () => t('metadata.height'), parser: parsers.height, recaller: recallers.height }), + initialImage: buildHandlers({ + getLabel: () => t('metadata.initImage'), + parser: parsers.initialImage, + recaller: recallers.initialImage, + }), negativePrompt: buildHandlers({ getLabel: () => t('metadata.negativePrompt'), parser: parsers.negativePrompt, diff --git a/invokeai/frontend/web/src/features/metadata/util/parsers.ts b/invokeai/frontend/web/src/features/metadata/util/parsers.ts index 635a63a8dec..26a0c3c5b1c 100644 --- a/invokeai/frontend/web/src/features/metadata/util/parsers.ts +++ b/invokeai/frontend/web/src/features/metadata/util/parsers.ts @@ -20,6 +20,7 @@ import type { ParameterHeight, ParameterHRFEnabled, ParameterHRFMethod, + ParameterInitialImage, ParameterModel, ParameterNegativePrompt, ParameterNegativeStylePromptSDXL, @@ -135,6 +136,9 @@ const parseCFGRescaleMultiplier: MetadataParseFunc = (metadata) => getProperty(metadata, 'scheduler', isParameterScheduler); +const parseInitialImage: MetadataParseFunc = (metadata) => + getProperty(metadata, 'init_image', isString); + const parseWidth: MetadataParseFunc = (metadata) => getProperty(metadata, 'width', isParameterWidth); const parseHeight: MetadataParseFunc = (metadata) => @@ -402,6 +406,7 @@ export const parsers = { cfgScale: parseCFGScale, cfgRescaleMultiplier: parseCFGRescaleMultiplier, scheduler: parseScheduler, + initialImage: parseInitialImage, width: parseWidth, height: parseHeight, steps: parseSteps, diff --git a/invokeai/frontend/web/src/features/metadata/util/recallers.ts b/invokeai/frontend/web/src/features/metadata/util/recallers.ts index f35399c1392..617e5b23773 100644 --- a/invokeai/frontend/web/src/features/metadata/util/recallers.ts +++ b/invokeai/frontend/web/src/features/metadata/util/recallers.ts @@ -17,6 +17,7 @@ import type { import { modelSelected } from 'features/parameters/store/actions'; import { heightRecalled, + initialImageChanged, setCfgRescaleMultiplier, setCfgScale, setImg2imgStrength, @@ -34,6 +35,7 @@ import type { ParameterHeight, ParameterHRFEnabled, ParameterHRFMethod, + ParameterInitialImage, ParameterModel, ParameterNegativePrompt, ParameterNegativeStylePromptSDXL, @@ -61,6 +63,7 @@ import { setRefinerStart, setRefinerSteps, } from 'features/sdxl/store/sdxlSlice'; +import type { ImageDTO } from 'services/api/types'; const recallPositivePrompt: MetadataRecallFunc = (positivePrompt) => { getStore().dispatch(setPositivePrompt(positivePrompt)); @@ -94,6 +97,13 @@ const recallScheduler: MetadataRecallFunc = (scheduler) => { getStore().dispatch(setScheduler(scheduler)); }; +const recallInitialImage: MetadataRecallFunc = (initialImage) => { + const image = { + image_name: initialImage, + }; + getStore().dispatch(initialImageChanged(image as ImageDTO)); +}; + const recallWidth: MetadataRecallFunc = (width) => { getStore().dispatch(widthRecalled(width)); }; @@ -235,6 +245,7 @@ export const recallers = { cfgScale: recallCFGScale, cfgRescaleMultiplier: recallCFGRescaleMultiplier, scheduler: recallScheduler, + initialImage: recallInitialImage, width: recallWidth, height: recallHeight, steps: recallSteps, diff --git a/invokeai/frontend/web/src/features/parameters/types/parameterSchemas.ts b/invokeai/frontend/web/src/features/parameters/types/parameterSchemas.ts index 75693cd47fa..b3c403488a2 100644 --- a/invokeai/frontend/web/src/features/parameters/types/parameterSchemas.ts +++ b/invokeai/frontend/web/src/features/parameters/types/parameterSchemas.ts @@ -126,6 +126,13 @@ const zParameterT2IAdapterModel = zModelIdentifierField; export type ParameterT2IAdapterModel = z.infer; // #endregion +// #region I2I Initial Image +const zParameterInitialImage = z.string(); +export type ParameterInitialImage = z.infer; +export const isParameterInitialImage = (val: unknown): val is ParameterInitialImage => + zParameterInitialImage.safeParse(val).success; +// #endregion + // #region Strength (l2l strength) const zParameterStrength = z.number().min(0).max(1); export type ParameterStrength = z.infer; From d31f0f8ffa7ffd941abb5d4af21ea23210e931c4 Mon Sep 17 00:00:00 2001 From: Jennifer Player Date: Thu, 4 Apr 2024 10:56:54 -0400 Subject: [PATCH 3/7] fix typo Params set set --- invokeai/frontend/web/public/locales/en.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/invokeai/frontend/web/public/locales/en.json b/invokeai/frontend/web/public/locales/en.json index 623cea64ee0..e2ef66b9de4 100644 --- a/invokeai/frontend/web/public/locales/en.json +++ b/invokeai/frontend/web/public/locales/en.json @@ -1044,7 +1044,7 @@ "parameterNotSet": "{{parameter}} not set", "parameterSet": "{{parameter}} set", "parametersNotSet": "Parameters Not Set", - "parametersSet": "Parameters Set", + "parametersSet": "Parameters", "problemCopyingCanvas": "Problem Copying Canvas", "problemCopyingCanvasDesc": "Unable to export base layer", "problemCopyingImage": "Unable to Copy Image", From 8b7c74fb3789edaec121d92d51f5f29e29a60f6e Mon Sep 17 00:00:00 2001 From: Jennifer Player Date: Thu, 4 Apr 2024 11:06:30 -0400 Subject: [PATCH 4/7] actually use the schema --- invokeai/frontend/web/src/features/metadata/util/parsers.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/invokeai/frontend/web/src/features/metadata/util/parsers.ts b/invokeai/frontend/web/src/features/metadata/util/parsers.ts index 26a0c3c5b1c..5d844c46637 100644 --- a/invokeai/frontend/web/src/features/metadata/util/parsers.ts +++ b/invokeai/frontend/web/src/features/metadata/util/parsers.ts @@ -43,6 +43,7 @@ import { isParameterHeight, isParameterHRFEnabled, isParameterHRFMethod, + isParameterInitialImage, isParameterLoRAWeight, isParameterNegativePrompt, isParameterNegativeStylePromptSDXL, @@ -137,7 +138,7 @@ const parseScheduler: MetadataParseFunc = (metadata) => getProperty(metadata, 'scheduler', isParameterScheduler); const parseInitialImage: MetadataParseFunc = (metadata) => - getProperty(metadata, 'init_image', isString); + getProperty(metadata, 'init_image', isParameterInitialImage); const parseWidth: MetadataParseFunc = (metadata) => getProperty(metadata, 'width', isParameterWidth); From c3c6ff60316725cd500d640358ab896457673519 Mon Sep 17 00:00:00 2001 From: Jennifer Player Date: Fri, 5 Apr 2024 13:30:31 -0400 Subject: [PATCH 5/7] addressed pr feedback --- invokeai/frontend/web/public/locales/en.json | 2 +- .../web/src/features/metadata/util/handlers.ts | 2 +- .../web/src/features/metadata/util/recallers.ts | 12 ++++++------ 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/invokeai/frontend/web/public/locales/en.json b/invokeai/frontend/web/public/locales/en.json index e2ef66b9de4..9686f8a02a6 100644 --- a/invokeai/frontend/web/public/locales/en.json +++ b/invokeai/frontend/web/public/locales/en.json @@ -1041,10 +1041,10 @@ "metadataLoadFailed": "Failed to load metadata", "modelAddedSimple": "Model Added to Queue", "modelImportCanceled": "Model Import Canceled", + "parameters": "Parameters", "parameterNotSet": "{{parameter}} not set", "parameterSet": "{{parameter}} set", "parametersNotSet": "Parameters Not Set", - "parametersSet": "Parameters", "problemCopyingCanvas": "Problem Copying Canvas", "problemCopyingCanvasDesc": "Unable to export base layer", "problemCopyingImage": "Unable to Copy Image", diff --git a/invokeai/frontend/web/src/features/metadata/util/handlers.ts b/invokeai/frontend/web/src/features/metadata/util/handlers.ts index 4bf717f6388..af089a3177a 100644 --- a/invokeai/frontend/web/src/features/metadata/util/handlers.ts +++ b/invokeai/frontend/web/src/features/metadata/util/handlers.ts @@ -410,6 +410,6 @@ export const parseAndRecallAllMetadata = async (metadata: unknown, skip: (keyof }) ); if (results.some((result) => result.status === 'fulfilled')) { - parameterSetToast(t('toast.parametersSet')); + parameterSetToast(t('toast.parameters')); } }; diff --git a/invokeai/frontend/web/src/features/metadata/util/recallers.ts b/invokeai/frontend/web/src/features/metadata/util/recallers.ts index 617e5b23773..50d814b859d 100644 --- a/invokeai/frontend/web/src/features/metadata/util/recallers.ts +++ b/invokeai/frontend/web/src/features/metadata/util/recallers.ts @@ -63,7 +63,7 @@ import { setRefinerStart, setRefinerSteps, } from 'features/sdxl/store/sdxlSlice'; -import type { ImageDTO } from 'services/api/types'; +import { imagesApi } from 'services/api/endpoints/images'; const recallPositivePrompt: MetadataRecallFunc = (positivePrompt) => { getStore().dispatch(setPositivePrompt(positivePrompt)); @@ -97,11 +97,11 @@ const recallScheduler: MetadataRecallFunc = (scheduler) => { getStore().dispatch(setScheduler(scheduler)); }; -const recallInitialImage: MetadataRecallFunc = (initialImage) => { - const image = { - image_name: initialImage, - }; - getStore().dispatch(initialImageChanged(image as ImageDTO)); +const recallInitialImage: MetadataRecallFunc = async (initialImage) => { + const imageDTORequest = getStore().dispatch(imagesApi.endpoints.getImageDTO.initiate(initialImage)); + const imageDTO = await imageDTORequest.unwrap(); + imageDTORequest.unsubscribe(); + getStore().dispatch(initialImageChanged(imageDTO)); }; const recallWidth: MetadataRecallFunc = (width) => { From 3616470f7b04587f2b7ae989e3a12d533a47f646 Mon Sep 17 00:00:00 2001 From: psychedelicious <4822129+psychedelicious@users.noreply.github.com> Date: Sat, 6 Apr 2024 14:47:24 +1100 Subject: [PATCH 6/7] feat(ui): shift around init image recall logic Retrieving the DTO happens as part of the metadata parsing, not recall. This way, we don't show the option to recall a nonexistent image. This matches the flow for other metadata entities like models - we don't show the model recall button if the model isn't available. --- .../web/src/features/metadata/util/handlers.ts | 1 + .../web/src/features/metadata/util/parsers.ts | 13 ++++++++++--- .../web/src/features/metadata/util/recallers.ts | 8 ++------ 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/invokeai/frontend/web/src/features/metadata/util/handlers.ts b/invokeai/frontend/web/src/features/metadata/util/handlers.ts index af089a3177a..2fb840afcbe 100644 --- a/invokeai/frontend/web/src/features/metadata/util/handlers.ts +++ b/invokeai/frontend/web/src/features/metadata/util/handlers.ts @@ -193,6 +193,7 @@ export const handlers = { getLabel: () => t('metadata.initImage'), parser: parsers.initialImage, recaller: recallers.initialImage, + renderValue: async (imageDTO) => imageDTO.image_name, }), negativePrompt: buildHandlers({ getLabel: () => t('metadata.negativePrompt'), diff --git a/invokeai/frontend/web/src/features/metadata/util/parsers.ts b/invokeai/frontend/web/src/features/metadata/util/parsers.ts index 5d844c46637..55a170745d0 100644 --- a/invokeai/frontend/web/src/features/metadata/util/parsers.ts +++ b/invokeai/frontend/web/src/features/metadata/util/parsers.ts @@ -1,3 +1,4 @@ +import { getStore } from 'app/store/nanostores/store'; import { initialControlNet, initialIPAdapter, @@ -20,7 +21,6 @@ import type { ParameterHeight, ParameterHRFEnabled, ParameterHRFMethod, - ParameterInitialImage, ParameterModel, ParameterNegativePrompt, ParameterNegativeStylePromptSDXL, @@ -59,6 +59,8 @@ import { isParameterWidth, } from 'features/parameters/types/parameterSchemas'; import { get, isArray, isString } from 'lodash-es'; +import { imagesApi } from 'services/api/endpoints/images'; +import type { ImageDTO } from 'services/api/types'; import { isControlNetModelConfig, isIPAdapterModelConfig, @@ -137,8 +139,13 @@ const parseCFGRescaleMultiplier: MetadataParseFunc = (metadata) => getProperty(metadata, 'scheduler', isParameterScheduler); -const parseInitialImage: MetadataParseFunc = (metadata) => - getProperty(metadata, 'init_image', isParameterInitialImage); +const parseInitialImage: MetadataParseFunc = async (metadata) => { + const imageName = await getProperty(metadata, 'init_image', isParameterInitialImage); + const imageDTORequest = getStore().dispatch(imagesApi.endpoints.getImageDTO.initiate(imageName)); + const imageDTO = await imageDTORequest.unwrap(); + imageDTORequest.unsubscribe(); + return imageDTO; +}; const parseWidth: MetadataParseFunc = (metadata) => getProperty(metadata, 'width', isParameterWidth); diff --git a/invokeai/frontend/web/src/features/metadata/util/recallers.ts b/invokeai/frontend/web/src/features/metadata/util/recallers.ts index 50d814b859d..88af390a20a 100644 --- a/invokeai/frontend/web/src/features/metadata/util/recallers.ts +++ b/invokeai/frontend/web/src/features/metadata/util/recallers.ts @@ -35,7 +35,6 @@ import type { ParameterHeight, ParameterHRFEnabled, ParameterHRFMethod, - ParameterInitialImage, ParameterModel, ParameterNegativePrompt, ParameterNegativeStylePromptSDXL, @@ -63,7 +62,7 @@ import { setRefinerStart, setRefinerSteps, } from 'features/sdxl/store/sdxlSlice'; -import { imagesApi } from 'services/api/endpoints/images'; +import type { ImageDTO } from 'services/api/types'; const recallPositivePrompt: MetadataRecallFunc = (positivePrompt) => { getStore().dispatch(setPositivePrompt(positivePrompt)); @@ -97,10 +96,7 @@ const recallScheduler: MetadataRecallFunc = (scheduler) => { getStore().dispatch(setScheduler(scheduler)); }; -const recallInitialImage: MetadataRecallFunc = async (initialImage) => { - const imageDTORequest = getStore().dispatch(imagesApi.endpoints.getImageDTO.initiate(initialImage)); - const imageDTO = await imageDTORequest.unwrap(); - imageDTORequest.unsubscribe(); +const recallInitialImage: MetadataRecallFunc = async (imageDTO) => { getStore().dispatch(initialImageChanged(imageDTO)); }; From eecb08871a4135ee72746cefe0f502d4d0ccd1b4 Mon Sep 17 00:00:00 2001 From: psychedelicious <4822129+psychedelicious@users.noreply.github.com> Date: Sat, 6 Apr 2024 14:48:51 +1100 Subject: [PATCH 7/7] tidy(ui): remove extraneous zod schema --- .../frontend/web/src/features/metadata/util/parsers.ts | 3 +-- .../web/src/features/parameters/types/parameterSchemas.ts | 7 ------- 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/invokeai/frontend/web/src/features/metadata/util/parsers.ts b/invokeai/frontend/web/src/features/metadata/util/parsers.ts index 55a170745d0..9f5c14d94eb 100644 --- a/invokeai/frontend/web/src/features/metadata/util/parsers.ts +++ b/invokeai/frontend/web/src/features/metadata/util/parsers.ts @@ -43,7 +43,6 @@ import { isParameterHeight, isParameterHRFEnabled, isParameterHRFMethod, - isParameterInitialImage, isParameterLoRAWeight, isParameterNegativePrompt, isParameterNegativeStylePromptSDXL, @@ -140,7 +139,7 @@ const parseScheduler: MetadataParseFunc = (metadata) => getProperty(metadata, 'scheduler', isParameterScheduler); const parseInitialImage: MetadataParseFunc = async (metadata) => { - const imageName = await getProperty(metadata, 'init_image', isParameterInitialImage); + const imageName = await getProperty(metadata, 'init_image', isString); const imageDTORequest = getStore().dispatch(imagesApi.endpoints.getImageDTO.initiate(imageName)); const imageDTO = await imageDTORequest.unwrap(); imageDTORequest.unsubscribe(); diff --git a/invokeai/frontend/web/src/features/parameters/types/parameterSchemas.ts b/invokeai/frontend/web/src/features/parameters/types/parameterSchemas.ts index b3c403488a2..75693cd47fa 100644 --- a/invokeai/frontend/web/src/features/parameters/types/parameterSchemas.ts +++ b/invokeai/frontend/web/src/features/parameters/types/parameterSchemas.ts @@ -126,13 +126,6 @@ const zParameterT2IAdapterModel = zModelIdentifierField; export type ParameterT2IAdapterModel = z.infer; // #endregion -// #region I2I Initial Image -const zParameterInitialImage = z.string(); -export type ParameterInitialImage = z.infer; -export const isParameterInitialImage = (val: unknown): val is ParameterInitialImage => - zParameterInitialImage.safeParse(val).success; -// #endregion - // #region Strength (l2l strength) const zParameterStrength = z.number().min(0).max(1); export type ParameterStrength = z.infer;