diff --git a/invokeai/app/invocations/image.py b/invokeai/app/invocations/image.py index a0c41161c3..6de182d7a5 100644 --- a/invokeai/app/invocations/image.py +++ b/invokeai/app/invocations/image.py @@ -17,16 +17,12 @@ from invokeai.app.invocations.fields import ( WithMetadata, ) from invokeai.app.invocations.primitives import ImageOutput -from invokeai.app.services.image_records.image_records_common import ImageCategory +from invokeai.app.services.image_records.image_records_common import ImageCategory, ResourceOrigin from invokeai.app.services.shared.invocation_context import InvocationContext from invokeai.backend.image_util.invisible_watermark import InvisibleWatermark from invokeai.backend.image_util.safety_checker import SafetyChecker -from .baseinvocation import ( - BaseInvocation, - Classification, - invocation, -) +from .baseinvocation import BaseInvocation, Classification, invocation @invocation("show_image", title="Show Image", tags=["image"], category="image", version="1.0.1") @@ -934,3 +930,42 @@ class SaveImageInvocation(BaseInvocation, WithMetadata, WithBoard): image_dto = context.images.save(image=image) return ImageOutput.build(image_dto) + + +@invocation( + "iai_canvas_paste_back", + title="InvokeAI Canvas Paste Back", + tags=["image", "combine"], + category="image", + version="1.0.0", +) +class IAICanvasPasteBackInvocation(BaseInvocation, WithMetadata, WithBoard): + """Combines two images by using the mask provided""" + + source_image: ImageField = InputField(description="The source image") + target_image: ImageField = InputField(default=None, description="The target image") + mask: ImageField = InputField( + description="The mask to use when pasting", + ) + mask_blur: int = InputField(default=0, ge=0, description="The amount to blur the mask by") + + def _prepare_mask(self, mask: Image.Image): + mask_array = numpy.array(mask) + kernel = numpy.ones((self.mask_blur, self.mask_blur), numpy.uint8) + dilated_mask_array = cv2.erode(mask_array, kernel, iterations=3) + dilated_mask = Image.fromarray(dilated_mask_array) + if self.mask_blur > 0: + mask = dilated_mask.filter(ImageFilter.GaussianBlur(self.mask_blur)) + return ImageOps.invert(mask.convert("L")) + + def invoke(self, context: InvocationContext) -> ImageOutput: + source_image = context.images.get_pil(self.source_image.image_name) + target_image = context.images.get_pil(self.target_image.image_name) + mask = self._prepare_mask(context.images.get_pil(self.mask.image_name)) + + # Merge the bands back together + source_image.paste(target_image, (0, 0), mask) + + image_dto = context.images.save(image=source_image) + + return ImageOutput.build(image_dto) diff --git a/invokeai/frontend/web/src/features/nodes/util/graph/buildCanvasInpaintGraph.ts b/invokeai/frontend/web/src/features/nodes/util/graph/buildCanvasInpaintGraph.ts index 59bbca1e7b..079940346b 100644 --- a/invokeai/frontend/web/src/features/nodes/util/graph/buildCanvasInpaintGraph.ts +++ b/invokeai/frontend/web/src/features/nodes/util/graph/buildCanvasInpaintGraph.ts @@ -1,7 +1,13 @@ import { logger } from 'app/logging/logger'; import type { RootState } from 'app/store/store'; -import { getBoardField, getIsIntermediate } from 'features/nodes/util/graph/graphBuilderUtils'; -import type { ImageDTO, ImageToLatentsInvocation, NoiseInvocation, NonNullableGraph } from 'services/api/types'; +import type { + CreateGradientMaskInvocation, + IAICanvasPasteBackInvocation, + ImageDTO, + ImageToLatentsInvocation, + NoiseInvocation, + NonNullableGraph, +} from 'services/api/types'; import { addControlNetToLinearGraph } from './addControlNetToLinearGraph'; import { addIPAdapterToLinearGraph } from './addIPAdapterToLinearGraph'; @@ -29,6 +35,7 @@ import { POSITIVE_CONDITIONING, SEAMLESS, } from './constants'; +import { getBoardField, getIsIntermediate } from './graphBuilderUtils'; /** * Builds the Canvas tab's Inpaint graph. @@ -61,8 +68,8 @@ export const buildCanvasInpaintGraph = ( } = state.generation; if (!model) { - log.error('No Image found in state'); - throw new Error('No Image found in state'); + log.error('No model found in state'); + throw new Error('No model found in state'); } // The bounding box determines width and height, not the width and height params @@ -106,7 +113,6 @@ export const buildCanvasInpaintGraph = ( is_intermediate, prompt: negativePrompt, }, - [INPAINT_IMAGE]: { type: 'i2l', id: INPAINT_IMAGE, @@ -146,12 +152,12 @@ export const buildCanvasInpaintGraph = ( fp32, }, [CANVAS_OUTPUT]: { - type: 'color_correct', + type: 'iai_canvas_paste_back', id: CANVAS_OUTPUT, is_intermediate: getIsIntermediate(state), board: getBoardField(state), - reference: canvasInitImage, - use_cache: false, + mask_blur: canvasCoherenceEdgeSize, + source_image: canvasInitImage, }, }, edges: [ @@ -325,7 +331,7 @@ export const buildCanvasInpaintGraph = ( field: 'mask', }, }, - // Color Correct The Inpainted Result + // Resize Down { source: { node_id: LATENTS_TO_IMAGE, @@ -336,16 +342,6 @@ export const buildCanvasInpaintGraph = ( field: 'image', }, }, - { - source: { - node_id: INPAINT_IMAGE_RESIZE_DOWN, - field: 'image', - }, - destination: { - node_id: CANVAS_OUTPUT, - field: 'image', - }, - }, { source: { node_id: MASK_RESIZE_UP, @@ -356,6 +352,17 @@ export const buildCanvasInpaintGraph = ( field: 'image', }, }, + // Paste Back + { + source: { + node_id: INPAINT_IMAGE_RESIZE_DOWN, + field: 'image', + }, + destination: { + node_id: CANVAS_OUTPUT, + field: 'target_image', + }, + }, { source: { node_id: MASK_RESIZE_DOWN, @@ -377,29 +384,27 @@ export const buildCanvasInpaintGraph = ( image: canvasInitImage, }; - graph.edges.push( - // Color Correct The Inpainted Result - { - source: { - node_id: LATENTS_TO_IMAGE, - field: 'image', - }, - destination: { - node_id: CANVAS_OUTPUT, - field: 'image', - }, + graph.nodes[INPAINT_CREATE_MASK] = { + ...(graph.nodes[INPAINT_CREATE_MASK] as CreateGradientMaskInvocation), + mask: canvasMaskImage, + }; + + // Paste Back + graph.nodes[CANVAS_OUTPUT] = { + ...(graph.nodes[CANVAS_OUTPUT] as IAICanvasPasteBackInvocation), + mask: canvasMaskImage, + }; + + graph.edges.push({ + source: { + node_id: LATENTS_TO_IMAGE, + field: 'image', }, - { - source: { - node_id: MASK_RESIZE_DOWN, - field: 'image', - }, - destination: { - node_id: CANVAS_OUTPUT, - field: 'mask', - }, - } - ); + destination: { + node_id: CANVAS_OUTPUT, + field: 'target_image', + }, + }); } // Add Seamless To Graph diff --git a/invokeai/frontend/web/src/features/nodes/util/graph/buildCanvasOutpaintGraph.ts b/invokeai/frontend/web/src/features/nodes/util/graph/buildCanvasOutpaintGraph.ts index 53840703f2..4140c4c485 100644 --- a/invokeai/frontend/web/src/features/nodes/util/graph/buildCanvasOutpaintGraph.ts +++ b/invokeai/frontend/web/src/features/nodes/util/graph/buildCanvasOutpaintGraph.ts @@ -1,6 +1,5 @@ import { logger } from 'app/logging/logger'; import type { RootState } from 'app/store/store'; -import { getBoardField, getIsIntermediate } from 'features/nodes/util/graph/graphBuilderUtils'; import type { ImageDTO, ImageToLatentsInvocation, @@ -40,6 +39,7 @@ import { POSITIVE_CONDITIONING, SEAMLESS, } from './constants'; +import { getBoardField, getIsIntermediate } from './graphBuilderUtils'; /** * Builds the Canvas tab's Outpaint graph. @@ -149,8 +149,8 @@ export const buildCanvasOutpaintGraph = ( id: INPAINT_CREATE_MASK, is_intermediate, coherence_mode: canvasCoherenceMode, - minimum_denoise: canvasCoherenceMinDenoise, edge_radius: canvasCoherenceEdgeSize, + minimum_denoise: canvasCoherenceMinDenoise, }, [DENOISE_LATENTS]: { type: 'denoise_latents', @@ -171,7 +171,7 @@ export const buildCanvasOutpaintGraph = ( fp32, }, [CANVAS_OUTPUT]: { - type: 'color_correct', + type: 'iai_canvas_paste_back', id: CANVAS_OUTPUT, is_intermediate: getIsIntermediate(state), board: getBoardField(state), @@ -455,7 +455,7 @@ export const buildCanvasOutpaintGraph = ( field: 'image', }, }, - // Color Correct The Inpainted Result + // Paste Back { source: { node_id: INPAINT_INFILL_RESIZE_DOWN, @@ -463,17 +463,17 @@ export const buildCanvasOutpaintGraph = ( }, destination: { node_id: CANVAS_OUTPUT, - field: 'reference', + field: 'source_image', }, }, { source: { - node_id: INPAINT_IMAGE_RESIZE_DOWN, + node_id: LATENTS_TO_IMAGE, field: 'image', }, destination: { node_id: CANVAS_OUTPUT, - field: 'image', + field: 'target_image', }, }, { @@ -503,7 +503,6 @@ export const buildCanvasOutpaintGraph = ( }; graph.edges.push( - // Color Correct The Inpainted Result { source: { node_id: INPAINT_INFILL, @@ -511,7 +510,7 @@ export const buildCanvasOutpaintGraph = ( }, destination: { node_id: CANVAS_OUTPUT, - field: 'reference', + field: 'source_image', }, }, { @@ -521,7 +520,7 @@ export const buildCanvasOutpaintGraph = ( }, destination: { node_id: CANVAS_OUTPUT, - field: 'image', + field: 'target_image', }, }, { diff --git a/invokeai/frontend/web/src/features/nodes/util/graph/buildCanvasSDXLInpaintGraph.ts b/invokeai/frontend/web/src/features/nodes/util/graph/buildCanvasSDXLInpaintGraph.ts index 56fb6147ce..14a45b8f40 100644 --- a/invokeai/frontend/web/src/features/nodes/util/graph/buildCanvasSDXLInpaintGraph.ts +++ b/invokeai/frontend/web/src/features/nodes/util/graph/buildCanvasSDXLInpaintGraph.ts @@ -1,7 +1,8 @@ import { logger } from 'app/logging/logger'; import type { RootState } from 'app/store/store'; import type { - CreateDenoiseMaskInvocation, + CreateGradientMaskInvocation, + IAICanvasPasteBackInvocation, ImageDTO, ImageToLatentsInvocation, NoiseInvocation, @@ -54,15 +55,15 @@ export const buildCanvasSDXLInpaintGraph = ( cfgRescaleMultiplier: cfg_rescale_multiplier, scheduler, steps, + img2imgStrength: strength, seed, vaePrecision, shouldUseCpuNoise, + seamlessXAxis, + seamlessYAxis, canvasCoherenceMode, canvasCoherenceMinDenoise, canvasCoherenceEdgeSize, - seamlessXAxis, - seamlessYAxis, - img2imgStrength: strength, } = state.generation; const { refinerModel, refinerStart } = state.sdxl; @@ -78,8 +79,9 @@ export const buildCanvasSDXLInpaintGraph = ( // We may need to set the inpaint width and height to scale the image const { scaledBoundingBoxDimensions, boundingBoxScaleMethod } = state.canvas; - const fp32 = vaePrecision === 'fp32'; const is_intermediate = true; + const fp32 = vaePrecision === 'fp32'; + const isUsingScaledDimensions = ['auto', 'manual'].includes(boundingBoxScaleMethod); let modelLoaderNodeId = SDXL_MODEL_LOADER; @@ -95,17 +97,20 @@ export const buildCanvasSDXLInpaintGraph = ( [modelLoaderNodeId]: { type: 'sdxl_model_loader', id: modelLoaderNodeId, + is_intermediate, model, }, [POSITIVE_CONDITIONING]: { type: 'sdxl_compel_prompt', id: POSITIVE_CONDITIONING, + is_intermediate, prompt: positivePrompt, style: positiveStylePrompt, }, [NEGATIVE_CONDITIONING]: { type: 'sdxl_compel_prompt', id: NEGATIVE_CONDITIONING, + is_intermediate, prompt: negativePrompt, style: negativeStylePrompt, }, @@ -148,12 +153,12 @@ export const buildCanvasSDXLInpaintGraph = ( fp32, }, [CANVAS_OUTPUT]: { - type: 'color_correct', + type: 'iai_canvas_paste_back', id: CANVAS_OUTPUT, is_intermediate: getIsIntermediate(state), board: getBoardField(state), - reference: canvasInitImage, - use_cache: false, + mask_blur: canvasCoherenceEdgeSize, + source_image: canvasInitImage, }, }, edges: [ @@ -208,7 +213,7 @@ export const buildCanvasSDXLInpaintGraph = ( field: 'clip2', }, }, - // Connect everything to Inpaint + // Connect Everything To Inpaint Node { source: { node_id: POSITIVE_CONDITIONING, @@ -336,7 +341,7 @@ export const buildCanvasSDXLInpaintGraph = ( field: 'mask', }, }, - // Color Correct The Inpainted Result + // Resize Down { source: { node_id: LATENTS_TO_IMAGE, @@ -347,16 +352,6 @@ export const buildCanvasSDXLInpaintGraph = ( field: 'image', }, }, - { - source: { - node_id: INPAINT_IMAGE_RESIZE_DOWN, - field: 'image', - }, - destination: { - node_id: CANVAS_OUTPUT, - field: 'image', - }, - }, { source: { node_id: MASK_RESIZE_UP, @@ -367,6 +362,17 @@ export const buildCanvasSDXLInpaintGraph = ( field: 'image', }, }, + // Paste Back + { + source: { + node_id: INPAINT_IMAGE_RESIZE_DOWN, + field: 'image', + }, + destination: { + node_id: CANVAS_OUTPUT, + field: 'target_image', + }, + }, { source: { node_id: MASK_RESIZE_DOWN, @@ -387,34 +393,28 @@ export const buildCanvasSDXLInpaintGraph = ( ...(graph.nodes[INPAINT_IMAGE] as ImageToLatentsInvocation), image: canvasInitImage, }; + graph.nodes[INPAINT_CREATE_MASK] = { - ...(graph.nodes[INPAINT_CREATE_MASK] as CreateDenoiseMaskInvocation), - image: canvasInitImage, + ...(graph.nodes[INPAINT_CREATE_MASK] as CreateGradientMaskInvocation), + mask: canvasMaskImage, }; - graph.edges.push( - // Color Correct The Inpainted Result - { - source: { - node_id: LATENTS_TO_IMAGE, - field: 'image', - }, - destination: { - node_id: CANVAS_OUTPUT, - field: 'image', - }, + // Paste Back + graph.nodes[CANVAS_OUTPUT] = { + ...(graph.nodes[CANVAS_OUTPUT] as IAICanvasPasteBackInvocation), + mask: canvasMaskImage, + }; + + graph.edges.push({ + source: { + node_id: LATENTS_TO_IMAGE, + field: 'image', }, - { - source: { - node_id: MASK_RESIZE_DOWN, - field: 'image', - }, - destination: { - node_id: CANVAS_OUTPUT, - field: 'mask', - }, - } - ); + destination: { + node_id: CANVAS_OUTPUT, + field: 'target_image', + }, + }); } // Add Seamless To Graph @@ -431,7 +431,7 @@ export const buildCanvasSDXLInpaintGraph = ( } } - // optionally add custom VAE + // Add VAE addVAEToGraph(state, graph, modelLoaderNodeId); // add LoRA support diff --git a/invokeai/frontend/web/src/features/nodes/util/graph/buildCanvasSDXLOutpaintGraph.ts b/invokeai/frontend/web/src/features/nodes/util/graph/buildCanvasSDXLOutpaintGraph.ts index f448b2be72..6a664acb51 100644 --- a/invokeai/frontend/web/src/features/nodes/util/graph/buildCanvasSDXLOutpaintGraph.ts +++ b/invokeai/frontend/web/src/features/nodes/util/graph/buildCanvasSDXLOutpaintGraph.ts @@ -59,18 +59,18 @@ export const buildCanvasSDXLOutpaintGraph = ( cfgRescaleMultiplier: cfg_rescale_multiplier, scheduler, steps, + img2imgStrength: strength, seed, vaePrecision, shouldUseCpuNoise, - canvasCoherenceMode, - canvasCoherenceMinDenoise, - canvasCoherenceEdgeSize, infillTileSize, infillPatchmatchDownscaleSize, infillMethod, seamlessXAxis, seamlessYAxis, - img2imgStrength: strength, + canvasCoherenceMode, + canvasCoherenceMinDenoise, + canvasCoherenceEdgeSize, } = state.generation; const { refinerModel, refinerStart } = state.sdxl; @@ -108,12 +108,14 @@ export const buildCanvasSDXLOutpaintGraph = ( [POSITIVE_CONDITIONING]: { type: 'sdxl_compel_prompt', id: POSITIVE_CONDITIONING, + is_intermediate, prompt: positivePrompt, style: positiveStylePrompt, }, [NEGATIVE_CONDITIONING]: { type: 'sdxl_compel_prompt', id: NEGATIVE_CONDITIONING, + is_intermediate, prompt: negativePrompt, style: negativeStylePrompt, }, @@ -161,6 +163,7 @@ export const buildCanvasSDXLOutpaintGraph = ( denoising_start: refinerModel ? Math.min(refinerStart, 1 - strength) : 1 - strength, denoising_end: refinerModel ? refinerStart : 1, }, + [LATENTS_TO_IMAGE]: { type: 'l2i', id: LATENTS_TO_IMAGE, @@ -168,7 +171,7 @@ export const buildCanvasSDXLOutpaintGraph = ( fp32, }, [CANVAS_OUTPUT]: { - type: 'color_correct', + type: 'iai_canvas_paste_back', id: CANVAS_OUTPUT, is_intermediate: getIsIntermediate(state), board: getBoardField(state), @@ -249,7 +252,7 @@ export const buildCanvasSDXLOutpaintGraph = ( field: 'mask1', }, }, - // Connect Everything To Inpaint + // Plug Everything Into Inpaint Node { source: { node_id: POSITIVE_CONDITIONING, @@ -311,7 +314,7 @@ export const buildCanvasSDXLOutpaintGraph = ( field: 'denoise_mask', }, }, - // Decode inpainted latents to image + { source: { node_id: SDXL_DENOISE_LATENTS, @@ -419,8 +422,7 @@ export const buildCanvasSDXLOutpaintGraph = ( field: 'image', }, }, - - // Take combined mask and resize and then blur + // Take combined mask and resize { source: { node_id: MASK_COMBINE, @@ -431,7 +433,6 @@ export const buildCanvasSDXLOutpaintGraph = ( field: 'image', }, }, - // Resize Results Down { source: { @@ -463,7 +464,7 @@ export const buildCanvasSDXLOutpaintGraph = ( field: 'image', }, }, - // Color Correct The Inpainted Result + // Paste Back { source: { node_id: INPAINT_INFILL_RESIZE_DOWN, @@ -471,17 +472,17 @@ export const buildCanvasSDXLOutpaintGraph = ( }, destination: { node_id: CANVAS_OUTPUT, - field: 'reference', + field: 'source_image', }, }, { source: { - node_id: INPAINT_IMAGE_RESIZE_DOWN, + node_id: LATENTS_TO_IMAGE, field: 'image', }, destination: { node_id: CANVAS_OUTPUT, - field: 'image', + field: 'target_image', }, }, { @@ -511,7 +512,6 @@ export const buildCanvasSDXLOutpaintGraph = ( }; graph.edges.push( - // Color Correct The Inpainted Result { source: { node_id: INPAINT_INFILL, @@ -519,7 +519,7 @@ export const buildCanvasSDXLOutpaintGraph = ( }, destination: { node_id: CANVAS_OUTPUT, - field: 'reference', + field: 'source_image', }, }, { @@ -529,7 +529,7 @@ export const buildCanvasSDXLOutpaintGraph = ( }, destination: { node_id: CANVAS_OUTPUT, - field: 'image', + field: 'target_image', }, }, { @@ -559,7 +559,7 @@ export const buildCanvasSDXLOutpaintGraph = ( } } - // optionally add custom VAE + // Add VAE addVAEToGraph(state, graph, modelLoaderNodeId); // add LoRA support diff --git a/invokeai/frontend/web/src/services/api/schema.ts b/invokeai/frontend/web/src/services/api/schema.ts index 59d1db5f19..943d0c146e 100644 --- a/invokeai/frontend/web/src/services/api/schema.ts +++ b/invokeai/frontend/web/src/services/api/schema.ts @@ -4286,7 +4286,7 @@ export type components = { * @description The nodes in this graph */ nodes: { - [key: string]: components["schemas"]["StringJoinInvocation"] | components["schemas"]["BlankImageInvocation"] | components["schemas"]["ImageHueAdjustmentInvocation"] | components["schemas"]["AddInvocation"] | components["schemas"]["SDXLCompelPromptInvocation"] | components["schemas"]["IterateInvocation"] | components["schemas"]["LoraLoaderInvocation"] | components["schemas"]["SaveImageInvocation"] | components["schemas"]["BlendLatentsInvocation"] | components["schemas"]["TileToPropertiesInvocation"] | components["schemas"]["ImageMultiplyInvocation"] | components["schemas"]["CreateGradientMaskInvocation"] | components["schemas"]["IdealSizeInvocation"] | components["schemas"]["CvInpaintInvocation"] | components["schemas"]["IntegerInvocation"] | components["schemas"]["NoiseInvocation"] | components["schemas"]["StringJoinThreeInvocation"] | components["schemas"]["CreateDenoiseMaskInvocation"] | components["schemas"]["ColorMapImageProcessorInvocation"] | components["schemas"]["LeresImageProcessorInvocation"] | components["schemas"]["ClipSkipInvocation"] | components["schemas"]["StringReplaceInvocation"] | components["schemas"]["PromptsFromFileInvocation"] | components["schemas"]["ColorInvocation"] | components["schemas"]["MlsdImageProcessorInvocation"] | components["schemas"]["FloatLinearRangeInvocation"] | components["schemas"]["InfillColorInvocation"] | components["schemas"]["ImageInvocation"] | components["schemas"]["InfillTileInvocation"] | components["schemas"]["CalculateImageTilesEvenSplitInvocation"] | components["schemas"]["ImageChannelMultiplyInvocation"] | components["schemas"]["RandomIntInvocation"] | components["schemas"]["SDXLRefinerModelLoaderInvocation"] | components["schemas"]["BooleanInvocation"] | components["schemas"]["MaskFromAlphaInvocation"] | components["schemas"]["RangeInvocation"] | components["schemas"]["VaeLoaderInvocation"] | components["schemas"]["ImageChannelOffsetInvocation"] | components["schemas"]["MainModelLoaderInvocation"] | components["schemas"]["CropLatentsCoreInvocation"] | components["schemas"]["FloatCollectionInvocation"] | components["schemas"]["StepParamEasingInvocation"] | components["schemas"]["UnsharpMaskInvocation"] | components["schemas"]["LatentsCollectionInvocation"] | components["schemas"]["ResizeLatentsInvocation"] | components["schemas"]["StringCollectionInvocation"] | components["schemas"]["MultiplyInvocation"] | components["schemas"]["LineartAnimeImageProcessorInvocation"] | components["schemas"]["FaceIdentifierInvocation"] | components["schemas"]["DWOpenposeImageProcessorInvocation"] | components["schemas"]["LatentsInvocation"] | components["schemas"]["ConditioningInvocation"] | components["schemas"]["LineartImageProcessorInvocation"] | components["schemas"]["CompelInvocation"] | components["schemas"]["MetadataItemInvocation"] | components["schemas"]["ImageWatermarkInvocation"] | components["schemas"]["IntegerMathInvocation"] | components["schemas"]["StringSplitInvocation"] | components["schemas"]["TileResamplerProcessorInvocation"] | components["schemas"]["NormalbaeImageProcessorInvocation"] | components["schemas"]["CoreMetadataInvocation"] | components["schemas"]["ContentShuffleImageProcessorInvocation"] | components["schemas"]["MetadataInvocation"] | components["schemas"]["ImageConvertInvocation"] | components["schemas"]["StringSplitNegInvocation"] | components["schemas"]["DenoiseLatentsInvocation"] | components["schemas"]["InfillPatchMatchInvocation"] | components["schemas"]["RandomFloatInvocation"] | components["schemas"]["SubtractInvocation"] | components["schemas"]["LaMaInfillInvocation"] | components["schemas"]["ImageCropInvocation"] | components["schemas"]["SchedulerInvocation"] | components["schemas"]["FloatMathInvocation"] | components["schemas"]["ImageScaleInvocation"] | components["schemas"]["FloatToIntegerInvocation"] | components["schemas"]["RangeOfSizeInvocation"] | components["schemas"]["CalculateImageTilesInvocation"] | components["schemas"]["MaskCombineInvocation"] | components["schemas"]["FaceMaskInvocation"] | components["schemas"]["IPAdapterInvocation"] | components["schemas"]["RoundInvocation"] | components["schemas"]["DepthAnythingImageProcessorInvocation"] | components["schemas"]["ImagePasteInvocation"] | components["schemas"]["CollectInvocation"] | components["schemas"]["SDXLLoraLoaderInvocation"] | components["schemas"]["CannyImageProcessorInvocation"] | components["schemas"]["FreeUInvocation"] | components["schemas"]["BooleanCollectionInvocation"] | components["schemas"]["CenterPadCropInvocation"] | components["schemas"]["PidiImageProcessorInvocation"] | components["schemas"]["SDXLModelLoaderInvocation"] | components["schemas"]["DivideInvocation"] | components["schemas"]["ImageCollectionInvocation"] | components["schemas"]["DynamicPromptInvocation"] | components["schemas"]["PairTileImageInvocation"] | components["schemas"]["ImageNSFWBlurInvocation"] | components["schemas"]["ImageToLatentsInvocation"] | components["schemas"]["StringInvocation"] | components["schemas"]["SegmentAnythingProcessorInvocation"] | components["schemas"]["MidasDepthImageProcessorInvocation"] | components["schemas"]["LatentsToImageInvocation"] | components["schemas"]["ColorCorrectInvocation"] | components["schemas"]["ConditioningCollectionInvocation"] | components["schemas"]["MergeMetadataInvocation"] | components["schemas"]["ImageResizeInvocation"] | components["schemas"]["FloatInvocation"] | components["schemas"]["MaskEdgeInvocation"] | components["schemas"]["T2IAdapterInvocation"] | components["schemas"]["ZoeDepthImageProcessorInvocation"] | components["schemas"]["CalculateImageTilesMinimumOverlapInvocation"] | components["schemas"]["ControlNetInvocation"] | components["schemas"]["FaceOffInvocation"] | components["schemas"]["MediapipeFaceProcessorInvocation"] | components["schemas"]["ImageLerpInvocation"] | components["schemas"]["RandomRangeInvocation"] | components["schemas"]["IntegerCollectionInvocation"] | components["schemas"]["CV2InfillInvocation"] | components["schemas"]["ImageChannelInvocation"] | components["schemas"]["ESRGANInvocation"] | components["schemas"]["HedImageProcessorInvocation"] | components["schemas"]["ImageInverseLerpInvocation"] | components["schemas"]["ShowImageInvocation"] | components["schemas"]["SDXLRefinerCompelPromptInvocation"] | components["schemas"]["ScaleLatentsInvocation"] | components["schemas"]["ImageBlurInvocation"] | components["schemas"]["SeamlessModeInvocation"] | components["schemas"]["MergeTilesToImageInvocation"]; + [key: string]: components["schemas"]["ESRGANInvocation"] | components["schemas"]["StringJoinInvocation"] | components["schemas"]["LaMaInfillInvocation"] | components["schemas"]["MainModelLoaderInvocation"] | components["schemas"]["SDXLRefinerModelLoaderInvocation"] | components["schemas"]["FloatMathInvocation"] | components["schemas"]["IntegerInvocation"] | components["schemas"]["LeresImageProcessorInvocation"] | components["schemas"]["ImageInverseLerpInvocation"] | components["schemas"]["LatentsCollectionInvocation"] | components["schemas"]["BlankImageInvocation"] | components["schemas"]["SDXLRefinerCompelPromptInvocation"] | components["schemas"]["IntegerMathInvocation"] | components["schemas"]["CompelInvocation"] | components["schemas"]["ImageLerpInvocation"] | components["schemas"]["CvInpaintInvocation"] | components["schemas"]["RangeInvocation"] | components["schemas"]["ControlNetInvocation"] | components["schemas"]["PromptsFromFileInvocation"] | components["schemas"]["ColorMapImageProcessorInvocation"] | components["schemas"]["CreateGradientMaskInvocation"] | components["schemas"]["CollectInvocation"] | components["schemas"]["StringJoinThreeInvocation"] | components["schemas"]["MlsdImageProcessorInvocation"] | components["schemas"]["ImageBlurInvocation"] | components["schemas"]["ConditioningInvocation"] | components["schemas"]["RangeOfSizeInvocation"] | components["schemas"]["ImageChannelInvocation"] | components["schemas"]["RandomFloatInvocation"] | components["schemas"]["FloatInvocation"] | components["schemas"]["MaskEdgeInvocation"] | components["schemas"]["DepthAnythingImageProcessorInvocation"] | components["schemas"]["StringSplitInvocation"] | components["schemas"]["FaceOffInvocation"] | components["schemas"]["ImagePasteInvocation"] | components["schemas"]["ContentShuffleImageProcessorInvocation"] | components["schemas"]["ImageInvocation"] | components["schemas"]["ImageScaleInvocation"] | components["schemas"]["ConditioningCollectionInvocation"] | components["schemas"]["DenoiseLatentsInvocation"] | components["schemas"]["CoreMetadataInvocation"] | components["schemas"]["LineartAnimeImageProcessorInvocation"] | components["schemas"]["SchedulerInvocation"] | components["schemas"]["PidiImageProcessorInvocation"] | components["schemas"]["SDXLLoraLoaderInvocation"] | components["schemas"]["NormalbaeImageProcessorInvocation"] | components["schemas"]["CalculateImageTilesInvocation"] | components["schemas"]["CV2InfillInvocation"] | components["schemas"]["ImageResizeInvocation"] | components["schemas"]["TileResamplerProcessorInvocation"] | components["schemas"]["IterateInvocation"] | components["schemas"]["StringCollectionInvocation"] | components["schemas"]["FreeUInvocation"] | components["schemas"]["StringSplitNegInvocation"] | components["schemas"]["ResizeLatentsInvocation"] | components["schemas"]["FloatToIntegerInvocation"] | components["schemas"]["InfillPatchMatchInvocation"] | components["schemas"]["PairTileImageInvocation"] | components["schemas"]["RandomRangeInvocation"] | components["schemas"]["SDXLModelLoaderInvocation"] | components["schemas"]["RoundInvocation"] | components["schemas"]["ImageWatermarkInvocation"] | components["schemas"]["FaceIdentifierInvocation"] | components["schemas"]["CalculateImageTilesMinimumOverlapInvocation"] | components["schemas"]["ColorCorrectInvocation"] | components["schemas"]["ImageCropInvocation"] | components["schemas"]["ImageMultiplyInvocation"] | components["schemas"]["BooleanInvocation"] | components["schemas"]["MergeMetadataInvocation"] | components["schemas"]["DynamicPromptInvocation"] | components["schemas"]["T2IAdapterInvocation"] | components["schemas"]["ImageConvertInvocation"] | components["schemas"]["MaskCombineInvocation"] | components["schemas"]["ImageHueAdjustmentInvocation"] | components["schemas"]["IAICanvasPasteBackInvocation"] | components["schemas"]["ShowImageInvocation"] | components["schemas"]["InfillColorInvocation"] | components["schemas"]["StringReplaceInvocation"] | components["schemas"]["LineartImageProcessorInvocation"] | components["schemas"]["IPAdapterInvocation"] | components["schemas"]["ImageToLatentsInvocation"] | components["schemas"]["ColorInvocation"] | components["schemas"]["CenterPadCropInvocation"] | components["schemas"]["ScaleLatentsInvocation"] | components["schemas"]["ImageNSFWBlurInvocation"] | components["schemas"]["LatentsInvocation"] | components["schemas"]["CannyImageProcessorInvocation"] | components["schemas"]["MergeTilesToImageInvocation"] | components["schemas"]["ImageChannelMultiplyInvocation"] | components["schemas"]["ZoeDepthImageProcessorInvocation"] | components["schemas"]["FloatLinearRangeInvocation"] | components["schemas"]["StepParamEasingInvocation"] | components["schemas"]["HedImageProcessorInvocation"] | components["schemas"]["ClipSkipInvocation"] | components["schemas"]["MediapipeFaceProcessorInvocation"] | components["schemas"]["MetadataInvocation"] | components["schemas"]["LoraLoaderInvocation"] | components["schemas"]["TileToPropertiesInvocation"] | components["schemas"]["FloatCollectionInvocation"] | components["schemas"]["SegmentAnythingProcessorInvocation"] | components["schemas"]["IdealSizeInvocation"] | components["schemas"]["NoiseInvocation"] | components["schemas"]["SeamlessModeInvocation"] | components["schemas"]["MaskFromAlphaInvocation"] | components["schemas"]["MidasDepthImageProcessorInvocation"] | components["schemas"]["FaceMaskInvocation"] | components["schemas"]["SaveImageInvocation"] | components["schemas"]["BlendLatentsInvocation"] | components["schemas"]["CropLatentsCoreInvocation"] | components["schemas"]["StringInvocation"] | components["schemas"]["DivideInvocation"] | components["schemas"]["UnsharpMaskInvocation"] | components["schemas"]["ImageCollectionInvocation"] | components["schemas"]["SubtractInvocation"] | components["schemas"]["CreateDenoiseMaskInvocation"] | components["schemas"]["MultiplyInvocation"] | components["schemas"]["SDXLCompelPromptInvocation"] | components["schemas"]["IntegerCollectionInvocation"] | components["schemas"]["BooleanCollectionInvocation"] | components["schemas"]["DWOpenposeImageProcessorInvocation"] | components["schemas"]["ImageChannelOffsetInvocation"] | components["schemas"]["CalculateImageTilesEvenSplitInvocation"] | components["schemas"]["InfillTileInvocation"] | components["schemas"]["AddInvocation"] | components["schemas"]["VaeLoaderInvocation"] | components["schemas"]["MetadataItemInvocation"] | components["schemas"]["LatentsToImageInvocation"] | components["schemas"]["RandomIntInvocation"]; }; /** * Edges @@ -4323,7 +4323,7 @@ export type components = { * @description The results of node executions */ results: { - [key: string]: components["schemas"]["LoraLoaderOutput"] | components["schemas"]["ImageOutput"] | components["schemas"]["CLIPOutput"] | components["schemas"]["ImageCollectionOutput"] | components["schemas"]["StringOutput"] | components["schemas"]["MetadataOutput"] | components["schemas"]["ColorOutput"] | components["schemas"]["StringPosNegOutput"] | components["schemas"]["ColorCollectionOutput"] | components["schemas"]["IPAdapterOutput"] | components["schemas"]["FloatOutput"] | components["schemas"]["SDXLLoraLoaderOutput"] | components["schemas"]["ClipSkipInvocationOutput"] | components["schemas"]["PairTileImageOutput"] | components["schemas"]["FaceMaskOutput"] | components["schemas"]["LatentsOutput"] | components["schemas"]["T2IAdapterOutput"] | components["schemas"]["SchedulerOutput"] | components["schemas"]["TileToPropertiesOutput"] | components["schemas"]["ConditioningCollectionOutput"] | components["schemas"]["LatentsCollectionOutput"] | components["schemas"]["FloatCollectionOutput"] | components["schemas"]["UNetOutput"] | components["schemas"]["IdealSizeOutput"] | components["schemas"]["MetadataItemOutput"] | components["schemas"]["IterateInvocationOutput"] | components["schemas"]["CalculateImageTilesOutput"] | components["schemas"]["BooleanOutput"] | components["schemas"]["IntegerCollectionOutput"] | components["schemas"]["CollectInvocationOutput"] | components["schemas"]["DenoiseMaskOutput"] | components["schemas"]["ControlOutput"] | components["schemas"]["BooleanCollectionOutput"] | components["schemas"]["String2Output"] | components["schemas"]["VAEOutput"] | components["schemas"]["ConditioningOutput"] | components["schemas"]["SDXLRefinerModelLoaderOutput"] | components["schemas"]["ModelLoaderOutput"] | components["schemas"]["IntegerOutput"] | components["schemas"]["SeamlessModeOutput"] | components["schemas"]["SDXLModelLoaderOutput"] | components["schemas"]["StringCollectionOutput"] | components["schemas"]["FaceOffOutput"] | components["schemas"]["NoiseOutput"]; + [key: string]: components["schemas"]["LatentsOutput"] | components["schemas"]["PairTileImageOutput"] | components["schemas"]["ControlOutput"] | components["schemas"]["LatentsCollectionOutput"] | components["schemas"]["MetadataOutput"] | components["schemas"]["ImageOutput"] | components["schemas"]["IntegerCollectionOutput"] | components["schemas"]["ImageCollectionOutput"] | components["schemas"]["FaceMaskOutput"] | components["schemas"]["String2Output"] | components["schemas"]["TileToPropertiesOutput"] | components["schemas"]["FloatOutput"] | components["schemas"]["MetadataItemOutput"] | components["schemas"]["DenoiseMaskOutput"] | components["schemas"]["ConditioningCollectionOutput"] | components["schemas"]["StringPosNegOutput"] | components["schemas"]["UNetOutput"] | components["schemas"]["ModelLoaderOutput"] | components["schemas"]["CollectInvocationOutput"] | components["schemas"]["CalculateImageTilesOutput"] | components["schemas"]["SchedulerOutput"] | components["schemas"]["IntegerOutput"] | components["schemas"]["FaceOffOutput"] | components["schemas"]["StringCollectionOutput"] | components["schemas"]["IdealSizeOutput"] | components["schemas"]["CLIPOutput"] | components["schemas"]["IterateInvocationOutput"] | components["schemas"]["ConditioningOutput"] | components["schemas"]["ClipSkipInvocationOutput"] | components["schemas"]["NoiseOutput"] | components["schemas"]["VAEOutput"] | components["schemas"]["StringOutput"] | components["schemas"]["BooleanCollectionOutput"] | components["schemas"]["IPAdapterOutput"] | components["schemas"]["SDXLModelLoaderOutput"] | components["schemas"]["T2IAdapterOutput"] | components["schemas"]["LoraLoaderOutput"] | components["schemas"]["SDXLRefinerModelLoaderOutput"] | components["schemas"]["ColorOutput"] | components["schemas"]["SeamlessModeOutput"] | components["schemas"]["ColorCollectionOutput"] | components["schemas"]["BooleanOutput"] | components["schemas"]["FloatCollectionOutput"] | components["schemas"]["SDXLLoraLoaderOutput"]; }; /** * Errors @@ -4472,6 +4472,51 @@ export type components = { */ last_modified: string; }; + /** + * InvokeAI Canvas Paste Back + * @description Combines two images by using the mask provided + */ + IAICanvasPasteBackInvocation: { + /** @description The board to save the image to */ + board?: components["schemas"]["BoardField"] | null; + /** @description Optional metadata to be saved with the image */ + metadata?: components["schemas"]["MetadataField"] | null; + /** + * 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; + /** @description The source image */ + source_image?: components["schemas"]["ImageField"]; + /** @description The target image */ + target_image?: components["schemas"]["ImageField"]; + /** @description The mask to use when pasting */ + mask?: components["schemas"]["ImageField"]; + /** + * Mask Blur + * @description The amount to blur the mask by + * @default 0 + */ + mask_blur?: number; + /** + * type + * @default iai_canvas_paste_back + * @constant + */ + type: "iai_canvas_paste_back"; + }; /** * IPAdapterConfig * @description Model config for IP Adaptor format models. diff --git a/invokeai/frontend/web/src/services/api/types.ts b/invokeai/frontend/web/src/services/api/types.ts index f6b7ad5e08..4d4de90e59 100644 --- a/invokeai/frontend/web/src/services/api/types.ts +++ b/invokeai/frontend/web/src/services/api/types.ts @@ -150,6 +150,8 @@ export type ImageScaleInvocation = S['ImageScaleInvocation']; export type InfillPatchMatchInvocation = S['InfillPatchMatchInvocation']; export type InfillTileInvocation = S['InfillTileInvocation']; export type CreateDenoiseMaskInvocation = S['CreateDenoiseMaskInvocation']; +export type CreateGradientMaskInvocation = S['CreateGradientMaskInvocation']; +export type IAICanvasPasteBackInvocation = S['IAICanvasPasteBackInvocation']; export type MaskEdgeInvocation = S['MaskEdgeInvocation']; export type RandomIntInvocation = S['RandomIntInvocation']; export type CompelInvocation = S['CompelInvocation'];