diff --git a/invokeai/app/invocations/metadata.py b/invokeai/app/invocations/metadata.py index 6ca3be7794..ed8a091f8d 100644 --- a/invokeai/app/invocations/metadata.py +++ b/invokeai/app/invocations/metadata.py @@ -160,13 +160,14 @@ class CoreMetadataInvocation(BaseInvocation): ) # High resolution fix metadata. - hrf_width: Optional[int] = InputField( + hrf_enabled: Optional[float] = InputField( default=None, - description="The high resolution fix height and width multipler.", + description="Whether or not high resolution fix was enabled.", ) - hrf_height: Optional[int] = InputField( + # TODO: should this be stricter or do we just let the UI handle it? + hrf_method: Optional[str] = InputField( default=None, - description="The high resolution fix height and width multipler.", + description="The high resolution fix upscale method.", ) hrf_strength: Optional[float] = InputField( default=None, diff --git a/invokeai/frontend/web/public/locales/en.json b/invokeai/frontend/web/public/locales/en.json index 564ed174a8..e06804772b 100644 --- a/invokeai/frontend/web/public/locales/en.json +++ b/invokeai/frontend/web/public/locales/en.json @@ -221,6 +221,19 @@ "resetIPAdapterImage": "Reset IP Adapter Image", "ipAdapterImageFallback": "No IP Adapter Image Selected" }, + "hrf": { + "hrf": "High Resolution Fix", + "enableHrf": "Enable High Resolution Fix", + "enableHrfTooltip": "Generate with a lower initial resolution, upscale to the base resolution, then run Image-to-Image.", + "upscaleMethod": "Upscale Method", + "hrfStrength": "High Resolution Fix Strength", + "strengthTooltip": "Lower values result in fewer details, which may reduce potential artifacts.", + "metadata": { + "enabled": "High Resolution Fix Enabled", + "strength": "High Resolution Fix Strength", + "method": "High Resolution Fix Method" + } + }, "embedding": { "addEmbedding": "Add Embedding", "incompatibleModel": "Incompatible base model:", @@ -1258,15 +1271,11 @@ }, "compositingBlur": { "heading": "Blur", - "paragraphs": [ - "The blur radius of the mask." - ] + "paragraphs": ["The blur radius of the mask."] }, "compositingBlurMethod": { "heading": "Blur Method", - "paragraphs": [ - "The method of blur applied to the masked area." - ] + "paragraphs": ["The method of blur applied to the masked area."] }, "compositingCoherencePass": { "heading": "Coherence Pass", @@ -1276,9 +1285,7 @@ }, "compositingCoherenceMode": { "heading": "Mode", - "paragraphs": [ - "The mode of the Coherence Pass." - ] + "paragraphs": ["The mode of the Coherence Pass."] }, "compositingCoherenceSteps": { "heading": "Steps", @@ -1296,9 +1303,7 @@ }, "compositingMaskAdjustments": { "heading": "Mask Adjustments", - "paragraphs": [ - "Adjust the mask." - ] + "paragraphs": ["Adjust the mask."] }, "controlNetBeginEnd": { "heading": "Begin / End Step Percentage", @@ -1356,9 +1361,7 @@ }, "infillMethod": { "heading": "Infill Method", - "paragraphs": [ - "Method to infill the selected area." - ] + "paragraphs": ["Method to infill the selected area."] }, "lora": { "heading": "LoRA Weight", 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 4d7c6f21c0..4e4531d268 100644 --- a/invokeai/frontend/web/src/features/gallery/components/ImageMetadataViewer/ImageMetadataActions.tsx +++ b/invokeai/frontend/web/src/features/gallery/components/ImageMetadataViewer/ImageMetadataActions.tsx @@ -35,6 +35,9 @@ const ImageMetadataActions = (props: Props) => { recallWidth, recallHeight, recallStrength, + recallHrfEnabled, + recallHrfStrength, + recallHrfMethod, recallLoRA, recallControlNet, recallIPAdapter, @@ -81,6 +84,18 @@ const ImageMetadataActions = (props: Props) => { recallStrength(metadata?.strength); }, [metadata?.strength, recallStrength]); + const handleRecallHrfEnabled = useCallback(() => { + recallHrfEnabled(metadata?.hrf_enabled); + }, [metadata?.hrf_enabled, recallHrfEnabled]); + + const handleRecallHrfStrength = useCallback(() => { + recallHrfStrength(metadata?.hrf_strength); + }, [metadata?.hrf_strength, recallHrfStrength]); + + const handleRecallHrfMethod = useCallback(() => { + recallHrfMethod(metadata?.hrf_method); + }, [metadata?.hrf_method, recallHrfMethod]); + const handleRecallLoRA = useCallback( (lora: LoRAMetadataItem) => { recallLoRA(lora); @@ -225,6 +240,27 @@ const ImageMetadataActions = (props: Props) => { onClick={handleRecallStrength} /> )} + {metadata.hrf_enabled && ( + + )} + {metadata.hrf_enabled && metadata.hrf_strength && ( + + )} + {metadata.hrf_enabled && metadata.hrf_method && ( + + )} {metadata.loras && metadata.loras.map((lora, index) => { if (isValidLoRAModel(lora.lora)) { diff --git a/invokeai/frontend/web/src/features/nodes/types/types.ts b/invokeai/frontend/web/src/features/nodes/types/types.ts index ba1ca05c4d..c55d114dcf 100644 --- a/invokeai/frontend/web/src/features/nodes/types/types.ts +++ b/invokeai/frontend/web/src/features/nodes/types/types.ts @@ -1424,6 +1424,9 @@ export const zCoreMetadata = z loras: z.array(zLoRAMetadataItem).nullish().catch(null), vae: zVaeModelField.nullish().catch(null), strength: z.number().nullish().catch(null), + hrf_enabled: z.boolean().nullish().catch(null), + hrf_strength: z.number().nullish().catch(null), + hrf_method: z.string().nullish().catch(null), init_image: z.string().nullish().catch(null), positive_style_prompt: z.string().nullish().catch(null), negative_style_prompt: z.string().nullish().catch(null), diff --git a/invokeai/frontend/web/src/features/nodes/util/graphBuilders/addHrfToGraph.ts b/invokeai/frontend/web/src/features/nodes/util/graphBuilders/addHrfToGraph.ts index 8c23ae667e..d1df9bb9c2 100644 --- a/invokeai/frontend/web/src/features/nodes/util/graphBuilders/addHrfToGraph.ts +++ b/invokeai/frontend/web/src/features/nodes/util/graphBuilders/addHrfToGraph.ts @@ -1,22 +1,26 @@ import { logger } from 'app/logging/logger'; import { RootState } from 'app/store/store'; +import { roundToMultiple } from 'common/util/roundDownToMultiple'; import { NonNullableGraph } from 'features/nodes/types/types'; import { DenoiseLatentsInvocation, + ESRGANInvocation, Edge, LatentsToImageInvocation, NoiseInvocation, - ResizeLatentsInvocation, } from 'services/api/types'; import { DENOISE_LATENTS, DENOISE_LATENTS_HRF, + ESRGAN_HRF, + IMAGE_TO_LATENTS_HRF, LATENTS_TO_IMAGE, - LATENTS_TO_IMAGE_HRF, + LATENTS_TO_IMAGE_HRF_HR, + LATENTS_TO_IMAGE_HRF_LR, MAIN_MODEL_LOADER, NOISE, NOISE_HRF, - RESCALE_LATENTS, + RESIZE_HRF, VAE_LOADER, } from './constants'; import { upsertMetadata } from './metadata'; @@ -56,6 +60,52 @@ function copyConnectionsToDenoiseLatentsHrf(graph: NonNullableGraph): void { graph.edges = graph.edges.concat(newEdges); } +/** + * Calculates the new resolution for high-resolution features (HRF) based on base model type. + * Adjusts the width and height to maintain the aspect ratio and constrains them by the model's dimension limits, + * rounding down to the nearest multiple of 8. + * + * @param {string} baseModel The base model type, which determines the base dimension used in calculations. + * @param {number} width The current width to be adjusted for HRF. + * @param {number} height The current height to be adjusted for HRF. + * @return {{newWidth: number, newHeight: number}} The new width and height, adjusted and rounded as needed. + */ +function calculateHrfRes( + baseModel: string, + width: number, + height: number +): { newWidth: number; newHeight: number } { + const aspect = width / height; + let dimension; + if (baseModel == 'sdxl') { + dimension = 1024; + } else { + dimension = 512; + } + + const minDimension = Math.floor(dimension * 0.5); + const modelArea = dimension * dimension; // Assuming square images for model_area + + let initWidth; + let initHeight; + + if (aspect > 1.0) { + initHeight = Math.max(minDimension, Math.sqrt(modelArea / aspect)); + initWidth = initHeight * aspect; + } else { + initWidth = Math.max(minDimension, Math.sqrt(modelArea * aspect)); + initHeight = initWidth / aspect; + } + // Cap initial height and width to final height and width. + initWidth = Math.min(width, initWidth); + initHeight = Math.min(height, initHeight); + + const newWidth = roundToMultiple(Math.floor(initWidth), 8); + const newHeight = roundToMultiple(Math.floor(initHeight), 8); + + return { newWidth, newHeight }; +} + // Adds the high-res fix feature to the given graph. export const addHrfToGraph = ( state: RootState, @@ -71,151 +121,61 @@ export const addHrfToGraph = ( } const log = logger('txt2img'); - const { vae, hrfWidth, hrfHeight, hrfStrength } = state.generation; + const { vae, hrfStrength, hrfEnabled, hrfMethod } = state.generation; const isAutoVae = !vae; + const width = state.generation.width; + const height = state.generation.height; + const baseModel = state.generation.model + ? state.generation.model.base_model + : 'sd1'; + const { newWidth: hrfWidth, newHeight: hrfHeight } = calculateHrfRes( + baseModel, + width, + height + ); // Pre-existing (original) graph nodes. const originalDenoiseLatentsNode = graph.nodes[DENOISE_LATENTS] as | DenoiseLatentsInvocation | undefined; const originalNoiseNode = graph.nodes[NOISE] as NoiseInvocation | undefined; - // Original latents to image should pick this up. const originalLatentsToImageNode = graph.nodes[LATENTS_TO_IMAGE] as | LatentsToImageInvocation | undefined; - // Check if originalDenoiseLatentsNode is undefined and log an error if (!originalDenoiseLatentsNode) { log.error('originalDenoiseLatentsNode is undefined'); return; } - // Check if originalNoiseNode is undefined and log an error if (!originalNoiseNode) { log.error('originalNoiseNode is undefined'); return; } - - // Check if originalLatentsToImageNode is undefined and log an error if (!originalLatentsToImageNode) { log.error('originalLatentsToImageNode is undefined'); return; } + // Change height and width of original noise node to initial resolution. if (originalNoiseNode) { originalNoiseNode.width = hrfWidth; originalNoiseNode.height = hrfHeight; } - // Define new nodes. - // Denoise latents node to be run on upscaled latents. - const denoiseLatentsHrfNode: DenoiseLatentsInvocation = { - type: 'denoise_latents', - id: DENOISE_LATENTS_HRF, - is_intermediate: originalDenoiseLatentsNode?.is_intermediate, - cfg_scale: originalDenoiseLatentsNode?.cfg_scale, - scheduler: originalDenoiseLatentsNode?.scheduler, - steps: originalDenoiseLatentsNode?.steps, - denoising_start: 1 - hrfStrength, - denoising_end: 1, + // Define new nodes and their connections, roughly in order of operations. + graph.nodes[LATENTS_TO_IMAGE_HRF_LR] = { + type: 'l2i', + id: LATENTS_TO_IMAGE_HRF_LR, + fp32: originalLatentsToImageNode?.fp32, + is_intermediate: true, }; - - // New base resolution noise node. - const hrfNoiseNode: NoiseInvocation = { - type: 'noise', - id: NOISE_HRF, - seed: originalNoiseNode?.seed, - use_cpu: originalNoiseNode?.use_cpu, - is_intermediate: originalNoiseNode?.is_intermediate, - }; - - const rescaleLatentsNode: ResizeLatentsInvocation = { - id: RESCALE_LATENTS, - type: 'lresize', - width: state.generation.width, - height: state.generation.height, - }; - - // New node to convert latents to image. - const latentsToImageHrfNode: LatentsToImageInvocation | undefined = - originalLatentsToImageNode - ? { - type: 'l2i', - id: LATENTS_TO_IMAGE_HRF, - fp32: originalLatentsToImageNode?.fp32, - is_intermediate: originalLatentsToImageNode?.is_intermediate, - } - : undefined; - - // Add new nodes to graph. - graph.nodes[LATENTS_TO_IMAGE_HRF] = - latentsToImageHrfNode as LatentsToImageInvocation; - graph.nodes[DENOISE_LATENTS_HRF] = - denoiseLatentsHrfNode as DenoiseLatentsInvocation; - graph.nodes[NOISE_HRF] = hrfNoiseNode as NoiseInvocation; - graph.nodes[RESCALE_LATENTS] = rescaleLatentsNode as ResizeLatentsInvocation; - - // Connect nodes. graph.edges.push( { - // Set up rescale latents. source: { node_id: DENOISE_LATENTS, field: 'latents', }, destination: { - node_id: RESCALE_LATENTS, - field: 'latents', - }, - }, - // Set up new noise node - { - source: { - node_id: RESCALE_LATENTS, - field: 'height', - }, - destination: { - node_id: NOISE_HRF, - field: 'height', - }, - }, - { - source: { - node_id: RESCALE_LATENTS, - field: 'width', - }, - destination: { - node_id: NOISE_HRF, - field: 'width', - }, - }, - // Set up new denoise node. - { - source: { - node_id: RESCALE_LATENTS, - field: 'latents', - }, - destination: { - node_id: DENOISE_LATENTS_HRF, - field: 'latents', - }, - }, - { - source: { - node_id: NOISE_HRF, - field: 'noise', - }, - destination: { - node_id: DENOISE_LATENTS_HRF, - field: 'noise', - }, - }, - // Set up new latents to image node. - { - source: { - node_id: DENOISE_LATENTS_HRF, - field: 'latents', - }, - destination: { - node_id: LATENTS_TO_IMAGE_HRF, + node_id: LATENTS_TO_IMAGE_HRF_LR, field: 'latents', }, }, @@ -225,17 +185,188 @@ export const addHrfToGraph = ( field: 'vae', }, destination: { - node_id: LATENTS_TO_IMAGE_HRF, + node_id: LATENTS_TO_IMAGE_HRF_LR, field: 'vae', }, } ); - upsertMetadata(graph, { - hrf_height: hrfHeight, - hrf_width: hrfWidth, - hrf_strength: hrfStrength, - }); + graph.nodes[RESIZE_HRF] = { + id: RESIZE_HRF, + type: 'img_resize', + is_intermediate: true, + width: width, + height: height, + }; + if (hrfMethod == 'ESRGAN') { + let model_name: ESRGANInvocation['model_name'] = 'RealESRGAN_x2plus.pth'; + if ((width * height) / (hrfWidth * hrfHeight) > 2) { + model_name = 'RealESRGAN_x4plus.pth'; + } + graph.nodes[ESRGAN_HRF] = { + id: ESRGAN_HRF, + type: 'esrgan', + model_name, + is_intermediate: true, + }; + graph.edges.push( + { + source: { + node_id: LATENTS_TO_IMAGE_HRF_LR, + field: 'image', + }, + destination: { + node_id: ESRGAN_HRF, + field: 'image', + }, + }, + { + source: { + node_id: ESRGAN_HRF, + field: 'image', + }, + destination: { + node_id: RESIZE_HRF, + field: 'image', + }, + } + ); + } else { + graph.edges.push({ + source: { + node_id: LATENTS_TO_IMAGE_HRF_LR, + field: 'image', + }, + destination: { + node_id: RESIZE_HRF, + field: 'image', + }, + }); + } + graph.nodes[NOISE_HRF] = { + type: 'noise', + id: NOISE_HRF, + seed: originalNoiseNode?.seed, + use_cpu: originalNoiseNode?.use_cpu, + is_intermediate: true, + }; + graph.edges.push( + { + source: { + node_id: RESIZE_HRF, + field: 'height', + }, + destination: { + node_id: NOISE_HRF, + field: 'height', + }, + }, + { + source: { + node_id: RESIZE_HRF, + field: 'width', + }, + destination: { + node_id: NOISE_HRF, + field: 'width', + }, + } + ); + + graph.nodes[IMAGE_TO_LATENTS_HRF] = { + type: 'i2l', + id: IMAGE_TO_LATENTS_HRF, + is_intermediate: true, + }; + graph.edges.push( + { + source: { + node_id: isAutoVae ? MAIN_MODEL_LOADER : VAE_LOADER, + field: 'vae', + }, + destination: { + node_id: IMAGE_TO_LATENTS_HRF, + field: 'vae', + }, + }, + { + source: { + node_id: RESIZE_HRF, + field: 'image', + }, + destination: { + node_id: IMAGE_TO_LATENTS_HRF, + field: 'image', + }, + } + ); + + graph.nodes[DENOISE_LATENTS_HRF] = { + type: 'denoise_latents', + id: DENOISE_LATENTS_HRF, + is_intermediate: true, + cfg_scale: originalDenoiseLatentsNode?.cfg_scale, + scheduler: originalDenoiseLatentsNode?.scheduler, + steps: originalDenoiseLatentsNode?.steps, + denoising_start: 1 - state.generation.hrfStrength, + denoising_end: 1, + }; + graph.edges.push( + { + source: { + node_id: IMAGE_TO_LATENTS_HRF, + field: 'latents', + }, + destination: { + node_id: DENOISE_LATENTS_HRF, + field: 'latents', + }, + }, + { + source: { + node_id: NOISE_HRF, + field: 'noise', + }, + destination: { + node_id: DENOISE_LATENTS_HRF, + field: 'noise', + }, + } + ); copyConnectionsToDenoiseLatentsHrf(graph); + + graph.nodes[LATENTS_TO_IMAGE_HRF_HR] = { + type: 'l2i', + id: LATENTS_TO_IMAGE_HRF_HR, + fp32: originalLatentsToImageNode?.fp32, + is_intermediate: true, + }; + graph.edges.push( + { + source: { + node_id: isAutoVae ? MAIN_MODEL_LOADER : VAE_LOADER, + field: 'vae', + }, + destination: { + node_id: LATENTS_TO_IMAGE_HRF_HR, + field: 'vae', + }, + }, + { + source: { + node_id: DENOISE_LATENTS_HRF, + field: 'latents', + }, + destination: { + node_id: LATENTS_TO_IMAGE_HRF_HR, + field: 'latents', + }, + } + ); + upsertMetadata(graph, { + hrf_strength: hrfStrength, + hrf_enabled: hrfEnabled, + hrf_method: hrfMethod, + }); }; diff --git a/invokeai/frontend/web/src/features/nodes/util/graphBuilders/addSaveImageNode.ts b/invokeai/frontend/web/src/features/nodes/util/graphBuilders/addSaveImageNode.ts index 79aace8f62..171bd37de8 100644 --- a/invokeai/frontend/web/src/features/nodes/util/graphBuilders/addSaveImageNode.ts +++ b/invokeai/frontend/web/src/features/nodes/util/graphBuilders/addSaveImageNode.ts @@ -5,7 +5,7 @@ import { SaveImageInvocation } from 'services/api/types'; import { CANVAS_OUTPUT, LATENTS_TO_IMAGE, - LATENTS_TO_IMAGE_HRF, + LATENTS_TO_IMAGE_HRF_HR, NSFW_CHECKER, SAVE_IMAGE, WATERMARKER, @@ -62,10 +62,10 @@ export const addSaveImageNode = ( }, destination, }); - } else if (LATENTS_TO_IMAGE_HRF in graph.nodes) { + } else if (LATENTS_TO_IMAGE_HRF_HR in graph.nodes) { graph.edges.push({ source: { - node_id: LATENTS_TO_IMAGE_HRF, + node_id: LATENTS_TO_IMAGE_HRF_HR, field: 'image', }, destination, diff --git a/invokeai/frontend/web/src/features/nodes/util/graphBuilders/constants.ts b/invokeai/frontend/web/src/features/nodes/util/graphBuilders/constants.ts index 51dc94769f..811b2604b1 100644 --- a/invokeai/frontend/web/src/features/nodes/util/graphBuilders/constants.ts +++ b/invokeai/frontend/web/src/features/nodes/util/graphBuilders/constants.ts @@ -4,7 +4,11 @@ export const NEGATIVE_CONDITIONING = 'negative_conditioning'; export const DENOISE_LATENTS = 'denoise_latents'; export const DENOISE_LATENTS_HRF = 'denoise_latents_hrf'; export const LATENTS_TO_IMAGE = 'latents_to_image'; -export const LATENTS_TO_IMAGE_HRF = 'latents_to_image_hrf'; +export const LATENTS_TO_IMAGE_HRF_HR = 'latents_to_image_hrf_hr'; +export const LATENTS_TO_IMAGE_HRF_LR = 'latents_to_image_hrf_lr'; +export const IMAGE_TO_LATENTS_HRF = 'image_to_latents_hrf'; +export const RESIZE_HRF = 'resize_hrf'; +export const ESRGAN_HRF = 'esrgan_hrf'; export const SAVE_IMAGE = 'save_image'; export const NSFW_CHECKER = 'nsfw_checker'; export const WATERMARKER = 'invisible_watermark'; @@ -21,7 +25,6 @@ export const CLIP_SKIP = 'clip_skip'; export const IMAGE_TO_LATENTS = 'image_to_latents'; export const LATENTS_TO_LATENTS = 'latents_to_latents'; export const RESIZE = 'resize_image'; -export const RESCALE_LATENTS = 'rescale_latents'; export const IMG2IMG_RESIZE = 'img2img_resize'; export const CANVAS_OUTPUT = 'canvas_output'; export const INPAINT_IMAGE = 'inpaint_image'; diff --git a/invokeai/frontend/web/src/features/parameters/components/Parameters/HighResFix/ParamHrfCollapse.tsx b/invokeai/frontend/web/src/features/parameters/components/Parameters/HighResFix/ParamHrfCollapse.tsx index 63709f23aa..3e97205407 100644 --- a/invokeai/frontend/web/src/features/parameters/components/Parameters/HighResFix/ParamHrfCollapse.tsx +++ b/invokeai/frontend/web/src/features/parameters/components/Parameters/HighResFix/ParamHrfCollapse.tsx @@ -7,10 +7,9 @@ import IAICollapse from 'common/components/IAICollapse'; import { useFeatureStatus } from 'features/system/hooks/useFeatureStatus'; import { useMemo } from 'react'; import { useTranslation } from 'react-i18next'; -import ParamHrfHeight from './ParamHrfHeight'; import ParamHrfStrength from './ParamHrfStrength'; import ParamHrfToggle from './ParamHrfToggle'; -import ParamHrfWidth from './ParamHrfWidth'; +import ParamHrfMethod from './ParamHrfMethod'; const selector = createSelector( stateSelector, @@ -37,28 +36,11 @@ export default function ParamHrfCollapse() { } return ( - + - {hrfEnabled && ( - - - - - )} - {hrfEnabled && } + + ); diff --git a/invokeai/frontend/web/src/features/parameters/components/Parameters/HighResFix/ParamHrfHeight.tsx b/invokeai/frontend/web/src/features/parameters/components/Parameters/HighResFix/ParamHrfHeight.tsx deleted file mode 100644 index 053da11a5a..0000000000 --- a/invokeai/frontend/web/src/features/parameters/components/Parameters/HighResFix/ParamHrfHeight.tsx +++ /dev/null @@ -1,87 +0,0 @@ -import { createSelector } from '@reduxjs/toolkit'; -import { stateSelector } from 'app/store/store'; -import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; -import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions'; -import IAISlider, { IAIFullSliderProps } from 'common/components/IAISlider'; -import { roundToMultiple } from 'common/util/roundDownToMultiple'; -import { - setHrfHeight, - setHrfWidth, -} from 'features/parameters/store/generationSlice'; -import { memo, useCallback } from 'react'; - -function findPrevMultipleOfEight(n: number): number { - return Math.floor((n - 1) / 8) * 8; -} - -const selector = createSelector( - [stateSelector], - ({ generation, hotkeys, config }) => { - const { min, fineStep, coarseStep } = config.sd.height; - const { model, height, hrfHeight, aspectRatio, hrfEnabled } = generation; - - const step = hotkeys.shift ? fineStep : coarseStep; - - return { - model, - height, - hrfHeight, - min, - step, - aspectRatio, - hrfEnabled, - }; - }, - defaultSelectorOptions -); - -type ParamHeightProps = Omit< - IAIFullSliderProps, - 'label' | 'value' | 'onChange' ->; - -const ParamHrfHeight = (props: ParamHeightProps) => { - const { height, hrfHeight, min, step, aspectRatio, hrfEnabled } = - useAppSelector(selector); - const dispatch = useAppDispatch(); - const maxHrfHeight = Math.max(findPrevMultipleOfEight(height), min); - - const handleChange = useCallback( - (v: number) => { - dispatch(setHrfHeight(v)); - if (aspectRatio) { - const newWidth = roundToMultiple(v * aspectRatio, 8); - dispatch(setHrfWidth(newWidth)); - } - }, - [dispatch, aspectRatio] - ); - - const handleReset = useCallback(() => { - dispatch(setHrfHeight(maxHrfHeight)); - if (aspectRatio) { - const newWidth = roundToMultiple(maxHrfHeight * aspectRatio, 8); - dispatch(setHrfWidth(newWidth)); - } - }, [dispatch, maxHrfHeight, aspectRatio]); - - return ( - - ); -}; - -export default memo(ParamHrfHeight); diff --git a/invokeai/frontend/web/src/features/parameters/components/Parameters/HighResFix/ParamHrfMethod.tsx b/invokeai/frontend/web/src/features/parameters/components/Parameters/HighResFix/ParamHrfMethod.tsx new file mode 100644 index 0000000000..403d2268c1 --- /dev/null +++ b/invokeai/frontend/web/src/features/parameters/components/Parameters/HighResFix/ParamHrfMethod.tsx @@ -0,0 +1,49 @@ +import { createSelector } from '@reduxjs/toolkit'; +import { stateSelector } from 'app/store/store'; +import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; +import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions'; +import IAIMantineSelect from 'common/components/IAIMantineSelect'; +import { setHrfMethod } from 'features/parameters/store/generationSlice'; +import { HrfMethodParam } from 'features/parameters/types/parameterSchemas'; +import { memo, useCallback } from 'react'; +import { useTranslation } from 'react-i18next'; + +const selector = createSelector( + stateSelector, + ({ generation }) => { + const { hrfMethod, hrfEnabled } = generation; + return { hrfMethod, hrfEnabled }; + }, + defaultSelectorOptions +); + +const DATA = ['ESRGAN', 'bilinear']; + +// Dropdown selection for the type of high resolution fix method to use. +const ParamHrfMethodSelect = () => { + const dispatch = useAppDispatch(); + const { t } = useTranslation(); + const { hrfMethod, hrfEnabled } = useAppSelector(selector); + + const handleChange = useCallback( + (v: HrfMethodParam | null) => { + if (!v) { + return; + } + dispatch(setHrfMethod(v)); + }, + [dispatch] + ); + + return ( + + ); +}; + +export default memo(ParamHrfMethodSelect); diff --git a/invokeai/frontend/web/src/features/parameters/components/Parameters/HighResFix/ParamHrfStrength.tsx b/invokeai/frontend/web/src/features/parameters/components/Parameters/HighResFix/ParamHrfStrength.tsx index ba17bc2f36..28205d27a4 100644 --- a/invokeai/frontend/web/src/features/parameters/components/Parameters/HighResFix/ParamHrfStrength.tsx +++ b/invokeai/frontend/web/src/features/parameters/components/Parameters/HighResFix/ParamHrfStrength.tsx @@ -5,6 +5,8 @@ import { memo, useCallback } from 'react'; import { stateSelector } from 'app/store/store'; import { setHrfStrength } from 'features/parameters/store/generationSlice'; import IAISlider from 'common/components/IAISlider'; +import { Tooltip } from '@chakra-ui/react'; +import { useTranslation } from 'react-i18next'; const selector = createSelector( [stateSelector], @@ -31,6 +33,7 @@ const ParamHrfStrength = () => { const { hrfStrength, initial, min, sliderMax, step, hrfEnabled } = useAppSelector(selector); const dispatch = useAppDispatch(); + const { t } = useTranslation(); const handleHrfStrengthReset = useCallback(() => { dispatch(setHrfStrength(initial)); @@ -44,20 +47,21 @@ const ParamHrfStrength = () => { ); return ( - + + + ); }; diff --git a/invokeai/frontend/web/src/features/parameters/components/Parameters/HighResFix/ParamHrfToggle.tsx b/invokeai/frontend/web/src/features/parameters/components/Parameters/HighResFix/ParamHrfToggle.tsx index 8a68ead652..b08e223b56 100644 --- a/invokeai/frontend/web/src/features/parameters/components/Parameters/HighResFix/ParamHrfToggle.tsx +++ b/invokeai/frontend/web/src/features/parameters/components/Parameters/HighResFix/ParamHrfToggle.tsx @@ -3,9 +3,11 @@ import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; import IAISwitch from 'common/components/IAISwitch'; import { setHrfEnabled } from 'features/parameters/store/generationSlice'; import { ChangeEvent, useCallback } from 'react'; +import { useTranslation } from 'react-i18next'; export default function ParamHrfToggle() { const dispatch = useAppDispatch(); + const { t } = useTranslation(); const hrfEnabled = useAppSelector( (state: RootState) => state.generation.hrfEnabled @@ -19,9 +21,10 @@ export default function ParamHrfToggle() { return ( ); } diff --git a/invokeai/frontend/web/src/features/parameters/components/Parameters/HighResFix/ParamHrfWidth.tsx b/invokeai/frontend/web/src/features/parameters/components/Parameters/HighResFix/ParamHrfWidth.tsx deleted file mode 100644 index 09615d5154..0000000000 --- a/invokeai/frontend/web/src/features/parameters/components/Parameters/HighResFix/ParamHrfWidth.tsx +++ /dev/null @@ -1,84 +0,0 @@ -import { createSelector } from '@reduxjs/toolkit'; -import { stateSelector } from 'app/store/store'; -import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; -import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions'; -import IAISlider, { IAIFullSliderProps } from 'common/components/IAISlider'; -import { roundToMultiple } from 'common/util/roundDownToMultiple'; -import { - setHrfHeight, - setHrfWidth, -} from 'features/parameters/store/generationSlice'; -import { memo, useCallback } from 'react'; - -function findPrevMultipleOfEight(n: number): number { - return Math.floor((n - 1) / 8) * 8; -} - -const selector = createSelector( - [stateSelector], - ({ generation, hotkeys, config }) => { - const { min, fineStep, coarseStep } = config.sd.width; - const { model, width, hrfWidth, aspectRatio, hrfEnabled } = generation; - - const step = hotkeys.shift ? fineStep : coarseStep; - - return { - model, - width, - hrfWidth, - min, - step, - aspectRatio, - hrfEnabled, - }; - }, - defaultSelectorOptions -); - -type ParamWidthProps = Omit; - -const ParamHrfWidth = (props: ParamWidthProps) => { - const { width, hrfWidth, min, step, aspectRatio, hrfEnabled } = - useAppSelector(selector); - const dispatch = useAppDispatch(); - const maxHrfWidth = Math.max(findPrevMultipleOfEight(width), min); - - const handleChange = useCallback( - (v: number) => { - dispatch(setHrfWidth(v)); - if (aspectRatio) { - const newHeight = roundToMultiple(v / aspectRatio, 8); - dispatch(setHrfHeight(newHeight)); - } - }, - [dispatch, aspectRatio] - ); - - const handleReset = useCallback(() => { - dispatch(setHrfWidth(maxHrfWidth)); - if (aspectRatio) { - const newHeight = roundToMultiple(maxHrfWidth / aspectRatio, 8); - dispatch(setHrfHeight(newHeight)); - } - }, [dispatch, maxHrfWidth, aspectRatio]); - - return ( - - ); -}; - -export default memo(ParamHrfWidth); diff --git a/invokeai/frontend/web/src/features/parameters/hooks/useRecallParameters.ts b/invokeai/frontend/web/src/features/parameters/hooks/useRecallParameters.ts index 8325620cb4..316554e35e 100644 --- a/invokeai/frontend/web/src/features/parameters/hooks/useRecallParameters.ts +++ b/invokeai/frontend/web/src/features/parameters/hooks/useRecallParameters.ts @@ -55,6 +55,9 @@ import { initialImageSelected, modelSelected } from '../store/actions'; import { setCfgScale, setHeight, + setHrfEnabled, + setHrfMethod, + setHrfStrength, setImg2imgStrength, setNegativePrompt, setPositivePrompt, @@ -67,6 +70,7 @@ import { isValidCfgScale, isValidControlNetModel, isValidHeight, + isValidHrfMethod, isValidIPAdapterModel, isValidLoRAModel, isValidMainModel, @@ -83,6 +87,7 @@ import { isValidSteps, isValidStrength, isValidWidth, + isValidBoolean, } from '../types/parameterSchemas'; const selector = createSelector( @@ -361,6 +366,51 @@ export const useRecallParameters = () => { [dispatch, parameterSetToast, parameterNotSetToast] ); + /** + * Recall high resolution enabled with toast + */ + const recallHrfEnabled = useCallback( + (hrfEnabled: unknown) => { + if (!isValidBoolean(hrfEnabled)) { + parameterNotSetToast(); + return; + } + dispatch(setHrfEnabled(hrfEnabled)); + parameterSetToast(); + }, + [dispatch, parameterSetToast, parameterNotSetToast] + ); + + /** + * Recall high resolution strength with toast + */ + const recallHrfStrength = useCallback( + (hrfStrength: unknown) => { + if (!isValidStrength(hrfStrength)) { + parameterNotSetToast(); + return; + } + dispatch(setHrfStrength(hrfStrength)); + parameterSetToast(); + }, + [dispatch, parameterSetToast, parameterNotSetToast] + ); + + /** + * Recall high resolution method with toast + */ + const recallHrfMethod = useCallback( + (hrfMethod: unknown) => { + if (!isValidHrfMethod(hrfMethod)) { + parameterNotSetToast(); + return; + } + dispatch(setHrfMethod(hrfMethod)); + parameterSetToast(); + }, + [dispatch, parameterSetToast, parameterNotSetToast] + ); + /** * Recall LoRA with toast */ @@ -711,6 +761,9 @@ export const useRecallParameters = () => { steps, width, strength, + hrf_enabled, + hrf_strength, + hrf_method, positive_style_prompt, negative_style_prompt, refiner_model, @@ -729,34 +782,55 @@ export const useRecallParameters = () => { if (isValidCfgScale(cfg_scale)) { dispatch(setCfgScale(cfg_scale)); } + if (isValidMainModel(model)) { dispatch(modelSelected(model)); } + if (isValidPositivePrompt(positive_prompt)) { dispatch(setPositivePrompt(positive_prompt)); } + if (isValidNegativePrompt(negative_prompt)) { dispatch(setNegativePrompt(negative_prompt)); } + if (isValidScheduler(scheduler)) { dispatch(setScheduler(scheduler)); } + if (isValidSeed(seed)) { dispatch(setSeed(seed)); } + if (isValidSteps(steps)) { dispatch(setSteps(steps)); } + if (isValidWidth(width)) { dispatch(setWidth(width)); } + if (isValidHeight(height)) { dispatch(setHeight(height)); } + if (isValidStrength(strength)) { dispatch(setImg2imgStrength(strength)); } + if (isValidBoolean(hrf_enabled)) { + dispatch(setHrfEnabled(hrf_enabled)); + } + + if (isValidStrength(hrf_strength)) { + dispatch(setHrfStrength(hrf_strength)); + } + + if (isValidHrfMethod(hrf_method)) { + dispatch(setHrfMethod(hrf_method)); + } + if (isValidSDXLPositiveStylePrompt(positive_style_prompt)) { dispatch(setPositiveStylePromptSDXL(positive_style_prompt)); } @@ -862,6 +936,9 @@ export const useRecallParameters = () => { recallWidth, recallHeight, recallStrength, + recallHrfEnabled, + recallHrfStrength, + recallHrfMethod, recallLoRA, recallControlNet, recallIPAdapter, diff --git a/invokeai/frontend/web/src/features/parameters/store/generationSlice.ts b/invokeai/frontend/web/src/features/parameters/store/generationSlice.ts index 63d545662a..8fbdfafbde 100644 --- a/invokeai/frontend/web/src/features/parameters/store/generationSlice.ts +++ b/invokeai/frontend/web/src/features/parameters/store/generationSlice.ts @@ -11,6 +11,7 @@ import { CanvasCoherenceModeParam, CfgScaleParam, HeightParam, + HrfMethodParam, MainModelParam, MaskBlurMethodParam, NegativePromptParam, @@ -27,10 +28,9 @@ import { } from '../types/parameterSchemas'; export interface GenerationState { - hrfHeight: HeightParam; - hrfWidth: WidthParam; hrfEnabled: boolean; hrfStrength: StrengthParam; + hrfMethod: HrfMethodParam; cfgScale: CfgScaleParam; height: HeightParam; img2imgStrength: StrengthParam; @@ -73,10 +73,9 @@ export interface GenerationState { } export const initialGenerationState: GenerationState = { - hrfHeight: 64, - hrfWidth: 64, - hrfStrength: 0.75, + hrfStrength: 0.45, hrfEnabled: false, + hrfMethod: 'ESRGAN', cfgScale: 7.5, height: 512, img2imgStrength: 0.75, @@ -279,18 +278,15 @@ export const generationSlice = createSlice({ setClipSkip: (state, action: PayloadAction) => { state.clipSkip = action.payload; }, - setHrfHeight: (state, action: PayloadAction) => { - state.hrfHeight = action.payload; - }, - setHrfWidth: (state, action: PayloadAction) => { - state.hrfWidth = action.payload; - }, setHrfStrength: (state, action: PayloadAction) => { state.hrfStrength = action.payload; }, setHrfEnabled: (state, action: PayloadAction) => { state.hrfEnabled = action.payload; }, + setHrfMethod: (state, action: PayloadAction) => { + state.hrfMethod = action.payload; + }, shouldUseCpuNoiseChanged: (state, action: PayloadAction) => { state.shouldUseCpuNoise = action.payload; }, @@ -375,10 +371,9 @@ export const { setSeamlessXAxis, setSeamlessYAxis, setClipSkip, - setHrfHeight, - setHrfWidth, - setHrfStrength, setHrfEnabled, + setHrfStrength, + setHrfMethod, shouldUseCpuNoiseChanged, setAspectRatio, setShouldLockAspectRatio, diff --git a/invokeai/frontend/web/src/features/parameters/types/parameterSchemas.ts b/invokeai/frontend/web/src/features/parameters/types/parameterSchemas.ts index 40e4603363..ec3f9baba1 100644 --- a/invokeai/frontend/web/src/features/parameters/types/parameterSchemas.ts +++ b/invokeai/frontend/web/src/features/parameters/types/parameterSchemas.ts @@ -400,6 +400,20 @@ export type PrecisionParam = z.infer; export const isValidPrecision = (val: unknown): val is PrecisionParam => zPrecision.safeParse(val).success; +/** + * Zod schema for a high resolution fix method parameter. + */ +export const zHrfMethod = z.enum(['ESRGAN', 'bilinear']); +/** + * Type alias for high resolution fix method parameter, inferred from its zod schema + */ +export type HrfMethodParam = z.infer; +/** + * Validates/type-guards a value as a high resolution fix method parameter + */ +export const isValidHrfMethod = (val: unknown): val is HrfMethodParam => + zHrfMethod.safeParse(val).success; + /** * Zod schema for SDXL refiner positive aesthetic score parameter */ @@ -482,6 +496,17 @@ export const isValidCoherenceModeParam = ( ): val is CanvasCoherenceModeParam => zCanvasCoherenceMode.safeParse(val).success; +/** + * Zod schema for a boolean. + */ +export const zBoolean = z.boolean(); + +/** + * Validates/type-guards a value as a boolean parameter + */ +export const isValidBoolean = (val: unknown): val is boolean => + zBoolean.safeParse(val).success && val !== null && val !== undefined; + // /** // * Zod schema for BaseModelType // */ diff --git a/invokeai/frontend/web/src/features/system/store/configSlice.ts b/invokeai/frontend/web/src/features/system/store/configSlice.ts index 78d540203b..762333044a 100644 --- a/invokeai/frontend/web/src/features/system/store/configSlice.ts +++ b/invokeai/frontend/web/src/features/system/store/configSlice.ts @@ -70,7 +70,7 @@ export const initialConfigState: AppConfig = { coarseStep: 0.05, }, hrfStrength: { - initial: 0.7, + initial: 0.45, min: 0, sliderMax: 1, inputMax: 1, diff --git a/invokeai/frontend/web/src/services/api/schema.d.ts b/invokeai/frontend/web/src/services/api/schema.d.ts index c693aaf3c6..f8e48bda5c 100644 --- a/invokeai/frontend/web/src/services/api/schema.d.ts +++ b/invokeai/frontend/web/src/services/api/schema.d.ts @@ -1956,15 +1956,15 @@ export type components = { /** @description The VAE used for decoding, if the main model's default was not used */ vae?: components["schemas"]["VAEModelField"] | null; /** - * Hrf Width - * @description The high resolution fix height and width multipler. + * Hrf Enabled + * @description Whether or not high resolution fix was enabled. */ - hrf_width?: number | null; + hrf_enabled?: number | null; /** - * Hrf Height - * @description The high resolution fix height and width multipler. + * Hrf Method + * @description The high resolution fix upscale method. */ - hrf_height?: number | null; + hrf_method?: string | null; /** * Hrf Strength * @description The high resolution fix img2img strength used in the upscale pass. @@ -3048,7 +3048,7 @@ export type components = { * @description The nodes in this graph */ nodes?: { - [key: string]: components["schemas"]["LatentsInvocation"] | components["schemas"]["ImageMultiplyInvocation"] | components["schemas"]["ControlNetInvocation"] | components["schemas"]["LeresImageProcessorInvocation"] | components["schemas"]["SubtractInvocation"] | components["schemas"]["ImagePasteInvocation"] | components["schemas"]["CompelInvocation"] | components["schemas"]["CoreMetadataInvocation"] | components["schemas"]["StringInvocation"] | components["schemas"]["CannyImageProcessorInvocation"] | components["schemas"]["SegmentAnythingProcessorInvocation"] | components["schemas"]["CV2InfillInvocation"] | components["schemas"]["BlendLatentsInvocation"] | components["schemas"]["FloatToIntegerInvocation"] | components["schemas"]["MidasDepthImageProcessorInvocation"] | components["schemas"]["RangeOfSizeInvocation"] | components["schemas"]["SchedulerInvocation"] | components["schemas"]["ONNXTextToLatentsInvocation"] | components["schemas"]["LoraLoaderInvocation"] | components["schemas"]["LineartImageProcessorInvocation"] | components["schemas"]["StringJoinInvocation"] | components["schemas"]["ColorInvocation"] | components["schemas"]["FloatMathInvocation"] | components["schemas"]["ConditioningInvocation"] | components["schemas"]["SDXLModelLoaderInvocation"] | components["schemas"]["IntegerInvocation"] | components["schemas"]["PidiImageProcessorInvocation"] | components["schemas"]["SDXLCompelPromptInvocation"] | components["schemas"]["OnnxModelLoaderInvocation"] | components["schemas"]["IterateInvocation"] | components["schemas"]["PromptsFromFileInvocation"] | components["schemas"]["ContentShuffleImageProcessorInvocation"] | components["schemas"]["ImageChannelInvocation"] | components["schemas"]["ImageChannelMultiplyInvocation"] | components["schemas"]["BooleanInvocation"] | components["schemas"]["NormalbaeImageProcessorInvocation"] | components["schemas"]["MultiplyInvocation"] | components["schemas"]["MetadataItemInvocation"] | components["schemas"]["OpenposeImageProcessorInvocation"] | components["schemas"]["InfillPatchMatchInvocation"] | components["schemas"]["VaeLoaderInvocation"] | components["schemas"]["SDXLRefinerCompelPromptInvocation"] | components["schemas"]["TileResamplerProcessorInvocation"] | components["schemas"]["FaceMaskInvocation"] | components["schemas"]["FreeUInvocation"] | components["schemas"]["MergeMetadataInvocation"] | components["schemas"]["ImageNSFWBlurInvocation"] | components["schemas"]["DenoiseLatentsInvocation"] | components["schemas"]["GraphInvocation"] | components["schemas"]["ImageConvertInvocation"] | components["schemas"]["ImageLerpInvocation"] | components["schemas"]["ImageScaleInvocation"] | components["schemas"]["FloatLinearRangeInvocation"] | components["schemas"]["ImageChannelOffsetInvocation"] | components["schemas"]["LaMaInfillInvocation"] | components["schemas"]["LineartAnimeImageProcessorInvocation"] | components["schemas"]["ColorMapImageProcessorInvocation"] | components["schemas"]["StringJoinThreeInvocation"] | components["schemas"]["SaveImageInvocation"] | components["schemas"]["ResizeLatentsInvocation"] | components["schemas"]["ONNXPromptInvocation"] | components["schemas"]["MediapipeFaceProcessorInvocation"] | components["schemas"]["ImageResizeInvocation"] | components["schemas"]["CreateDenoiseMaskInvocation"] | components["schemas"]["FloatInvocation"] | components["schemas"]["ShowImageInvocation"] | components["schemas"]["ESRGANInvocation"] | components["schemas"]["ImageWatermarkInvocation"] | components["schemas"]["IntegerCollectionInvocation"] | components["schemas"]["LatentsToImageInvocation"] | components["schemas"]["RandomFloatInvocation"] | components["schemas"]["BlankImageInvocation"] | components["schemas"]["HedImageProcessorInvocation"] | components["schemas"]["BooleanCollectionInvocation"] | components["schemas"]["MlsdImageProcessorInvocation"] | components["schemas"]["ScaleLatentsInvocation"] | components["schemas"]["DivideInvocation"] | components["schemas"]["StepParamEasingInvocation"] | components["schemas"]["InfillTileInvocation"] | components["schemas"]["SeamlessModeInvocation"] | components["schemas"]["NoiseInvocation"] | components["schemas"]["MainModelLoaderInvocation"] | components["schemas"]["SDXLRefinerModelLoaderInvocation"] | components["schemas"]["ZoeDepthImageProcessorInvocation"] | components["schemas"]["InfillColorInvocation"] | components["schemas"]["AddInvocation"] | components["schemas"]["ImageBlurInvocation"] | components["schemas"]["T2IAdapterInvocation"] | components["schemas"]["CollectInvocation"] | components["schemas"]["MaskCombineInvocation"] | components["schemas"]["ImageInvocation"] | components["schemas"]["ClipSkipInvocation"] | components["schemas"]["ImageToLatentsInvocation"] | components["schemas"]["ImageHueAdjustmentInvocation"] | components["schemas"]["ImageCropInvocation"] | components["schemas"]["StringSplitNegInvocation"] | components["schemas"]["RangeInvocation"] | components["schemas"]["CvInpaintInvocation"] | components["schemas"]["RandomIntInvocation"] | components["schemas"]["LatentsCollectionInvocation"] | components["schemas"]["RoundInvocation"] | components["schemas"]["RandomRangeInvocation"] | components["schemas"]["FaceOffInvocation"] | components["schemas"]["ConditioningCollectionInvocation"] | components["schemas"]["ColorCorrectInvocation"] | components["schemas"]["StringSplitInvocation"] | components["schemas"]["SDXLLoraLoaderInvocation"] | components["schemas"]["MaskFromAlphaInvocation"] | components["schemas"]["FloatCollectionInvocation"] | components["schemas"]["FaceIdentifierInvocation"] | components["schemas"]["IPAdapterInvocation"] | components["schemas"]["MaskEdgeInvocation"] | components["schemas"]["IntegerMathInvocation"] | components["schemas"]["DynamicPromptInvocation"] | components["schemas"]["ImageInverseLerpInvocation"] | components["schemas"]["StringReplaceInvocation"] | components["schemas"]["ImageCollectionInvocation"] | components["schemas"]["StringCollectionInvocation"] | components["schemas"]["MetadataInvocation"] | components["schemas"]["ONNXLatentsToImageInvocation"]; + [key: string]: components["schemas"]["HedImageProcessorInvocation"] | components["schemas"]["LatentsCollectionInvocation"] | components["schemas"]["DynamicPromptInvocation"] | components["schemas"]["FaceMaskInvocation"] | components["schemas"]["ColorInvocation"] | components["schemas"]["LaMaInfillInvocation"] | components["schemas"]["DenoiseLatentsInvocation"] | components["schemas"]["ONNXTextToLatentsInvocation"] | components["schemas"]["IntegerCollectionInvocation"] | components["schemas"]["InfillTileInvocation"] | components["schemas"]["ControlNetInvocation"] | components["schemas"]["ImageCollectionInvocation"] | components["schemas"]["ImageChannelInvocation"] | components["schemas"]["FloatToIntegerInvocation"] | components["schemas"]["MetadataItemInvocation"] | components["schemas"]["ImageInvocation"] | components["schemas"]["ImageToLatentsInvocation"] | components["schemas"]["CoreMetadataInvocation"] | components["schemas"]["StringJoinInvocation"] | components["schemas"]["IntegerMathInvocation"] | components["schemas"]["MidasDepthImageProcessorInvocation"] | components["schemas"]["ImageChannelOffsetInvocation"] | components["schemas"]["SubtractInvocation"] | components["schemas"]["ImageHueAdjustmentInvocation"] | components["schemas"]["IterateInvocation"] | components["schemas"]["MediapipeFaceProcessorInvocation"] | components["schemas"]["MaskFromAlphaInvocation"] | components["schemas"]["BooleanInvocation"] | components["schemas"]["StringSplitNegInvocation"] | components["schemas"]["StringInvocation"] | components["schemas"]["SeamlessModeInvocation"] | components["schemas"]["StringJoinThreeInvocation"] | components["schemas"]["PromptsFromFileInvocation"] | components["schemas"]["LatentsInvocation"] | components["schemas"]["SDXLCompelPromptInvocation"] | components["schemas"]["MlsdImageProcessorInvocation"] | components["schemas"]["ImageMultiplyInvocation"] | components["schemas"]["ImageLerpInvocation"] | components["schemas"]["ColorCorrectInvocation"] | components["schemas"]["ConditioningInvocation"] | components["schemas"]["MainModelLoaderInvocation"] | components["schemas"]["ScaleLatentsInvocation"] | components["schemas"]["ImageWatermarkInvocation"] | components["schemas"]["RandomIntInvocation"] | components["schemas"]["AddInvocation"] | components["schemas"]["TestInvocation"] | components["schemas"]["StringCollectionInvocation"] | components["schemas"]["SchedulerInvocation"] | components["schemas"]["FloatLinearRangeInvocation"] | components["schemas"]["LineartImageProcessorInvocation"] | components["schemas"]["ImageCropInvocation"] | components["schemas"]["NormalbaeImageProcessorInvocation"] | components["schemas"]["InfillColorInvocation"] | components["schemas"]["MergeMetadataInvocation"] | components["schemas"]["VaeLoaderInvocation"] | components["schemas"]["SDXLLoraLoaderInvocation"] | components["schemas"]["RangeOfSizeInvocation"] | components["schemas"]["ImageConvertInvocation"] | components["schemas"]["DivideInvocation"] | components["schemas"]["BlankImageInvocation"] | components["schemas"]["GraphInvocation"] | components["schemas"]["ImageScaleInvocation"] | components["schemas"]["LeresImageProcessorInvocation"] | components["schemas"]["FaceIdentifierInvocation"] | components["schemas"]["StringSplitInvocation"] | components["schemas"]["MaskEdgeInvocation"] | components["schemas"]["ImageNSFWBlurInvocation"] | components["schemas"]["RandomFloatInvocation"] | components["schemas"]["LoraLoaderInvocation"] | components["schemas"]["CannyImageProcessorInvocation"] | components["schemas"]["LineartAnimeImageProcessorInvocation"] | components["schemas"]["MultiplyInvocation"] | components["schemas"]["TestInvocation2"] | components["schemas"]["ContentShuffleImageProcessorInvocation"] | components["schemas"]["BlendLatentsInvocation"] | components["schemas"]["FloatInvocation"] | components["schemas"]["FloatCollectionInvocation"] | components["schemas"]["ONNXLatentsToImageInvocation"] | components["schemas"]["MetadataInvocation"] | components["schemas"]["NoiseInvocation"] | components["schemas"]["ImageInverseLerpInvocation"] | components["schemas"]["StringReplaceInvocation"] | components["schemas"]["PidiImageProcessorInvocation"] | components["schemas"]["ConditioningCollectionInvocation"] | components["schemas"]["ShowImageInvocation"] | components["schemas"]["CompelInvocation"] | components["schemas"]["RoundInvocation"] | components["schemas"]["SegmentAnythingProcessorInvocation"] | components["schemas"]["CvInpaintInvocation"] | components["schemas"]["FloatMathInvocation"] | components["schemas"]["RangeInvocation"] | components["schemas"]["InfillPatchMatchInvocation"] | components["schemas"]["CollectInvocation"] | components["schemas"]["ClipSkipInvocation"] | components["schemas"]["ImageResizeInvocation"] | components["schemas"]["TestInvocation3"] | components["schemas"]["SaveImageInvocation"] | components["schemas"]["T2IAdapterInvocation"] | components["schemas"]["ZoeDepthImageProcessorInvocation"] | components["schemas"]["ONNXPromptInvocation"] | components["schemas"]["FaceOffInvocation"] | components["schemas"]["SDXLRefinerCompelPromptInvocation"] | components["schemas"]["ImagePasteInvocation"] | components["schemas"]["IPAdapterInvocation"] | components["schemas"]["CV2InfillInvocation"] | components["schemas"]["ESRGANInvocation"] | components["schemas"]["SDXLModelLoaderInvocation"] | components["schemas"]["TileResamplerProcessorInvocation"] | components["schemas"]["OpenposeImageProcessorInvocation"] | components["schemas"]["BooleanCollectionInvocation"] | components["schemas"]["CreateDenoiseMaskInvocation"] | components["schemas"]["LatentsToImageInvocation"] | components["schemas"]["ColorMapImageProcessorInvocation"] | components["schemas"]["OnnxModelLoaderInvocation"] | components["schemas"]["IntegerInvocation"] | components["schemas"]["ImageChannelMultiplyInvocation"] | components["schemas"]["RandomRangeInvocation"] | components["schemas"]["MaskCombineInvocation"] | components["schemas"]["SDXLRefinerModelLoaderInvocation"] | components["schemas"]["ResizeLatentsInvocation"] | components["schemas"]["ImageBlurInvocation"] | components["schemas"]["FreeUInvocation"] | components["schemas"]["StepParamEasingInvocation"]; }; /** * Edges @@ -3085,7 +3085,7 @@ export type components = { * @description The results of node executions */ results: { - [key: string]: components["schemas"]["IterateInvocationOutput"] | components["schemas"]["ConditioningCollectionOutput"] | components["schemas"]["BooleanCollectionOutput"] | components["schemas"]["ClipSkipInvocationOutput"] | components["schemas"]["ControlOutput"] | components["schemas"]["UNetOutput"] | components["schemas"]["SDXLRefinerModelLoaderOutput"] | components["schemas"]["LatentsOutput"] | components["schemas"]["StringPosNegOutput"] | components["schemas"]["SeamlessModeOutput"] | components["schemas"]["DenoiseMaskOutput"] | components["schemas"]["StringCollectionOutput"] | components["schemas"]["StringOutput"] | components["schemas"]["ColorCollectionOutput"] | components["schemas"]["CLIPOutput"] | components["schemas"]["VAEOutput"] | components["schemas"]["LatentsCollectionOutput"] | components["schemas"]["T2IAdapterOutput"] | components["schemas"]["ImageCollectionOutput"] | components["schemas"]["MetadataOutput"] | components["schemas"]["ImageOutput"] | components["schemas"]["ModelLoaderOutput"] | components["schemas"]["ColorOutput"] | components["schemas"]["IPAdapterOutput"] | components["schemas"]["FaceOffOutput"] | components["schemas"]["BooleanOutput"] | components["schemas"]["FloatCollectionOutput"] | components["schemas"]["ConditioningOutput"] | components["schemas"]["SchedulerOutput"] | components["schemas"]["CollectInvocationOutput"] | components["schemas"]["LoraLoaderOutput"] | components["schemas"]["String2Output"] | components["schemas"]["FloatOutput"] | components["schemas"]["FaceMaskOutput"] | components["schemas"]["MetadataItemOutput"] | components["schemas"]["SDXLModelLoaderOutput"] | components["schemas"]["ONNXModelLoaderOutput"] | components["schemas"]["GraphInvocationOutput"] | components["schemas"]["IntegerCollectionOutput"] | components["schemas"]["NoiseOutput"] | components["schemas"]["IntegerOutput"] | components["schemas"]["SDXLLoraLoaderOutput"]; + [key: string]: components["schemas"]["IterateInvocationOutput"] | components["schemas"]["LatentsCollectionOutput"] | components["schemas"]["LatentsOutput"] | components["schemas"]["String2Output"] | components["schemas"]["StringOutput"] | components["schemas"]["StringCollectionOutput"] | components["schemas"]["T2IAdapterOutput"] | components["schemas"]["IntegerCollectionOutput"] | components["schemas"]["BooleanCollectionOutput"] | components["schemas"]["StringPosNegOutput"] | components["schemas"]["LoraLoaderOutput"] | components["schemas"]["MetadataOutput"] | components["schemas"]["FloatOutput"] | components["schemas"]["FaceOffOutput"] | components["schemas"]["SDXLLoraLoaderOutput"] | components["schemas"]["UNetOutput"] | components["schemas"]["ConditioningOutput"] | components["schemas"]["FaceMaskOutput"] | components["schemas"]["SeamlessModeOutput"] | components["schemas"]["FloatCollectionOutput"] | components["schemas"]["ColorCollectionOutput"] | components["schemas"]["ColorOutput"] | components["schemas"]["CLIPOutput"] | components["schemas"]["ImageCollectionOutput"] | components["schemas"]["ONNXModelLoaderOutput"] | components["schemas"]["IPAdapterOutput"] | components["schemas"]["SDXLRefinerModelLoaderOutput"] | components["schemas"]["ClipSkipInvocationOutput"] | components["schemas"]["ModelLoaderOutput"] | components["schemas"]["NoiseOutput"] | components["schemas"]["IntegerOutput"] | components["schemas"]["BooleanOutput"] | components["schemas"]["SchedulerOutput"] | components["schemas"]["MetadataItemOutput"] | components["schemas"]["ImageOutput"] | components["schemas"]["ControlOutput"] | components["schemas"]["ConditioningCollectionOutput"] | components["schemas"]["VAEOutput"] | components["schemas"]["DenoiseMaskOutput"] | components["schemas"]["CollectInvocationOutput"] | components["schemas"]["GraphInvocationOutput"] | components["schemas"]["SDXLModelLoaderOutput"]; }; /** * Errors @@ -8505,6 +8505,90 @@ export type components = { */ type: "t2i_adapter_output"; }; + /** TestInvocation */ + TestInvocation: { + /** + * Id + * @description The id of this instance of an invocation. Must be unique among all instances of invocations. + */ + id: string; + /** + * Is Intermediate + * @description Whether or not this is an intermediate invocation. + * @default false + */ + is_intermediate?: boolean; + /** + * Use Cache + * @description Whether or not to use the cache + * @default true + */ + use_cache?: boolean; + /** A */ + a?: string; + /** + * type + * @default test_invocation + * @constant + */ + type: "test_invocation"; + }; + /** TestInvocation2 */ + TestInvocation2: { + /** + * Id + * @description The id of this instance of an invocation. Must be unique among all instances of invocations. + */ + id: string; + /** + * Is Intermediate + * @description Whether or not this is an intermediate invocation. + * @default false + */ + is_intermediate?: boolean; + /** + * Use Cache + * @description Whether or not to use the cache + * @default true + */ + use_cache?: boolean; + /** A */ + a?: string; + /** + * type + * @default test_invocation_2 + * @constant + */ + type: "test_invocation_2"; + }; + /** TestInvocation3 */ + TestInvocation3: { + /** + * Id + * @description The id of this instance of an invocation. Must be unique among all instances of invocations. + */ + id: string; + /** + * Is Intermediate + * @description Whether or not this is an intermediate invocation. + * @default false + */ + is_intermediate?: boolean; + /** + * Use Cache + * @description Whether or not to use the cache + * @default true + */ + use_cache?: boolean; + /** A */ + a?: string; + /** + * type + * @default test_invocation_3 + * @constant + */ + type: "test_invocation_3"; + }; /** TextualInversionModelConfig */ TextualInversionModelConfig: { /** Model Name */ @@ -8850,35 +8934,29 @@ export type components = { ui_order: number | null; }; /** - * ControlNetModelFormat + * IPAdapterModelFormat * @description An enumeration. * @enum {string} */ - ControlNetModelFormat: "checkpoint" | "diffusers"; - /** - * StableDiffusion1ModelFormat - * @description An enumeration. - * @enum {string} - */ - StableDiffusion1ModelFormat: "checkpoint" | "diffusers"; + IPAdapterModelFormat: "invokeai"; /** * StableDiffusionOnnxModelFormat * @description An enumeration. * @enum {string} */ StableDiffusionOnnxModelFormat: "olive" | "onnx"; + /** + * T2IAdapterModelFormat + * @description An enumeration. + * @enum {string} + */ + T2IAdapterModelFormat: "diffusers"; /** * CLIPVisionModelFormat * @description An enumeration. * @enum {string} */ CLIPVisionModelFormat: "diffusers"; - /** - * StableDiffusion2ModelFormat - * @description An enumeration. - * @enum {string} - */ - StableDiffusion2ModelFormat: "checkpoint" | "diffusers"; /** * StableDiffusionXLModelFormat * @description An enumeration. @@ -8886,17 +8964,23 @@ export type components = { */ StableDiffusionXLModelFormat: "checkpoint" | "diffusers"; /** - * IPAdapterModelFormat + * StableDiffusion1ModelFormat * @description An enumeration. * @enum {string} */ - IPAdapterModelFormat: "invokeai"; + StableDiffusion1ModelFormat: "checkpoint" | "diffusers"; /** - * T2IAdapterModelFormat + * ControlNetModelFormat * @description An enumeration. * @enum {string} */ - T2IAdapterModelFormat: "diffusers"; + ControlNetModelFormat: "checkpoint" | "diffusers"; + /** + * StableDiffusion2ModelFormat + * @description An enumeration. + * @enum {string} + */ + StableDiffusion2ModelFormat: "checkpoint" | "diffusers"; }; responses: never; parameters: never; diff --git a/invokeai/frontend/web/src/services/api/types.ts b/invokeai/frontend/web/src/services/api/types.ts index 085ea65327..526a4d6601 100644 --- a/invokeai/frontend/web/src/services/api/types.ts +++ b/invokeai/frontend/web/src/services/api/types.ts @@ -127,7 +127,6 @@ export type CompelInvocation = s['CompelInvocation']; export type DynamicPromptInvocation = s['DynamicPromptInvocation']; export type NoiseInvocation = s['NoiseInvocation']; export type DenoiseLatentsInvocation = s['DenoiseLatentsInvocation']; -export type ResizeLatentsInvocation = s['ResizeLatentsInvocation']; export type ONNXTextToLatentsInvocation = s['ONNXTextToLatentsInvocation']; export type SDXLLoraLoaderInvocation = s['SDXLLoraLoaderInvocation']; export type ImageToLatentsInvocation = s['ImageToLatentsInvocation'];