From 0d3d8803234b2f2f49c88f65a2652467984acef0 Mon Sep 17 00:00:00 2001 From: blessedcoolant <54517381+blessedcoolant@users.noreply.github.com> Date: Fri, 1 Sep 2023 09:13:28 +1200 Subject: [PATCH 01/26] feat: Re-Enable LaMa Infill --- .../Parameters/Canvas/InfillAndScaling/ParamInfillMethod.tsx | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/invokeai/frontend/web/src/features/parameters/components/Parameters/Canvas/InfillAndScaling/ParamInfillMethod.tsx b/invokeai/frontend/web/src/features/parameters/components/Parameters/Canvas/InfillAndScaling/ParamInfillMethod.tsx index 2a8f1ece69..9ac0e3588f 100644 --- a/invokeai/frontend/web/src/features/parameters/components/Parameters/Canvas/InfillAndScaling/ParamInfillMethod.tsx +++ b/invokeai/frontend/web/src/features/parameters/components/Parameters/Canvas/InfillAndScaling/ParamInfillMethod.tsx @@ -27,9 +27,7 @@ const ParamInfillMethod = () => { const { data: appConfigData, isLoading } = useGetAppConfigQuery(); - const infill_methods = appConfigData?.infill_methods.filter( - (method) => method !== 'lama' - ); + const infill_methods = appConfigData?.infill_methods; const { t } = useTranslation(); From 54cda8ea4240921d9972ae8468d95e94c5b4faf3 Mon Sep 17 00:00:00 2001 From: blessedcoolant <54517381+blessedcoolant@users.noreply.github.com> Date: Fri, 1 Sep 2023 09:17:41 +1200 Subject: [PATCH 02/26] chore: Change LaMA log statement to use InvokeAI Logger --- invokeai/backend/image_util/lama.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/invokeai/backend/image_util/lama.py b/invokeai/backend/image_util/lama.py index 2ea22b6fa3..9c5e0153c4 100644 --- a/invokeai/backend/image_util/lama.py +++ b/invokeai/backend/image_util/lama.py @@ -5,6 +5,7 @@ import numpy as np import torch from PIL import Image +import invokeai.backend.util.logging as logger from invokeai.app.services.config import get_invokeai_config from invokeai.backend.util.devices import choose_torch_device @@ -19,7 +20,7 @@ def norm_img(np_img): def load_jit_model(url_or_path, device): model_path = url_or_path - print(f"Loading model from: {model_path}") + logger.info(f"Loading model from: {model_path}") model = torch.jit.load(model_path, map_location="cpu").to(device) model.eval() return model From b94ec148534d806b0cdac53adbe7e1f03fe2b880 Mon Sep 17 00:00:00 2001 From: blessedcoolant <54517381+blessedcoolant@users.noreply.github.com> Date: Fri, 1 Sep 2023 09:19:10 +1200 Subject: [PATCH 03/26] chore: Black lint fix --- .../diffusion/cross_attention_control.py | 2 +- .../diffusion/shared_invokeai_diffusion.py | 20 ++++-- .../image_degradation/bsrgan.py | 4 +- .../image_degradation/bsrgan_light.py | 4 +- .../image_degradation/utils_image.py | 72 ++++++++----------- .../training/textual_inversion_training.py | 5 +- invokeai/backend/util/mps_fixes.py | 2 +- invokeai/backend/util/util.py | 2 +- 8 files changed, 57 insertions(+), 54 deletions(-) diff --git a/invokeai/backend/stable_diffusion/diffusion/cross_attention_control.py b/invokeai/backend/stable_diffusion/diffusion/cross_attention_control.py index 334837a273..35d4800859 100644 --- a/invokeai/backend/stable_diffusion/diffusion/cross_attention_control.py +++ b/invokeai/backend/stable_diffusion/diffusion/cross_attention_control.py @@ -265,7 +265,7 @@ class InvokeAICrossAttentionMixin: if q.shape[1] <= 4096: # (512x512) max q.shape[1]: 4096 return self.einsum_lowest_level(q, k, v, None, None, None) else: - slice_size = math.floor(2 ** 30 / (q.shape[0] * q.shape[1])) + slice_size = math.floor(2**30 / (q.shape[0] * q.shape[1])) return self.einsum_op_slice_dim1(q, k, v, slice_size) def einsum_op_mps_v2(self, q, k, v): diff --git a/invokeai/backend/stable_diffusion/diffusion/shared_invokeai_diffusion.py b/invokeai/backend/stable_diffusion/diffusion/shared_invokeai_diffusion.py index 331b42c047..f05adafca2 100644 --- a/invokeai/backend/stable_diffusion/diffusion/shared_invokeai_diffusion.py +++ b/invokeai/backend/stable_diffusion/diffusion/shared_invokeai_diffusion.py @@ -215,7 +215,10 @@ class InvokeAIDiffuserComponent: dim=0, ), } - (encoder_hidden_states, encoder_attention_mask,) = self._concat_conditionings_for_batch( + ( + encoder_hidden_states, + encoder_attention_mask, + ) = self._concat_conditionings_for_batch( conditioning_data.unconditioned_embeddings.embeds, conditioning_data.text_embeddings.embeds, ) @@ -277,7 +280,10 @@ class InvokeAIDiffuserComponent: wants_cross_attention_control = len(cross_attention_control_types_to_do) > 0 if wants_cross_attention_control: - (unconditioned_next_x, conditioned_next_x,) = self._apply_cross_attention_controlled_conditioning( + ( + unconditioned_next_x, + conditioned_next_x, + ) = self._apply_cross_attention_controlled_conditioning( sample, timestep, conditioning_data, @@ -285,7 +291,10 @@ class InvokeAIDiffuserComponent: **kwargs, ) elif self.sequential_guidance: - (unconditioned_next_x, conditioned_next_x,) = self._apply_standard_conditioning_sequentially( + ( + unconditioned_next_x, + conditioned_next_x, + ) = self._apply_standard_conditioning_sequentially( sample, timestep, conditioning_data, @@ -293,7 +302,10 @@ class InvokeAIDiffuserComponent: ) else: - (unconditioned_next_x, conditioned_next_x,) = self._apply_standard_conditioning( + ( + unconditioned_next_x, + conditioned_next_x, + ) = self._apply_standard_conditioning( sample, timestep, conditioning_data, diff --git a/invokeai/backend/stable_diffusion/image_degradation/bsrgan.py b/invokeai/backend/stable_diffusion/image_degradation/bsrgan.py index 2a2edc92bd..e4d614207b 100644 --- a/invokeai/backend/stable_diffusion/image_degradation/bsrgan.py +++ b/invokeai/backend/stable_diffusion/image_degradation/bsrgan.py @@ -395,7 +395,7 @@ def add_Gaussian_noise(img, noise_level1=2, noise_level2=25): D = np.diag(np.random.rand(3)) U = orth(np.random.rand(3, 3)) conv = np.dot(np.dot(np.transpose(U), D), U) - img = img + np.random.multivariate_normal([0, 0, 0], np.abs(L ** 2 * conv), img.shape[:2]).astype(np.float32) + img = img + np.random.multivariate_normal([0, 0, 0], np.abs(L**2 * conv), img.shape[:2]).astype(np.float32) img = np.clip(img, 0.0, 1.0) return img @@ -413,7 +413,7 @@ def add_speckle_noise(img, noise_level1=2, noise_level2=25): D = np.diag(np.random.rand(3)) U = orth(np.random.rand(3, 3)) conv = np.dot(np.dot(np.transpose(U), D), U) - img += img * np.random.multivariate_normal([0, 0, 0], np.abs(L ** 2 * conv), img.shape[:2]).astype(np.float32) + img += img * np.random.multivariate_normal([0, 0, 0], np.abs(L**2 * conv), img.shape[:2]).astype(np.float32) img = np.clip(img, 0.0, 1.0) return img diff --git a/invokeai/backend/stable_diffusion/image_degradation/bsrgan_light.py b/invokeai/backend/stable_diffusion/image_degradation/bsrgan_light.py index 6c516c8101..cd74adc519 100644 --- a/invokeai/backend/stable_diffusion/image_degradation/bsrgan_light.py +++ b/invokeai/backend/stable_diffusion/image_degradation/bsrgan_light.py @@ -399,7 +399,7 @@ def add_Gaussian_noise(img, noise_level1=2, noise_level2=25): D = np.diag(np.random.rand(3)) U = orth(np.random.rand(3, 3)) conv = np.dot(np.dot(np.transpose(U), D), U) - img = img + np.random.multivariate_normal([0, 0, 0], np.abs(L ** 2 * conv), img.shape[:2]).astype(np.float32) + img = img + np.random.multivariate_normal([0, 0, 0], np.abs(L**2 * conv), img.shape[:2]).astype(np.float32) img = np.clip(img, 0.0, 1.0) return img @@ -417,7 +417,7 @@ def add_speckle_noise(img, noise_level1=2, noise_level2=25): D = np.diag(np.random.rand(3)) U = orth(np.random.rand(3, 3)) conv = np.dot(np.dot(np.transpose(U), D), U) - img += img * np.random.multivariate_normal([0, 0, 0], np.abs(L ** 2 * conv), img.shape[:2]).astype(np.float32) + img += img * np.random.multivariate_normal([0, 0, 0], np.abs(L**2 * conv), img.shape[:2]).astype(np.float32) img = np.clip(img, 0.0, 1.0) return img diff --git a/invokeai/backend/stable_diffusion/image_degradation/utils_image.py b/invokeai/backend/stable_diffusion/image_degradation/utils_image.py index 11df5c5710..2a0773c3ed 100644 --- a/invokeai/backend/stable_diffusion/image_degradation/utils_image.py +++ b/invokeai/backend/stable_diffusion/image_degradation/utils_image.py @@ -562,18 +562,14 @@ def rgb2ycbcr(img, only_y=True): if only_y: rlt = np.dot(img, [65.481, 128.553, 24.966]) / 255.0 + 16.0 else: - rlt = ( - np.matmul( - img, - [ - [65.481, -37.797, 112.0], - [128.553, -74.203, -93.786], - [24.966, 112.0, -18.214], - ], - ) - / 255.0 - + [16, 128, 128] - ) + rlt = np.matmul( + img, + [ + [65.481, -37.797, 112.0], + [128.553, -74.203, -93.786], + [24.966, 112.0, -18.214], + ], + ) / 255.0 + [16, 128, 128] if in_img_type == np.uint8: rlt = rlt.round() else: @@ -592,18 +588,14 @@ def ycbcr2rgb(img): if in_img_type != np.uint8: img *= 255.0 # convert - rlt = ( - np.matmul( - img, - [ - [0.00456621, 0.00456621, 0.00456621], - [0, -0.00153632, 0.00791071], - [0.00625893, -0.00318811, 0], - ], - ) - * 255.0 - + [-222.921, 135.576, -276.836] - ) + rlt = np.matmul( + img, + [ + [0.00456621, 0.00456621, 0.00456621], + [0, -0.00153632, 0.00791071], + [0.00625893, -0.00318811, 0], + ], + ) * 255.0 + [-222.921, 135.576, -276.836] if in_img_type == np.uint8: rlt = rlt.round() else: @@ -626,18 +618,14 @@ def bgr2ycbcr(img, only_y=True): if only_y: rlt = np.dot(img, [24.966, 128.553, 65.481]) / 255.0 + 16.0 else: - rlt = ( - np.matmul( - img, - [ - [24.966, 112.0, -18.214], - [128.553, -74.203, -93.786], - [65.481, -37.797, 112.0], - ], - ) - / 255.0 - + [16, 128, 128] - ) + rlt = np.matmul( + img, + [ + [24.966, 112.0, -18.214], + [128.553, -74.203, -93.786], + [65.481, -37.797, 112.0], + ], + ) / 255.0 + [16, 128, 128] if in_img_type == np.uint8: rlt = rlt.round() else: @@ -728,11 +716,11 @@ def ssim(img1, img2): mu1 = cv2.filter2D(img1, -1, window)[5:-5, 5:-5] # valid mu2 = cv2.filter2D(img2, -1, window)[5:-5, 5:-5] - mu1_sq = mu1 ** 2 - mu2_sq = mu2 ** 2 + mu1_sq = mu1**2 + mu2_sq = mu2**2 mu1_mu2 = mu1 * mu2 - sigma1_sq = cv2.filter2D(img1 ** 2, -1, window)[5:-5, 5:-5] - mu1_sq - sigma2_sq = cv2.filter2D(img2 ** 2, -1, window)[5:-5, 5:-5] - mu2_sq + sigma1_sq = cv2.filter2D(img1**2, -1, window)[5:-5, 5:-5] - mu1_sq + sigma2_sq = cv2.filter2D(img2**2, -1, window)[5:-5, 5:-5] - mu2_sq sigma12 = cv2.filter2D(img1 * img2, -1, window)[5:-5, 5:-5] - mu1_mu2 ssim_map = ((2 * mu1_mu2 + C1) * (2 * sigma12 + C2)) / ((mu1_sq + mu2_sq + C1) * (sigma1_sq + sigma2_sq + C2)) @@ -749,8 +737,8 @@ def ssim(img1, img2): # matlab 'imresize' function, now only support 'bicubic' def cubic(x): absx = torch.abs(x) - absx2 = absx ** 2 - absx3 = absx ** 3 + absx2 = absx**2 + absx3 = absx**3 return (1.5 * absx3 - 2.5 * absx2 + 1) * ((absx <= 1).type_as(absx)) + ( -0.5 * absx3 + 2.5 * absx2 - 4 * absx + 2 ) * (((absx > 1) * (absx <= 2)).type_as(absx)) diff --git a/invokeai/backend/training/textual_inversion_training.py b/invokeai/backend/training/textual_inversion_training.py index 658db5e1d5..d92aa80b38 100644 --- a/invokeai/backend/training/textual_inversion_training.py +++ b/invokeai/backend/training/textual_inversion_training.py @@ -475,7 +475,10 @@ class TextualInversionDataset(Dataset): if self.center_crop: crop = min(img.shape[0], img.shape[1]) - (h, w,) = ( + ( + h, + w, + ) = ( img.shape[0], img.shape[1], ) diff --git a/invokeai/backend/util/mps_fixes.py b/invokeai/backend/util/mps_fixes.py index be465d7d9a..8a4e6baab5 100644 --- a/invokeai/backend/util/mps_fixes.py +++ b/invokeai/backend/util/mps_fixes.py @@ -203,7 +203,7 @@ class ChunkedSlicedAttnProcessor: if attn.upcast_attention: out_item_size = 4 - chunk_size = 2 ** 29 + chunk_size = 2**29 out_size = query.shape[1] * key.shape[1] * out_item_size chunks_count = min(query.shape[1], math.ceil((out_size - 1) / chunk_size)) diff --git a/invokeai/backend/util/util.py b/invokeai/backend/util/util.py index da0b9f6834..7ef9c72fb0 100644 --- a/invokeai/backend/util/util.py +++ b/invokeai/backend/util/util.py @@ -207,7 +207,7 @@ def parallel_data_prefetch( return gather_res -def rand_perlin_2d(shape, res, device, fade=lambda t: 6 * t ** 5 - 15 * t ** 4 + 10 * t ** 3): +def rand_perlin_2d(shape, res, device, fade=lambda t: 6 * t**5 - 15 * t**4 + 10 * t**3): delta = (res[0] / shape[0], res[1] / shape[1]) d = (shape[0] // res[0], shape[1] // res[1]) From 6f162c5decb182715593af7140805add74ecbf0c Mon Sep 17 00:00:00 2001 From: blessedcoolant <54517381+blessedcoolant@users.noreply.github.com> Date: Fri, 1 Sep 2023 11:12:30 +1200 Subject: [PATCH 04/26] experimental: Dilate mask if blurred in Color Correction --- invokeai/app/invocations/image.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/invokeai/app/invocations/image.py b/invokeai/app/invocations/image.py index 5eeead7db2..df5e718ca7 100644 --- a/invokeai/app/invocations/image.py +++ b/invokeai/app/invocations/image.py @@ -561,7 +561,7 @@ class MaskEdgeInvocation(BaseInvocation): ) def invoke(self, context: InvocationContext) -> ImageOutput: - mask = context.services.images.get_pil_image(self.image.image_name) + mask = context.services.images.get_pil_image(self.image.image_name).convert("L") npimg = numpy.asarray(mask, dtype=numpy.uint8) npgradient = numpy.uint8(255 * (1.0 - numpy.floor(numpy.abs(0.5 - numpy.float32(npimg) / 255.0) * 2.0))) @@ -696,8 +696,13 @@ class ColorCorrectInvocation(BaseInvocation): # Blur the mask out (into init image) by specified amount if self.mask_blur_radius > 0: nm = numpy.asarray(pil_init_mask, dtype=numpy.uint8) + inverted_nm = 255 - nm + dilation_size = int(round(self.mask_blur_radius) + 20) + dilating_kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (dilation_size, dilation_size)) + inverted_dilated_nm = cv2.dilate(inverted_nm, dilating_kernel) + dilated_nm = 255 - inverted_dilated_nm nmd = cv2.erode( - nm, + dilated_nm, kernel=numpy.ones((3, 3), dtype=numpy.uint8), iterations=int(self.mask_blur_radius / 2), ) From 7a295cbfd5be2f74804c1b35692219d5603d89ba Mon Sep 17 00:00:00 2001 From: blessedcoolant <54517381+blessedcoolant@users.noreply.github.com> Date: Fri, 1 Sep 2023 11:20:45 +1200 Subject: [PATCH 05/26] experimental: Pass Mask To Coherence Pass --- .../graphBuilders/addSDXLRefinerToGraph.ts | 5 +- .../nodes/util/graphBuilders/addVAEToGraph.ts | 11 +++ .../graphBuilders/buildCanvasInpaintGraph.ts | 89 ++++++++++++++++-- .../graphBuilders/buildCanvasOutpaintGraph.ts | 87 ++++++++++++++---- .../buildCanvasSDXLInpaintGraph.ts | 77 +++++++++++++++- .../buildCanvasSDXLOutpaintGraph.ts | 92 ++++++++++++++----- .../nodes/util/graphBuilders/constants.ts | 4 + .../frontend/web/src/services/api/types.ts | 1 + 8 files changed, 313 insertions(+), 53 deletions(-) diff --git a/invokeai/frontend/web/src/features/nodes/util/graphBuilders/addSDXLRefinerToGraph.ts b/invokeai/frontend/web/src/features/nodes/util/graphBuilders/addSDXLRefinerToGraph.ts index 92d15ffd8c..c9b055dfc2 100644 --- a/invokeai/frontend/web/src/features/nodes/util/graphBuilders/addSDXLRefinerToGraph.ts +++ b/invokeai/frontend/web/src/features/nodes/util/graphBuilders/addSDXLRefinerToGraph.ts @@ -10,7 +10,8 @@ import { CANVAS_OUTPUT, INPAINT_IMAGE_RESIZE_UP, LATENTS_TO_IMAGE, - MASK_BLUR, + MASK_COMBINE, + MASK_RESIZE_UP, METADATA_ACCUMULATOR, SDXL_CANVAS_IMAGE_TO_IMAGE_GRAPH, SDXL_CANVAS_INPAINT_GRAPH, @@ -257,7 +258,7 @@ export const addSDXLRefinerToGraph = ( graph.edges.push( { source: { - node_id: MASK_BLUR, + node_id: isUsingScaledDimensions ? MASK_RESIZE_UP : MASK_COMBINE, field: 'image', }, destination: { diff --git a/invokeai/frontend/web/src/features/nodes/util/graphBuilders/addVAEToGraph.ts b/invokeai/frontend/web/src/features/nodes/util/graphBuilders/addVAEToGraph.ts index b274f8fbba..34d37e9b17 100644 --- a/invokeai/frontend/web/src/features/nodes/util/graphBuilders/addVAEToGraph.ts +++ b/invokeai/frontend/web/src/features/nodes/util/graphBuilders/addVAEToGraph.ts @@ -2,6 +2,7 @@ import { RootState } from 'app/store/store'; import { NonNullableGraph } from 'features/nodes/types/types'; import { MetadataAccumulatorInvocation } from 'services/api/types'; import { + CANVAS_COHERENCE_INPAINT_CREATE_MASK, CANVAS_IMAGE_TO_IMAGE_GRAPH, CANVAS_INPAINT_GRAPH, CANVAS_OUTPAINT_GRAPH, @@ -135,6 +136,16 @@ export const addVAEToGraph = ( field: 'vae', }, }, + { + source: { + node_id: isAutoVae ? modelLoaderNodeId : VAE_LOADER, + field: isAutoVae && isOnnxModel ? 'vae_decoder' : 'vae', + }, + destination: { + node_id: CANVAS_COHERENCE_INPAINT_CREATE_MASK, + field: 'vae', + }, + }, { source: { node_id: isAutoVae ? modelLoaderNodeId : VAE_LOADER, diff --git a/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasInpaintGraph.ts b/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasInpaintGraph.ts index 6eafd1fc06..1783174079 100644 --- a/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasInpaintGraph.ts +++ b/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasInpaintGraph.ts @@ -6,6 +6,7 @@ import { ImageBlurInvocation, ImageDTO, ImageToLatentsInvocation, + MaskEdgeInvocation, NoiseInvocation, RandomIntInvocation, RangeOfSizeInvocation, @@ -18,6 +19,8 @@ import { addVAEToGraph } from './addVAEToGraph'; import { addWatermarkerToGraph } from './addWatermarkerToGraph'; import { CANVAS_COHERENCE_DENOISE_LATENTS, + CANVAS_COHERENCE_INPAINT_CREATE_MASK, + CANVAS_COHERENCE_MASK_EDGE, CANVAS_COHERENCE_NOISE, CANVAS_COHERENCE_NOISE_INCREMENT, CANVAS_INPAINT_GRAPH, @@ -89,6 +92,10 @@ export const buildCanvasInpaintGraph = ( shouldAutoSave, } = state.canvas; + const isUsingScaledDimensions = ['auto', 'manual'].includes( + boundingBoxScaleMethod + ); + let modelLoaderNodeId = MAIN_MODEL_LOADER; const use_cpu = shouldUseNoiseSettings @@ -135,18 +142,18 @@ export const buildCanvasInpaintGraph = ( is_intermediate: true, fp32: vaePrecision === 'fp32' ? true : false, }, - [INPAINT_CREATE_MASK]: { - type: 'create_denoise_mask', - id: INPAINT_CREATE_MASK, - is_intermediate: true, - fp32: vaePrecision === 'fp32' ? true : false, - }, [NOISE]: { type: 'noise', id: NOISE, use_cpu, is_intermediate: true, }, + [INPAINT_CREATE_MASK]: { + type: 'create_denoise_mask', + id: INPAINT_CREATE_MASK, + is_intermediate: true, + fp32: vaePrecision === 'fp32' ? true : false, + }, [DENOISE_LATENTS]: { type: 'denoise_latents', id: DENOISE_LATENTS, @@ -169,9 +176,24 @@ export const buildCanvasInpaintGraph = ( b: 1, is_intermediate: true, }, + [CANVAS_COHERENCE_MASK_EDGE]: { + type: 'mask_edge', + id: CANVAS_COHERENCE_MASK_EDGE, + is_intermediate: true, + edge_blur: maskBlur, + edge_size: maskBlur * 2, + low_threshold: 100, + high_threshold: 200, + }, + [CANVAS_COHERENCE_INPAINT_CREATE_MASK]: { + type: 'create_denoise_mask', + id: CANVAS_COHERENCE_INPAINT_CREATE_MASK, + is_intermediate: true, + fp32: vaePrecision === 'fp32' ? true : false, + }, [CANVAS_COHERENCE_DENOISE_LATENTS]: { type: 'denoise_latents', - id: DENOISE_LATENTS, + id: CANVAS_COHERENCE_DENOISE_LATENTS, is_intermediate: true, steps: canvasCoherenceSteps, cfg_scale: cfg_scale, @@ -311,6 +333,27 @@ export const buildCanvasInpaintGraph = ( field: 'denoise_mask', }, }, + // Create Coherence Mask + { + source: { + node_id: CANVAS_COHERENCE_MASK_EDGE, + field: 'image', + }, + destination: { + node_id: CANVAS_COHERENCE_INPAINT_CREATE_MASK, + field: 'mask', + }, + }, + { + source: { + node_id: CANVAS_COHERENCE_INPAINT_CREATE_MASK, + field: 'denoise_mask', + }, + destination: { + node_id: CANVAS_COHERENCE_DENOISE_LATENTS, + field: 'denoise_mask', + }, + }, // Iterate { source: { @@ -418,7 +461,7 @@ export const buildCanvasInpaintGraph = ( }; // Handle Scale Before Processing - if (['auto', 'manual'].includes(boundingBoxScaleMethod)) { + if (isUsingScaledDimensions) { const scaledWidth: number = scaledBoundingBoxDimensions.width; const scaledHeight: number = scaledBoundingBoxDimensions.height; @@ -494,6 +537,26 @@ export const buildCanvasInpaintGraph = ( field: 'image', }, }, + { + source: { + node_id: INPAINT_IMAGE_RESIZE_UP, + field: 'image', + }, + destination: { + node_id: CANVAS_COHERENCE_INPAINT_CREATE_MASK, + field: 'image', + }, + }, + { + source: { + node_id: MASK_RESIZE_UP, + field: 'image', + }, + destination: { + node_id: CANVAS_COHERENCE_MASK_EDGE, + field: 'image', + }, + }, // Color Correct The Inpainted Result { source: { @@ -555,6 +618,16 @@ export const buildCanvasInpaintGraph = ( ...(graph.nodes[INPAINT_CREATE_MASK] as CreateDenoiseMaskInvocation), image: canvasInitImage, }; + graph.nodes[CANVAS_COHERENCE_INPAINT_CREATE_MASK] = { + ...(graph.nodes[ + CANVAS_COHERENCE_INPAINT_CREATE_MASK + ] as CreateDenoiseMaskInvocation), + image: canvasInitImage, + }; + graph.nodes[CANVAS_COHERENCE_MASK_EDGE] = { + ...(graph.nodes[CANVAS_COHERENCE_MASK_EDGE] as MaskEdgeInvocation), + image: canvasMaskImage, + }; graph.edges.push( // Color Correct The Inpainted Result diff --git a/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasOutpaintGraph.ts b/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasOutpaintGraph.ts index aec9d1c035..2098d3c3e1 100644 --- a/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasOutpaintGraph.ts +++ b/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasOutpaintGraph.ts @@ -2,7 +2,6 @@ import { logger } from 'app/logging/logger'; import { RootState } from 'app/store/store'; import { NonNullableGraph } from 'features/nodes/types/types'; import { - ImageBlurInvocation, ImageDTO, ImageToLatentsInvocation, InfillPatchMatchInvocation, @@ -19,6 +18,8 @@ import { addVAEToGraph } from './addVAEToGraph'; import { addWatermarkerToGraph } from './addWatermarkerToGraph'; import { CANVAS_COHERENCE_DENOISE_LATENTS, + CANVAS_COHERENCE_INPAINT_CREATE_MASK, + CANVAS_COHERENCE_MASK_EDGE, CANVAS_COHERENCE_NOISE, CANVAS_COHERENCE_NOISE_INCREMENT, CANVAS_OUTPAINT_GRAPH, @@ -34,7 +35,6 @@ import { ITERATE, LATENTS_TO_IMAGE, MAIN_MODEL_LOADER, - MASK_BLUR, MASK_COMBINE, MASK_FROM_ALPHA, MASK_RESIZE_DOWN, @@ -71,7 +71,6 @@ export const buildCanvasOutpaintGraph = ( shouldUseNoiseSettings, shouldUseCpuNoise, maskBlur, - maskBlurMethod, canvasCoherenceSteps, canvasCoherenceStrength, tileSize, @@ -96,6 +95,10 @@ export const buildCanvasOutpaintGraph = ( shouldAutoSave, } = state.canvas; + const isUsingScaledDimensions = ['auto', 'manual'].includes( + boundingBoxScaleMethod + ); + let modelLoaderNodeId = MAIN_MODEL_LOADER; const use_cpu = shouldUseNoiseSettings @@ -141,13 +144,6 @@ export const buildCanvasOutpaintGraph = ( is_intermediate: true, mask2: canvasMaskImage, }, - [MASK_BLUR]: { - type: 'img_blur', - id: MASK_BLUR, - is_intermediate: true, - radius: maskBlur, - blur_type: maskBlurMethod, - }, [INPAINT_IMAGE]: { type: 'i2l', id: INPAINT_IMAGE, @@ -188,6 +184,21 @@ export const buildCanvasOutpaintGraph = ( b: 1, is_intermediate: true, }, + [CANVAS_COHERENCE_MASK_EDGE]: { + type: 'mask_edge', + id: CANVAS_COHERENCE_MASK_EDGE, + is_intermediate: true, + edge_blur: maskBlur, + edge_size: maskBlur * 2, + low_threshold: 100, + high_threshold: 200, + }, + [CANVAS_COHERENCE_INPAINT_CREATE_MASK]: { + type: 'create_denoise_mask', + id: CANVAS_COHERENCE_INPAINT_CREATE_MASK, + is_intermediate: true, + fp32: vaePrecision === 'fp32' ? true : false, + }, [CANVAS_COHERENCE_DENOISE_LATENTS]: { type: 'denoise_latents', id: CANVAS_COHERENCE_DENOISE_LATENTS, @@ -333,7 +344,7 @@ export const buildCanvasOutpaintGraph = ( // Create Inpaint Mask { source: { - node_id: MASK_BLUR, + node_id: isUsingScaledDimensions ? MASK_RESIZE_UP : MASK_COMBINE, field: 'image', }, destination: { @@ -351,6 +362,27 @@ export const buildCanvasOutpaintGraph = ( field: 'denoise_mask', }, }, + // Create Coherence Mask + { + source: { + node_id: CANVAS_COHERENCE_MASK_EDGE, + field: 'image', + }, + destination: { + node_id: CANVAS_COHERENCE_INPAINT_CREATE_MASK, + field: 'mask', + }, + }, + { + source: { + node_id: CANVAS_COHERENCE_INPAINT_CREATE_MASK, + field: 'denoise_mask', + }, + destination: { + node_id: CANVAS_COHERENCE_DENOISE_LATENTS, + field: 'denoise_mask', + }, + }, // Iterate { source: { @@ -484,7 +516,7 @@ export const buildCanvasOutpaintGraph = ( } // Handle Scale Before Processing - if (['auto', 'manual'].includes(boundingBoxScaleMethod)) { + if (isUsingScaledDimensions) { const scaledWidth: number = scaledBoundingBoxDimensions.width; const scaledHeight: number = scaledBoundingBoxDimensions.height; @@ -556,6 +588,16 @@ export const buildCanvasOutpaintGraph = ( field: 'image', }, }, + { + source: { + node_id: INPAINT_INFILL, + field: 'image', + }, + destination: { + node_id: CANVAS_COHERENCE_INPAINT_CREATE_MASK, + field: 'image', + }, + }, // Take combined mask and resize and then blur { source: { @@ -573,7 +615,7 @@ export const buildCanvasOutpaintGraph = ( field: 'image', }, destination: { - node_id: MASK_BLUR, + node_id: CANVAS_COHERENCE_MASK_EDGE, field: 'image', }, }, @@ -658,19 +700,26 @@ export const buildCanvasOutpaintGraph = ( ...(graph.nodes[INPAINT_IMAGE] as ImageToLatentsInvocation), image: canvasInitImage, }; - graph.nodes[MASK_BLUR] = { - ...(graph.nodes[MASK_BLUR] as ImageBlurInvocation), - }; graph.edges.push( // Take combined mask and plug it to blur + { + source: { + node_id: INPAINT_INFILL, + field: 'image', + }, + destination: { + node_id: INPAINT_CREATE_MASK, + field: 'image', + }, + }, { source: { node_id: MASK_COMBINE, field: 'image', }, destination: { - node_id: MASK_BLUR, + node_id: CANVAS_COHERENCE_MASK_EDGE, field: 'image', }, }, @@ -680,7 +729,7 @@ export const buildCanvasOutpaintGraph = ( field: 'image', }, destination: { - node_id: INPAINT_CREATE_MASK, + node_id: CANVAS_COHERENCE_INPAINT_CREATE_MASK, field: 'image', }, }, @@ -707,7 +756,7 @@ export const buildCanvasOutpaintGraph = ( }, { source: { - node_id: MASK_BLUR, + node_id: MASK_COMBINE, field: 'image', }, destination: { diff --git a/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasSDXLInpaintGraph.ts b/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasSDXLInpaintGraph.ts index 3cf1eb41e8..ca3f39257e 100644 --- a/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasSDXLInpaintGraph.ts +++ b/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasSDXLInpaintGraph.ts @@ -6,6 +6,7 @@ import { ImageBlurInvocation, ImageDTO, ImageToLatentsInvocation, + MaskEdgeInvocation, NoiseInvocation, RandomIntInvocation, RangeOfSizeInvocation, @@ -19,6 +20,8 @@ import { addVAEToGraph } from './addVAEToGraph'; import { addWatermarkerToGraph } from './addWatermarkerToGraph'; import { CANVAS_COHERENCE_DENOISE_LATENTS, + CANVAS_COHERENCE_INPAINT_CREATE_MASK, + CANVAS_COHERENCE_MASK_EDGE, CANVAS_COHERENCE_NOISE, CANVAS_COHERENCE_NOISE_INCREMENT, CANVAS_OUTPUT, @@ -96,6 +99,10 @@ export const buildCanvasSDXLInpaintGraph = ( shouldAutoSave, } = state.canvas; + const isUsingScaledDimensions = ['auto', 'manual'].includes( + boundingBoxScaleMethod + ); + let modelLoaderNodeId = SDXL_MODEL_LOADER; const use_cpu = shouldUseNoiseSettings @@ -175,9 +182,24 @@ export const buildCanvasSDXLInpaintGraph = ( b: 1, is_intermediate: true, }, + [CANVAS_COHERENCE_MASK_EDGE]: { + type: 'mask_edge', + id: CANVAS_COHERENCE_MASK_EDGE, + is_intermediate: true, + edge_blur: maskBlur, + edge_size: maskBlur * 2, + low_threshold: 100, + high_threshold: 200, + }, + [CANVAS_COHERENCE_INPAINT_CREATE_MASK]: { + type: 'create_denoise_mask', + id: CANVAS_COHERENCE_INPAINT_CREATE_MASK, + is_intermediate: true, + fp32: vaePrecision === 'fp32' ? true : false, + }, [CANVAS_COHERENCE_DENOISE_LATENTS]: { type: 'denoise_latents', - id: SDXL_DENOISE_LATENTS, + id: CANVAS_COHERENCE_DENOISE_LATENTS, is_intermediate: true, steps: canvasCoherenceSteps, cfg_scale: cfg_scale, @@ -326,6 +348,27 @@ export const buildCanvasSDXLInpaintGraph = ( field: 'denoise_mask', }, }, + // Create Coherence Mask + { + source: { + node_id: CANVAS_COHERENCE_MASK_EDGE, + field: 'image', + }, + destination: { + node_id: CANVAS_COHERENCE_INPAINT_CREATE_MASK, + field: 'mask', + }, + }, + { + source: { + node_id: CANVAS_COHERENCE_INPAINT_CREATE_MASK, + field: 'denoise_mask', + }, + destination: { + node_id: CANVAS_COHERENCE_DENOISE_LATENTS, + field: 'denoise_mask', + }, + }, // Iterate { source: { @@ -433,7 +476,7 @@ export const buildCanvasSDXLInpaintGraph = ( }; // Handle Scale Before Processing - if (['auto', 'manual'].includes(boundingBoxScaleMethod)) { + if (isUsingScaledDimensions) { const scaledWidth: number = scaledBoundingBoxDimensions.width; const scaledHeight: number = scaledBoundingBoxDimensions.height; @@ -509,6 +552,26 @@ export const buildCanvasSDXLInpaintGraph = ( field: 'image', }, }, + { + source: { + node_id: INPAINT_IMAGE_RESIZE_UP, + field: 'image', + }, + destination: { + node_id: CANVAS_COHERENCE_INPAINT_CREATE_MASK, + field: 'image', + }, + }, + { + source: { + node_id: MASK_RESIZE_UP, + field: 'image', + }, + destination: { + node_id: CANVAS_COHERENCE_MASK_EDGE, + field: 'image', + }, + }, // Color Correct The Inpainted Result { source: { @@ -570,6 +633,16 @@ export const buildCanvasSDXLInpaintGraph = ( ...(graph.nodes[INPAINT_CREATE_MASK] as CreateDenoiseMaskInvocation), image: canvasInitImage, }; + graph.nodes[CANVAS_COHERENCE_INPAINT_CREATE_MASK] = { + ...(graph.nodes[ + CANVAS_COHERENCE_INPAINT_CREATE_MASK + ] as CreateDenoiseMaskInvocation), + image: canvasInitImage, + }; + graph.nodes[CANVAS_COHERENCE_MASK_EDGE] = { + ...(graph.nodes[CANVAS_COHERENCE_MASK_EDGE] as MaskEdgeInvocation), + image: canvasMaskImage, + }; graph.edges.push( // Color Correct The Inpainted Result diff --git a/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasSDXLOutpaintGraph.ts b/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasSDXLOutpaintGraph.ts index 811efce6df..e8c3ce6435 100644 --- a/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasSDXLOutpaintGraph.ts +++ b/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasSDXLOutpaintGraph.ts @@ -2,7 +2,6 @@ import { logger } from 'app/logging/logger'; import { RootState } from 'app/store/store'; import { NonNullableGraph } from 'features/nodes/types/types'; import { - ImageBlurInvocation, ImageDTO, ImageToLatentsInvocation, InfillPatchMatchInvocation, @@ -20,6 +19,8 @@ import { addVAEToGraph } from './addVAEToGraph'; import { addWatermarkerToGraph } from './addWatermarkerToGraph'; import { CANVAS_COHERENCE_DENOISE_LATENTS, + CANVAS_COHERENCE_INPAINT_CREATE_MASK, + CANVAS_COHERENCE_MASK_EDGE, CANVAS_COHERENCE_NOISE, CANVAS_COHERENCE_NOISE_INCREMENT, CANVAS_OUTPUT, @@ -31,7 +32,6 @@ import { INPAINT_INFILL_RESIZE_DOWN, ITERATE, LATENTS_TO_IMAGE, - MASK_BLUR, MASK_COMBINE, MASK_FROM_ALPHA, MASK_RESIZE_DOWN, @@ -72,7 +72,6 @@ export const buildCanvasSDXLOutpaintGraph = ( shouldUseNoiseSettings, shouldUseCpuNoise, maskBlur, - maskBlurMethod, canvasCoherenceSteps, canvasCoherenceStrength, tileSize, @@ -103,6 +102,10 @@ export const buildCanvasSDXLOutpaintGraph = ( shouldAutoSave, } = state.canvas; + const isUsingScaledDimensions = ['auto', 'manual'].includes( + boundingBoxScaleMethod + ); + let modelLoaderNodeId = SDXL_MODEL_LOADER; const use_cpu = shouldUseNoiseSettings @@ -145,13 +148,6 @@ export const buildCanvasSDXLOutpaintGraph = ( is_intermediate: true, mask2: canvasMaskImage, }, - [MASK_BLUR]: { - type: 'img_blur', - id: MASK_BLUR, - is_intermediate: true, - radius: maskBlur, - blur_type: maskBlurMethod, - }, [INPAINT_IMAGE]: { type: 'i2l', id: INPAINT_IMAGE, @@ -194,6 +190,21 @@ export const buildCanvasSDXLOutpaintGraph = ( b: 1, is_intermediate: true, }, + [CANVAS_COHERENCE_MASK_EDGE]: { + type: 'mask_edge', + id: CANVAS_COHERENCE_MASK_EDGE, + is_intermediate: true, + edge_blur: maskBlur, + edge_size: maskBlur * 2, + low_threshold: 100, + high_threshold: 200, + }, + [CANVAS_COHERENCE_INPAINT_CREATE_MASK]: { + type: 'create_denoise_mask', + id: CANVAS_COHERENCE_INPAINT_CREATE_MASK, + is_intermediate: true, + fp32: vaePrecision === 'fp32' ? true : false, + }, [CANVAS_COHERENCE_DENOISE_LATENTS]: { type: 'denoise_latents', id: CANVAS_COHERENCE_DENOISE_LATENTS, @@ -348,7 +359,7 @@ export const buildCanvasSDXLOutpaintGraph = ( // Create Inpaint Mask { source: { - node_id: MASK_BLUR, + node_id: isUsingScaledDimensions ? MASK_RESIZE_UP : MASK_COMBINE, field: 'image', }, destination: { @@ -366,6 +377,27 @@ export const buildCanvasSDXLOutpaintGraph = ( field: 'denoise_mask', }, }, + // Create Coherence Mask + { + source: { + node_id: CANVAS_COHERENCE_MASK_EDGE, + field: 'image', + }, + destination: { + node_id: CANVAS_COHERENCE_INPAINT_CREATE_MASK, + field: 'mask', + }, + }, + { + source: { + node_id: CANVAS_COHERENCE_INPAINT_CREATE_MASK, + field: 'denoise_mask', + }, + destination: { + node_id: CANVAS_COHERENCE_DENOISE_LATENTS, + field: 'denoise_mask', + }, + }, // Iterate { source: { @@ -410,7 +442,7 @@ export const buildCanvasSDXLOutpaintGraph = ( }, { source: { - node_id: SDXL_MODEL_LOADER, + node_id: modelLoaderNodeId, field: 'unet', }, destination: { @@ -473,7 +505,6 @@ export const buildCanvasSDXLOutpaintGraph = ( }; // Add Infill Nodes - if (infillMethod === 'patchmatch') { graph.nodes[INPAINT_INFILL] = { type: 'infill_patchmatch', @@ -500,7 +531,7 @@ export const buildCanvasSDXLOutpaintGraph = ( } // Handle Scale Before Processing - if (['auto', 'manual'].includes(boundingBoxScaleMethod)) { + if (isUsingScaledDimensions) { const scaledWidth: number = scaledBoundingBoxDimensions.width; const scaledHeight: number = scaledBoundingBoxDimensions.height; @@ -572,6 +603,16 @@ export const buildCanvasSDXLOutpaintGraph = ( field: 'image', }, }, + { + source: { + node_id: INPAINT_INFILL, + field: 'image', + }, + destination: { + node_id: CANVAS_COHERENCE_INPAINT_CREATE_MASK, + field: 'image', + }, + }, // Take combined mask and resize and then blur { source: { @@ -589,7 +630,7 @@ export const buildCanvasSDXLOutpaintGraph = ( field: 'image', }, destination: { - node_id: MASK_BLUR, + node_id: CANVAS_COHERENCE_MASK_EDGE, field: 'image', }, }, @@ -674,19 +715,26 @@ export const buildCanvasSDXLOutpaintGraph = ( ...(graph.nodes[INPAINT_IMAGE] as ImageToLatentsInvocation), image: canvasInitImage, }; - graph.nodes[MASK_BLUR] = { - ...(graph.nodes[MASK_BLUR] as ImageBlurInvocation), - }; graph.edges.push( // Take combined mask and plug it to blur + { + source: { + node_id: INPAINT_INFILL, + field: 'image', + }, + destination: { + node_id: INPAINT_CREATE_MASK, + field: 'image', + }, + }, { source: { node_id: MASK_COMBINE, field: 'image', }, destination: { - node_id: MASK_BLUR, + node_id: CANVAS_COHERENCE_MASK_EDGE, field: 'image', }, }, @@ -696,7 +744,7 @@ export const buildCanvasSDXLOutpaintGraph = ( field: 'image', }, destination: { - node_id: INPAINT_CREATE_MASK, + node_id: CANVAS_COHERENCE_INPAINT_CREATE_MASK, field: 'image', }, }, @@ -723,7 +771,7 @@ export const buildCanvasSDXLOutpaintGraph = ( }, { source: { - node_id: MASK_BLUR, + node_id: MASK_COMBINE, field: 'image', }, destination: { @@ -734,7 +782,7 @@ export const buildCanvasSDXLOutpaintGraph = ( ); } - // Handle seed + // Handle Seed if (shouldRandomizeSeed) { // Random int node to generate the starting seed const randomIntNode: RandomIntInvocation = { 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 9eaeaa9c7e..70bd0c4058 100644 --- a/invokeai/frontend/web/src/features/nodes/util/graphBuilders/constants.ts +++ b/invokeai/frontend/web/src/features/nodes/util/graphBuilders/constants.ts @@ -27,11 +27,15 @@ export const INPAINT_INFILL = 'inpaint_infill'; export const INPAINT_INFILL_RESIZE_DOWN = 'inpaint_infill_resize_down'; export const INPAINT_FINAL_IMAGE = 'inpaint_final_image'; export const INPAINT_CREATE_MASK = 'inpaint_create_mask'; +export const INPAINT_MASK = 'inpaint_mask'; export const CANVAS_COHERENCE_DENOISE_LATENTS = 'canvas_coherence_denoise_latents'; export const CANVAS_COHERENCE_NOISE = 'canvas_coherence_noise'; export const CANVAS_COHERENCE_NOISE_INCREMENT = 'canvas_coherence_noise_increment'; +export const CANVAS_COHERENCE_MASK_EDGE = 'canvas_coherence_mask_edge'; +export const CANVAS_COHERENCE_INPAINT_CREATE_MASK = + 'canvas_coherence_inpaint_create_mask'; export const MASK_FROM_ALPHA = 'tomask'; export const MASK_EDGE = 'mask_edge'; export const MASK_BLUR = 'mask_blur'; diff --git a/invokeai/frontend/web/src/services/api/types.ts b/invokeai/frontend/web/src/services/api/types.ts index 51e2459b7f..bae60ff701 100644 --- a/invokeai/frontend/web/src/services/api/types.ts +++ b/invokeai/frontend/web/src/services/api/types.ts @@ -112,6 +112,7 @@ export type ImageScaleInvocation = s['ImageScaleInvocation']; export type InfillPatchMatchInvocation = s['InfillPatchMatchInvocation']; export type InfillTileInvocation = s['InfillTileInvocation']; export type CreateDenoiseMaskInvocation = s['CreateDenoiseMaskInvocation']; +export type MaskEdgeInvocation = s['MaskEdgeInvocation']; export type RandomIntInvocation = s['RandomIntInvocation']; export type CompelInvocation = s['CompelInvocation']; export type DynamicPromptInvocation = s['DynamicPromptInvocation']; From 1a9f552a7560f56e94bc57b372aba631ac01fb75 Mon Sep 17 00:00:00 2001 From: blessedcoolant <54517381+blessedcoolant@users.noreply.github.com> Date: Sat, 2 Sep 2023 04:48:18 +1200 Subject: [PATCH 06/26] experimental: Add CV2 Infill --- invokeai/app/api/routers/app_info.py | 12 +- invokeai/app/invocations/infill.py | 38 +++++- invokeai/backend/image_util/cv2_inpaint.py | 20 +++ .../graphBuilders/buildCanvasOutpaintGraph.ts | 8 ++ .../buildCanvasSDXLOutpaintGraph.ts | 8 ++ .../frontend/web/src/services/api/schema.d.ts | 121 +++++++++++++++--- 6 files changed, 178 insertions(+), 29 deletions(-) create mode 100644 invokeai/backend/image_util/cv2_inpaint.py diff --git a/invokeai/app/api/routers/app_info.py b/invokeai/app/api/routers/app_info.py index b69a0b9a03..afa17d5bd7 100644 --- a/invokeai/app/api/routers/app_info.py +++ b/invokeai/app/api/routers/app_info.py @@ -1,19 +1,19 @@ import typing from enum import Enum +from pathlib import Path + from fastapi import Body from fastapi.routing import APIRouter -from pathlib import Path from pydantic import BaseModel, Field +from invokeai.app.invocations.upscale import ESRGAN_MODELS +from invokeai.backend.image_util.invisible_watermark import InvisibleWatermark from invokeai.backend.image_util.patchmatch import PatchMatch from invokeai.backend.image_util.safety_checker import SafetyChecker -from invokeai.backend.image_util.invisible_watermark import InvisibleWatermark -from invokeai.app.invocations.upscale import ESRGAN_MODELS - +from invokeai.backend.util.logging import logging from invokeai.version import __version__ from ..dependencies import ApiDependencies -from invokeai.backend.util.logging import logging class LogLevel(int, Enum): @@ -55,7 +55,7 @@ async def get_version() -> AppVersion: @app_router.get("/config", operation_id="get_config", status_code=200, response_model=AppConfig) async def get_config() -> AppConfig: - infill_methods = ["tile", "lama"] + infill_methods = ["tile", "lama", "cv2"] if PatchMatch.patchmatch_available(): infill_methods.append("patchmatch") diff --git a/invokeai/app/invocations/infill.py b/invokeai/app/invocations/infill.py index 438c56e312..69d2a04b75 100644 --- a/invokeai/app/invocations/infill.py +++ b/invokeai/app/invocations/infill.py @@ -8,6 +8,7 @@ from PIL import Image, ImageOps from invokeai.app.invocations.primitives import ColorField, ImageField, ImageOutput from invokeai.app.util.misc import SEED_MAX, get_random_seed +from invokeai.backend.image_util.cv2_inpaint import cv2_inpaint from invokeai.backend.image_util.lama import LaMA from invokeai.backend.image_util.patchmatch import PatchMatch @@ -16,11 +17,7 @@ from .baseinvocation import BaseInvocation, InputField, InvocationContext, invoc def infill_methods() -> list[str]: - methods = [ - "tile", - "solid", - "lama", - ] + methods = ["tile", "solid", "lama", "cv2"] if PatchMatch.patchmatch_available(): methods.insert(0, "patchmatch") return methods @@ -49,6 +46,10 @@ def infill_patchmatch(im: Image.Image) -> Image.Image: return im_patched +def infill_cv2(im: Image.Image) -> Image.Image: + return cv2_inpaint(im) + + def get_tile_images(image: np.ndarray, width=8, height=8): _nrows, _ncols, depth = image.shape _strides = image.strides @@ -243,3 +244,30 @@ class LaMaInfillInvocation(BaseInvocation): width=image_dto.width, height=image_dto.height, ) + + +@invocation("infill_cv2", title="CV2 Infill", tags=["image", "inpaint"], category="inpaint") +class CV2InfillInvocation(BaseInvocation): + """Infills transparent areas of an image using OpenCV Inpainting""" + + image: ImageField = InputField(description="The image to infill") + + def invoke(self, context: InvocationContext) -> ImageOutput: + image = context.services.images.get_pil_image(self.image.image_name) + + infilled = infill_cv2(image.copy()) + + image_dto = context.services.images.create( + image=infilled, + image_origin=ResourceOrigin.INTERNAL, + image_category=ImageCategory.GENERAL, + node_id=self.id, + session_id=context.graph_execution_state_id, + is_intermediate=self.is_intermediate, + ) + + return ImageOutput( + image=ImageField(image_name=image_dto.image_name), + width=image_dto.width, + height=image_dto.height, + ) diff --git a/invokeai/backend/image_util/cv2_inpaint.py b/invokeai/backend/image_util/cv2_inpaint.py new file mode 100644 index 0000000000..edc16e3bfb --- /dev/null +++ b/invokeai/backend/image_util/cv2_inpaint.py @@ -0,0 +1,20 @@ +import cv2 +import numpy as np +from PIL import Image + + +def cv2_inpaint(image: Image.Image) -> Image.Image: + # Prepare Image + image_array = np.array(image.convert("RGB")) + image_cv = cv2.cvtColor(image_array, cv2.COLOR_RGB2BGR) + + # Prepare Mask From Alpha Channel + mask = image.split()[3].convert("RGB") + mask_array = np.array(mask) + mask_cv = cv2.cvtColor(mask_array, cv2.COLOR_BGR2GRAY) + mask_inv = cv2.bitwise_not(mask_cv) + + # Inpaint Image + inpainted_result = cv2.inpaint(image_cv, mask_inv, 3, cv2.INPAINT_TELEA) + inpainted_image = Image.fromarray(cv2.cvtColor(inpainted_result, cv2.COLOR_BGR2RGB)) + return inpainted_image diff --git a/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasOutpaintGraph.ts b/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasOutpaintGraph.ts index 2098d3c3e1..64c60206fd 100644 --- a/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasOutpaintGraph.ts +++ b/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasOutpaintGraph.ts @@ -506,6 +506,14 @@ export const buildCanvasOutpaintGraph = ( }; } + if (infillMethod === 'cv2') { + graph.nodes[INPAINT_INFILL] = { + type: 'infill_cv2', + id: INPAINT_INFILL, + is_intermediate: true, + }; + } + if (infillMethod === 'tile') { graph.nodes[INPAINT_INFILL] = { type: 'infill_tile', diff --git a/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasSDXLOutpaintGraph.ts b/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasSDXLOutpaintGraph.ts index e8c3ce6435..6ab1e7e7b2 100644 --- a/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasSDXLOutpaintGraph.ts +++ b/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasSDXLOutpaintGraph.ts @@ -521,6 +521,14 @@ export const buildCanvasSDXLOutpaintGraph = ( }; } + if (infillMethod === 'cv2') { + graph.nodes[INPAINT_INFILL] = { + type: 'infill_cv2', + id: INPAINT_INFILL, + is_intermediate: true, + }; + } + if (infillMethod === 'tile') { graph.nodes[INPAINT_INFILL] = { type: 'infill_tile', diff --git a/invokeai/frontend/web/src/services/api/schema.d.ts b/invokeai/frontend/web/src/services/api/schema.d.ts index 85470183c1..863498879d 100644 --- a/invokeai/frontend/web/src/services/api/schema.d.ts +++ b/invokeai/frontend/web/src/services/api/schema.d.ts @@ -780,6 +780,39 @@ export type components = { */ type: "boolean_output"; }; + /** + * CV2 Infill + * @description Infills transparent areas of an image using OpenCV Inpainting + */ + CV2InfillInvocation: { + /** + * 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; + /** + * Workflow + * @description The workflow to save with the image + */ + workflow?: string; + /** + * Image + * @description The image to infill + */ + image?: components["schemas"]["ImageField"]; + /** + * Type + * @default infill_cv2 + * @enum {string} + */ + type: "infill_cv2"; + }; /** * Canny Processor * @description Canny edge detection for ControlNet @@ -1173,7 +1206,6 @@ export type components = { /** * Collection * @description The collection of conditioning tensors - * @default 0 */ collection?: components["schemas"]["ConditioningField"][]; /** @@ -1522,7 +1554,7 @@ export type components = { /** * App Version * @description The version of InvokeAI used to generate this image - * @default 3.0.2post1 + * @default 3.1.0 */ app_version?: string; /** @@ -2214,7 +2246,7 @@ export type components = { * @description The nodes in this graph */ nodes?: { - [key: string]: components["schemas"]["BooleanInvocation"] | components["schemas"]["BooleanCollectionInvocation"] | components["schemas"]["IntegerInvocation"] | components["schemas"]["IntegerCollectionInvocation"] | components["schemas"]["FloatInvocation"] | components["schemas"]["FloatCollectionInvocation"] | components["schemas"]["StringInvocation"] | components["schemas"]["StringCollectionInvocation"] | components["schemas"]["ImageInvocation"] | components["schemas"]["ImageCollectionInvocation"] | components["schemas"]["LatentsInvocation"] | components["schemas"]["LatentsCollectionInvocation"] | components["schemas"]["ColorInvocation"] | components["schemas"]["ConditioningInvocation"] | components["schemas"]["ConditioningCollectionInvocation"] | components["schemas"]["ControlNetInvocation"] | components["schemas"]["ImageProcessorInvocation"] | components["schemas"]["MainModelLoaderInvocation"] | components["schemas"]["LoraLoaderInvocation"] | components["schemas"]["SDXLLoraLoaderInvocation"] | components["schemas"]["VaeLoaderInvocation"] | components["schemas"]["SeamlessModeInvocation"] | components["schemas"]["MetadataAccumulatorInvocation"] | components["schemas"]["SDXLModelLoaderInvocation"] | components["schemas"]["SDXLRefinerModelLoaderInvocation"] | components["schemas"]["CompelInvocation"] | components["schemas"]["SDXLCompelPromptInvocation"] | components["schemas"]["SDXLRefinerCompelPromptInvocation"] | components["schemas"]["ClipSkipInvocation"] | components["schemas"]["CreateDenoiseMaskInvocation"] | components["schemas"]["DenoiseLatentsInvocation"] | components["schemas"]["LatentsToImageInvocation"] | components["schemas"]["ResizeLatentsInvocation"] | components["schemas"]["ScaleLatentsInvocation"] | components["schemas"]["ImageToLatentsInvocation"] | components["schemas"]["BlendLatentsInvocation"] | components["schemas"]["ONNXPromptInvocation"] | components["schemas"]["ONNXTextToLatentsInvocation"] | components["schemas"]["ONNXLatentsToImageInvocation"] | components["schemas"]["OnnxModelLoaderInvocation"] | components["schemas"]["ShowImageInvocation"] | components["schemas"]["BlankImageInvocation"] | components["schemas"]["ImageCropInvocation"] | components["schemas"]["ImagePasteInvocation"] | components["schemas"]["MaskFromAlphaInvocation"] | components["schemas"]["ImageMultiplyInvocation"] | components["schemas"]["ImageChannelInvocation"] | components["schemas"]["ImageConvertInvocation"] | components["schemas"]["ImageBlurInvocation"] | components["schemas"]["ImageResizeInvocation"] | components["schemas"]["ImageScaleInvocation"] | components["schemas"]["ImageLerpInvocation"] | components["schemas"]["ImageInverseLerpInvocation"] | components["schemas"]["ImageNSFWBlurInvocation"] | components["schemas"]["ImageWatermarkInvocation"] | components["schemas"]["MaskEdgeInvocation"] | components["schemas"]["MaskCombineInvocation"] | components["schemas"]["ColorCorrectInvocation"] | components["schemas"]["ImageHueAdjustmentInvocation"] | components["schemas"]["ImageLuminosityAdjustmentInvocation"] | components["schemas"]["ImageSaturationAdjustmentInvocation"] | components["schemas"]["DynamicPromptInvocation"] | components["schemas"]["PromptsFromFileInvocation"] | components["schemas"]["CvInpaintInvocation"] | components["schemas"]["FloatLinearRangeInvocation"] | components["schemas"]["StepParamEasingInvocation"] | components["schemas"]["AddInvocation"] | components["schemas"]["SubtractInvocation"] | components["schemas"]["MultiplyInvocation"] | components["schemas"]["DivideInvocation"] | components["schemas"]["RandomIntInvocation"] | components["schemas"]["NoiseInvocation"] | components["schemas"]["RangeInvocation"] | components["schemas"]["RangeOfSizeInvocation"] | components["schemas"]["RandomRangeInvocation"] | components["schemas"]["ESRGANInvocation"] | components["schemas"]["InfillColorInvocation"] | components["schemas"]["InfillTileInvocation"] | components["schemas"]["InfillPatchMatchInvocation"] | components["schemas"]["LaMaInfillInvocation"] | components["schemas"]["GraphInvocation"] | components["schemas"]["IterateInvocation"] | components["schemas"]["CollectInvocation"] | components["schemas"]["CannyImageProcessorInvocation"] | components["schemas"]["HedImageProcessorInvocation"] | components["schemas"]["LineartImageProcessorInvocation"] | components["schemas"]["LineartAnimeImageProcessorInvocation"] | components["schemas"]["OpenposeImageProcessorInvocation"] | components["schemas"]["MidasDepthImageProcessorInvocation"] | components["schemas"]["NormalbaeImageProcessorInvocation"] | components["schemas"]["MlsdImageProcessorInvocation"] | components["schemas"]["PidiImageProcessorInvocation"] | components["schemas"]["ContentShuffleImageProcessorInvocation"] | components["schemas"]["ZoeDepthImageProcessorInvocation"] | components["schemas"]["MediapipeFaceProcessorInvocation"] | components["schemas"]["LeresImageProcessorInvocation"] | components["schemas"]["TileResamplerProcessorInvocation"] | components["schemas"]["SegmentAnythingProcessorInvocation"]; + [key: string]: components["schemas"]["BooleanInvocation"] | components["schemas"]["BooleanCollectionInvocation"] | components["schemas"]["IntegerInvocation"] | components["schemas"]["IntegerCollectionInvocation"] | components["schemas"]["FloatInvocation"] | components["schemas"]["FloatCollectionInvocation"] | components["schemas"]["StringInvocation"] | components["schemas"]["StringCollectionInvocation"] | components["schemas"]["ImageInvocation"] | components["schemas"]["ImageCollectionInvocation"] | components["schemas"]["LatentsInvocation"] | components["schemas"]["LatentsCollectionInvocation"] | components["schemas"]["ColorInvocation"] | components["schemas"]["ConditioningInvocation"] | components["schemas"]["ConditioningCollectionInvocation"] | components["schemas"]["ControlNetInvocation"] | components["schemas"]["ImageProcessorInvocation"] | components["schemas"]["MainModelLoaderInvocation"] | components["schemas"]["LoraLoaderInvocation"] | components["schemas"]["SDXLLoraLoaderInvocation"] | components["schemas"]["VaeLoaderInvocation"] | components["schemas"]["SeamlessModeInvocation"] | components["schemas"]["MetadataAccumulatorInvocation"] | components["schemas"]["RangeInvocation"] | components["schemas"]["RangeOfSizeInvocation"] | components["schemas"]["RandomRangeInvocation"] | components["schemas"]["CompelInvocation"] | components["schemas"]["SDXLCompelPromptInvocation"] | components["schemas"]["SDXLRefinerCompelPromptInvocation"] | components["schemas"]["ClipSkipInvocation"] | components["schemas"]["CvInpaintInvocation"] | components["schemas"]["ShowImageInvocation"] | components["schemas"]["BlankImageInvocation"] | components["schemas"]["ImageCropInvocation"] | components["schemas"]["ImagePasteInvocation"] | components["schemas"]["MaskFromAlphaInvocation"] | components["schemas"]["ImageMultiplyInvocation"] | components["schemas"]["ImageChannelInvocation"] | components["schemas"]["ImageConvertInvocation"] | components["schemas"]["ImageBlurInvocation"] | components["schemas"]["ImageResizeInvocation"] | components["schemas"]["ImageScaleInvocation"] | components["schemas"]["ImageLerpInvocation"] | components["schemas"]["ImageInverseLerpInvocation"] | components["schemas"]["ImageNSFWBlurInvocation"] | components["schemas"]["ImageWatermarkInvocation"] | components["schemas"]["MaskEdgeInvocation"] | components["schemas"]["MaskCombineInvocation"] | components["schemas"]["ColorCorrectInvocation"] | components["schemas"]["ImageHueAdjustmentInvocation"] | components["schemas"]["ImageLuminosityAdjustmentInvocation"] | components["schemas"]["ImageSaturationAdjustmentInvocation"] | components["schemas"]["InfillColorInvocation"] | components["schemas"]["InfillTileInvocation"] | components["schemas"]["InfillPatchMatchInvocation"] | components["schemas"]["LaMaInfillInvocation"] | components["schemas"]["CV2InfillInvocation"] | components["schemas"]["SchedulerInvocation"] | components["schemas"]["CreateDenoiseMaskInvocation"] | components["schemas"]["DenoiseLatentsInvocation"] | components["schemas"]["LatentsToImageInvocation"] | components["schemas"]["ResizeLatentsInvocation"] | components["schemas"]["ScaleLatentsInvocation"] | components["schemas"]["ImageToLatentsInvocation"] | components["schemas"]["BlendLatentsInvocation"] | components["schemas"]["AddInvocation"] | components["schemas"]["SubtractInvocation"] | components["schemas"]["MultiplyInvocation"] | components["schemas"]["DivideInvocation"] | components["schemas"]["RandomIntInvocation"] | components["schemas"]["NoiseInvocation"] | components["schemas"]["ONNXPromptInvocation"] | components["schemas"]["ONNXTextToLatentsInvocation"] | components["schemas"]["ONNXLatentsToImageInvocation"] | components["schemas"]["OnnxModelLoaderInvocation"] | components["schemas"]["FloatLinearRangeInvocation"] | components["schemas"]["StepParamEasingInvocation"] | components["schemas"]["DynamicPromptInvocation"] | components["schemas"]["PromptsFromFileInvocation"] | components["schemas"]["SDXLModelLoaderInvocation"] | components["schemas"]["SDXLRefinerModelLoaderInvocation"] | components["schemas"]["ESRGANInvocation"] | components["schemas"]["GraphInvocation"] | components["schemas"]["IterateInvocation"] | components["schemas"]["CollectInvocation"] | components["schemas"]["CannyImageProcessorInvocation"] | components["schemas"]["HedImageProcessorInvocation"] | components["schemas"]["LineartImageProcessorInvocation"] | components["schemas"]["LineartAnimeImageProcessorInvocation"] | components["schemas"]["OpenposeImageProcessorInvocation"] | components["schemas"]["MidasDepthImageProcessorInvocation"] | components["schemas"]["NormalbaeImageProcessorInvocation"] | components["schemas"]["MlsdImageProcessorInvocation"] | components["schemas"]["PidiImageProcessorInvocation"] | components["schemas"]["ContentShuffleImageProcessorInvocation"] | components["schemas"]["ZoeDepthImageProcessorInvocation"] | components["schemas"]["MediapipeFaceProcessorInvocation"] | components["schemas"]["LeresImageProcessorInvocation"] | components["schemas"]["TileResamplerProcessorInvocation"] | components["schemas"]["SegmentAnythingProcessorInvocation"]; }; /** * Edges @@ -2257,7 +2289,7 @@ export type components = { * @description The results of node executions */ results: { - [key: string]: components["schemas"]["BooleanOutput"] | components["schemas"]["BooleanCollectionOutput"] | components["schemas"]["IntegerOutput"] | components["schemas"]["IntegerCollectionOutput"] | components["schemas"]["FloatOutput"] | components["schemas"]["FloatCollectionOutput"] | components["schemas"]["StringOutput"] | components["schemas"]["StringCollectionOutput"] | components["schemas"]["ImageOutput"] | components["schemas"]["ImageCollectionOutput"] | components["schemas"]["DenoiseMaskOutput"] | components["schemas"]["LatentsOutput"] | components["schemas"]["LatentsCollectionOutput"] | components["schemas"]["ColorOutput"] | components["schemas"]["ColorCollectionOutput"] | components["schemas"]["ConditioningOutput"] | components["schemas"]["ConditioningCollectionOutput"] | components["schemas"]["ControlOutput"] | components["schemas"]["ModelLoaderOutput"] | components["schemas"]["LoraLoaderOutput"] | components["schemas"]["SDXLLoraLoaderOutput"] | components["schemas"]["VaeLoaderOutput"] | components["schemas"]["SeamlessModeOutput"] | components["schemas"]["MetadataAccumulatorOutput"] | components["schemas"]["SDXLModelLoaderOutput"] | components["schemas"]["SDXLRefinerModelLoaderOutput"] | components["schemas"]["ClipSkipInvocationOutput"] | components["schemas"]["ONNXModelLoaderOutput"] | components["schemas"]["NoiseOutput"] | components["schemas"]["GraphInvocationOutput"] | components["schemas"]["IterateInvocationOutput"] | components["schemas"]["CollectInvocationOutput"]; + [key: string]: components["schemas"]["BooleanOutput"] | components["schemas"]["BooleanCollectionOutput"] | components["schemas"]["IntegerOutput"] | components["schemas"]["IntegerCollectionOutput"] | components["schemas"]["FloatOutput"] | components["schemas"]["FloatCollectionOutput"] | components["schemas"]["StringOutput"] | components["schemas"]["StringCollectionOutput"] | components["schemas"]["ImageOutput"] | components["schemas"]["ImageCollectionOutput"] | components["schemas"]["DenoiseMaskOutput"] | components["schemas"]["LatentsOutput"] | components["schemas"]["LatentsCollectionOutput"] | components["schemas"]["ColorOutput"] | components["schemas"]["ColorCollectionOutput"] | components["schemas"]["ConditioningOutput"] | components["schemas"]["ConditioningCollectionOutput"] | components["schemas"]["ControlOutput"] | components["schemas"]["ModelLoaderOutput"] | components["schemas"]["LoraLoaderOutput"] | components["schemas"]["SDXLLoraLoaderOutput"] | components["schemas"]["VaeLoaderOutput"] | components["schemas"]["SeamlessModeOutput"] | components["schemas"]["MetadataAccumulatorOutput"] | components["schemas"]["ClipSkipInvocationOutput"] | components["schemas"]["SchedulerOutput"] | components["schemas"]["NoiseOutput"] | components["schemas"]["ONNXModelLoaderOutput"] | components["schemas"]["SDXLModelLoaderOutput"] | components["schemas"]["SDXLRefinerModelLoaderOutput"] | components["schemas"]["GraphInvocationOutput"] | components["schemas"]["IterateInvocationOutput"] | components["schemas"]["CollectInvocationOutput"]; }; /** * Errors @@ -2506,7 +2538,6 @@ export type components = { /** * Collection * @description The collection of image values - * @default 0 */ collection?: components["schemas"]["ImageField"][]; /** @@ -3563,7 +3594,6 @@ export type components = { /** * Collection * @description The collection of integer values - * @default 0 */ collection?: number[]; /** @@ -6147,6 +6177,61 @@ export type components = { */ type: "lscale"; }; + /** + * Scheduler + * @description Selects a scheduler. + */ + SchedulerInvocation: { + /** + * 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; + /** + * Workflow + * @description The workflow to save with the image + */ + workflow?: string; + /** + * Scheduler + * @description Scheduler to use during inference + * @default euler + * @enum {string} + */ + scheduler?: "ddim" | "ddpm" | "deis" | "lms" | "lms_k" | "pndm" | "heun" | "heun_k" | "euler" | "euler_k" | "euler_a" | "kdpm_2" | "kdpm_2_a" | "dpmpp_2s" | "dpmpp_2s_k" | "dpmpp_2m" | "dpmpp_2m_k" | "dpmpp_2m_sde" | "dpmpp_2m_sde_k" | "dpmpp_sde" | "dpmpp_sde_k" | "unipc"; + /** + * Type + * @default scheduler + * @enum {string} + */ + type: "scheduler"; + }; + /** + * SchedulerOutput + * @description Base class for all invocation outputs. + * + * All invocation outputs must use the `@invocation_output` decorator to provide their unique type. + */ + SchedulerOutput: { + /** + * Scheduler + * @description Scheduler to use during inference + * @enum {string} + */ + scheduler: "ddim" | "ddpm" | "deis" | "lms" | "lms_k" | "pndm" | "heun" | "heun_k" | "euler" | "euler_k" | "euler_a" | "kdpm_2" | "kdpm_2_a" | "dpmpp_2s" | "dpmpp_2s_k" | "dpmpp_2m" | "dpmpp_2m_k" | "dpmpp_2m_sde" | "dpmpp_2m_sde_k" | "dpmpp_sde" | "dpmpp_sde_k" | "unipc"; + /** + * Type + * @default scheduler_output + * @enum {string} + */ + type: "scheduler_output"; + }; /** * SchedulerPredictionType * @description An enumeration. @@ -6990,17 +7075,11 @@ export type components = { */ StableDiffusion1ModelFormat: "checkpoint" | "diffusers"; /** - * ControlNetModelFormat + * StableDiffusion2ModelFormat * @description An enumeration. * @enum {string} */ - ControlNetModelFormat: "checkpoint" | "diffusers"; - /** - * StableDiffusionOnnxModelFormat - * @description An enumeration. - * @enum {string} - */ - StableDiffusionOnnxModelFormat: "olive" | "onnx"; + StableDiffusion2ModelFormat: "checkpoint" | "diffusers"; /** * StableDiffusionXLModelFormat * @description An enumeration. @@ -7008,11 +7087,17 @@ export type components = { */ StableDiffusionXLModelFormat: "checkpoint" | "diffusers"; /** - * StableDiffusion2ModelFormat + * StableDiffusionOnnxModelFormat * @description An enumeration. * @enum {string} */ - StableDiffusion2ModelFormat: "checkpoint" | "diffusers"; + StableDiffusionOnnxModelFormat: "olive" | "onnx"; + /** + * ControlNetModelFormat + * @description An enumeration. + * @enum {string} + */ + ControlNetModelFormat: "checkpoint" | "diffusers"; }; responses: never; parameters: never; @@ -7129,7 +7214,7 @@ export type operations = { }; requestBody: { content: { - "application/json": components["schemas"]["BooleanInvocation"] | components["schemas"]["BooleanCollectionInvocation"] | components["schemas"]["IntegerInvocation"] | components["schemas"]["IntegerCollectionInvocation"] | components["schemas"]["FloatInvocation"] | components["schemas"]["FloatCollectionInvocation"] | components["schemas"]["StringInvocation"] | components["schemas"]["StringCollectionInvocation"] | components["schemas"]["ImageInvocation"] | components["schemas"]["ImageCollectionInvocation"] | components["schemas"]["LatentsInvocation"] | components["schemas"]["LatentsCollectionInvocation"] | components["schemas"]["ColorInvocation"] | components["schemas"]["ConditioningInvocation"] | components["schemas"]["ConditioningCollectionInvocation"] | components["schemas"]["ControlNetInvocation"] | components["schemas"]["ImageProcessorInvocation"] | components["schemas"]["MainModelLoaderInvocation"] | components["schemas"]["LoraLoaderInvocation"] | components["schemas"]["SDXLLoraLoaderInvocation"] | components["schemas"]["VaeLoaderInvocation"] | components["schemas"]["SeamlessModeInvocation"] | components["schemas"]["MetadataAccumulatorInvocation"] | components["schemas"]["SDXLModelLoaderInvocation"] | components["schemas"]["SDXLRefinerModelLoaderInvocation"] | components["schemas"]["CompelInvocation"] | components["schemas"]["SDXLCompelPromptInvocation"] | components["schemas"]["SDXLRefinerCompelPromptInvocation"] | components["schemas"]["ClipSkipInvocation"] | components["schemas"]["CreateDenoiseMaskInvocation"] | components["schemas"]["DenoiseLatentsInvocation"] | components["schemas"]["LatentsToImageInvocation"] | components["schemas"]["ResizeLatentsInvocation"] | components["schemas"]["ScaleLatentsInvocation"] | components["schemas"]["ImageToLatentsInvocation"] | components["schemas"]["BlendLatentsInvocation"] | components["schemas"]["ONNXPromptInvocation"] | components["schemas"]["ONNXTextToLatentsInvocation"] | components["schemas"]["ONNXLatentsToImageInvocation"] | components["schemas"]["OnnxModelLoaderInvocation"] | components["schemas"]["ShowImageInvocation"] | components["schemas"]["BlankImageInvocation"] | components["schemas"]["ImageCropInvocation"] | components["schemas"]["ImagePasteInvocation"] | components["schemas"]["MaskFromAlphaInvocation"] | components["schemas"]["ImageMultiplyInvocation"] | components["schemas"]["ImageChannelInvocation"] | components["schemas"]["ImageConvertInvocation"] | components["schemas"]["ImageBlurInvocation"] | components["schemas"]["ImageResizeInvocation"] | components["schemas"]["ImageScaleInvocation"] | components["schemas"]["ImageLerpInvocation"] | components["schemas"]["ImageInverseLerpInvocation"] | components["schemas"]["ImageNSFWBlurInvocation"] | components["schemas"]["ImageWatermarkInvocation"] | components["schemas"]["MaskEdgeInvocation"] | components["schemas"]["MaskCombineInvocation"] | components["schemas"]["ColorCorrectInvocation"] | components["schemas"]["ImageHueAdjustmentInvocation"] | components["schemas"]["ImageLuminosityAdjustmentInvocation"] | components["schemas"]["ImageSaturationAdjustmentInvocation"] | components["schemas"]["DynamicPromptInvocation"] | components["schemas"]["PromptsFromFileInvocation"] | components["schemas"]["CvInpaintInvocation"] | components["schemas"]["FloatLinearRangeInvocation"] | components["schemas"]["StepParamEasingInvocation"] | components["schemas"]["AddInvocation"] | components["schemas"]["SubtractInvocation"] | components["schemas"]["MultiplyInvocation"] | components["schemas"]["DivideInvocation"] | components["schemas"]["RandomIntInvocation"] | components["schemas"]["NoiseInvocation"] | components["schemas"]["RangeInvocation"] | components["schemas"]["RangeOfSizeInvocation"] | components["schemas"]["RandomRangeInvocation"] | components["schemas"]["ESRGANInvocation"] | components["schemas"]["InfillColorInvocation"] | components["schemas"]["InfillTileInvocation"] | components["schemas"]["InfillPatchMatchInvocation"] | components["schemas"]["LaMaInfillInvocation"] | components["schemas"]["GraphInvocation"] | components["schemas"]["IterateInvocation"] | components["schemas"]["CollectInvocation"] | components["schemas"]["CannyImageProcessorInvocation"] | components["schemas"]["HedImageProcessorInvocation"] | components["schemas"]["LineartImageProcessorInvocation"] | components["schemas"]["LineartAnimeImageProcessorInvocation"] | components["schemas"]["OpenposeImageProcessorInvocation"] | components["schemas"]["MidasDepthImageProcessorInvocation"] | components["schemas"]["NormalbaeImageProcessorInvocation"] | components["schemas"]["MlsdImageProcessorInvocation"] | components["schemas"]["PidiImageProcessorInvocation"] | components["schemas"]["ContentShuffleImageProcessorInvocation"] | components["schemas"]["ZoeDepthImageProcessorInvocation"] | components["schemas"]["MediapipeFaceProcessorInvocation"] | components["schemas"]["LeresImageProcessorInvocation"] | components["schemas"]["TileResamplerProcessorInvocation"] | components["schemas"]["SegmentAnythingProcessorInvocation"]; + "application/json": components["schemas"]["BooleanInvocation"] | components["schemas"]["BooleanCollectionInvocation"] | components["schemas"]["IntegerInvocation"] | components["schemas"]["IntegerCollectionInvocation"] | components["schemas"]["FloatInvocation"] | components["schemas"]["FloatCollectionInvocation"] | components["schemas"]["StringInvocation"] | components["schemas"]["StringCollectionInvocation"] | components["schemas"]["ImageInvocation"] | components["schemas"]["ImageCollectionInvocation"] | components["schemas"]["LatentsInvocation"] | components["schemas"]["LatentsCollectionInvocation"] | components["schemas"]["ColorInvocation"] | components["schemas"]["ConditioningInvocation"] | components["schemas"]["ConditioningCollectionInvocation"] | components["schemas"]["ControlNetInvocation"] | components["schemas"]["ImageProcessorInvocation"] | components["schemas"]["MainModelLoaderInvocation"] | components["schemas"]["LoraLoaderInvocation"] | components["schemas"]["SDXLLoraLoaderInvocation"] | components["schemas"]["VaeLoaderInvocation"] | components["schemas"]["SeamlessModeInvocation"] | components["schemas"]["MetadataAccumulatorInvocation"] | components["schemas"]["RangeInvocation"] | components["schemas"]["RangeOfSizeInvocation"] | components["schemas"]["RandomRangeInvocation"] | components["schemas"]["CompelInvocation"] | components["schemas"]["SDXLCompelPromptInvocation"] | components["schemas"]["SDXLRefinerCompelPromptInvocation"] | components["schemas"]["ClipSkipInvocation"] | components["schemas"]["CvInpaintInvocation"] | components["schemas"]["ShowImageInvocation"] | components["schemas"]["BlankImageInvocation"] | components["schemas"]["ImageCropInvocation"] | components["schemas"]["ImagePasteInvocation"] | components["schemas"]["MaskFromAlphaInvocation"] | components["schemas"]["ImageMultiplyInvocation"] | components["schemas"]["ImageChannelInvocation"] | components["schemas"]["ImageConvertInvocation"] | components["schemas"]["ImageBlurInvocation"] | components["schemas"]["ImageResizeInvocation"] | components["schemas"]["ImageScaleInvocation"] | components["schemas"]["ImageLerpInvocation"] | components["schemas"]["ImageInverseLerpInvocation"] | components["schemas"]["ImageNSFWBlurInvocation"] | components["schemas"]["ImageWatermarkInvocation"] | components["schemas"]["MaskEdgeInvocation"] | components["schemas"]["MaskCombineInvocation"] | components["schemas"]["ColorCorrectInvocation"] | components["schemas"]["ImageHueAdjustmentInvocation"] | components["schemas"]["ImageLuminosityAdjustmentInvocation"] | components["schemas"]["ImageSaturationAdjustmentInvocation"] | components["schemas"]["InfillColorInvocation"] | components["schemas"]["InfillTileInvocation"] | components["schemas"]["InfillPatchMatchInvocation"] | components["schemas"]["LaMaInfillInvocation"] | components["schemas"]["CV2InfillInvocation"] | components["schemas"]["SchedulerInvocation"] | components["schemas"]["CreateDenoiseMaskInvocation"] | components["schemas"]["DenoiseLatentsInvocation"] | components["schemas"]["LatentsToImageInvocation"] | components["schemas"]["ResizeLatentsInvocation"] | components["schemas"]["ScaleLatentsInvocation"] | components["schemas"]["ImageToLatentsInvocation"] | components["schemas"]["BlendLatentsInvocation"] | components["schemas"]["AddInvocation"] | components["schemas"]["SubtractInvocation"] | components["schemas"]["MultiplyInvocation"] | components["schemas"]["DivideInvocation"] | components["schemas"]["RandomIntInvocation"] | components["schemas"]["NoiseInvocation"] | components["schemas"]["ONNXPromptInvocation"] | components["schemas"]["ONNXTextToLatentsInvocation"] | components["schemas"]["ONNXLatentsToImageInvocation"] | components["schemas"]["OnnxModelLoaderInvocation"] | components["schemas"]["FloatLinearRangeInvocation"] | components["schemas"]["StepParamEasingInvocation"] | components["schemas"]["DynamicPromptInvocation"] | components["schemas"]["PromptsFromFileInvocation"] | components["schemas"]["SDXLModelLoaderInvocation"] | components["schemas"]["SDXLRefinerModelLoaderInvocation"] | components["schemas"]["ESRGANInvocation"] | components["schemas"]["GraphInvocation"] | components["schemas"]["IterateInvocation"] | components["schemas"]["CollectInvocation"] | components["schemas"]["CannyImageProcessorInvocation"] | components["schemas"]["HedImageProcessorInvocation"] | components["schemas"]["LineartImageProcessorInvocation"] | components["schemas"]["LineartAnimeImageProcessorInvocation"] | components["schemas"]["OpenposeImageProcessorInvocation"] | components["schemas"]["MidasDepthImageProcessorInvocation"] | components["schemas"]["NormalbaeImageProcessorInvocation"] | components["schemas"]["MlsdImageProcessorInvocation"] | components["schemas"]["PidiImageProcessorInvocation"] | components["schemas"]["ContentShuffleImageProcessorInvocation"] | components["schemas"]["ZoeDepthImageProcessorInvocation"] | components["schemas"]["MediapipeFaceProcessorInvocation"] | components["schemas"]["LeresImageProcessorInvocation"] | components["schemas"]["TileResamplerProcessorInvocation"] | components["schemas"]["SegmentAnythingProcessorInvocation"]; }; }; responses: { @@ -7170,7 +7255,7 @@ export type operations = { }; requestBody: { content: { - "application/json": components["schemas"]["BooleanInvocation"] | components["schemas"]["BooleanCollectionInvocation"] | components["schemas"]["IntegerInvocation"] | components["schemas"]["IntegerCollectionInvocation"] | components["schemas"]["FloatInvocation"] | components["schemas"]["FloatCollectionInvocation"] | components["schemas"]["StringInvocation"] | components["schemas"]["StringCollectionInvocation"] | components["schemas"]["ImageInvocation"] | components["schemas"]["ImageCollectionInvocation"] | components["schemas"]["LatentsInvocation"] | components["schemas"]["LatentsCollectionInvocation"] | components["schemas"]["ColorInvocation"] | components["schemas"]["ConditioningInvocation"] | components["schemas"]["ConditioningCollectionInvocation"] | components["schemas"]["ControlNetInvocation"] | components["schemas"]["ImageProcessorInvocation"] | components["schemas"]["MainModelLoaderInvocation"] | components["schemas"]["LoraLoaderInvocation"] | components["schemas"]["SDXLLoraLoaderInvocation"] | components["schemas"]["VaeLoaderInvocation"] | components["schemas"]["SeamlessModeInvocation"] | components["schemas"]["MetadataAccumulatorInvocation"] | components["schemas"]["SDXLModelLoaderInvocation"] | components["schemas"]["SDXLRefinerModelLoaderInvocation"] | components["schemas"]["CompelInvocation"] | components["schemas"]["SDXLCompelPromptInvocation"] | components["schemas"]["SDXLRefinerCompelPromptInvocation"] | components["schemas"]["ClipSkipInvocation"] | components["schemas"]["CreateDenoiseMaskInvocation"] | components["schemas"]["DenoiseLatentsInvocation"] | components["schemas"]["LatentsToImageInvocation"] | components["schemas"]["ResizeLatentsInvocation"] | components["schemas"]["ScaleLatentsInvocation"] | components["schemas"]["ImageToLatentsInvocation"] | components["schemas"]["BlendLatentsInvocation"] | components["schemas"]["ONNXPromptInvocation"] | components["schemas"]["ONNXTextToLatentsInvocation"] | components["schemas"]["ONNXLatentsToImageInvocation"] | components["schemas"]["OnnxModelLoaderInvocation"] | components["schemas"]["ShowImageInvocation"] | components["schemas"]["BlankImageInvocation"] | components["schemas"]["ImageCropInvocation"] | components["schemas"]["ImagePasteInvocation"] | components["schemas"]["MaskFromAlphaInvocation"] | components["schemas"]["ImageMultiplyInvocation"] | components["schemas"]["ImageChannelInvocation"] | components["schemas"]["ImageConvertInvocation"] | components["schemas"]["ImageBlurInvocation"] | components["schemas"]["ImageResizeInvocation"] | components["schemas"]["ImageScaleInvocation"] | components["schemas"]["ImageLerpInvocation"] | components["schemas"]["ImageInverseLerpInvocation"] | components["schemas"]["ImageNSFWBlurInvocation"] | components["schemas"]["ImageWatermarkInvocation"] | components["schemas"]["MaskEdgeInvocation"] | components["schemas"]["MaskCombineInvocation"] | components["schemas"]["ColorCorrectInvocation"] | components["schemas"]["ImageHueAdjustmentInvocation"] | components["schemas"]["ImageLuminosityAdjustmentInvocation"] | components["schemas"]["ImageSaturationAdjustmentInvocation"] | components["schemas"]["DynamicPromptInvocation"] | components["schemas"]["PromptsFromFileInvocation"] | components["schemas"]["CvInpaintInvocation"] | components["schemas"]["FloatLinearRangeInvocation"] | components["schemas"]["StepParamEasingInvocation"] | components["schemas"]["AddInvocation"] | components["schemas"]["SubtractInvocation"] | components["schemas"]["MultiplyInvocation"] | components["schemas"]["DivideInvocation"] | components["schemas"]["RandomIntInvocation"] | components["schemas"]["NoiseInvocation"] | components["schemas"]["RangeInvocation"] | components["schemas"]["RangeOfSizeInvocation"] | components["schemas"]["RandomRangeInvocation"] | components["schemas"]["ESRGANInvocation"] | components["schemas"]["InfillColorInvocation"] | components["schemas"]["InfillTileInvocation"] | components["schemas"]["InfillPatchMatchInvocation"] | components["schemas"]["LaMaInfillInvocation"] | components["schemas"]["GraphInvocation"] | components["schemas"]["IterateInvocation"] | components["schemas"]["CollectInvocation"] | components["schemas"]["CannyImageProcessorInvocation"] | components["schemas"]["HedImageProcessorInvocation"] | components["schemas"]["LineartImageProcessorInvocation"] | components["schemas"]["LineartAnimeImageProcessorInvocation"] | components["schemas"]["OpenposeImageProcessorInvocation"] | components["schemas"]["MidasDepthImageProcessorInvocation"] | components["schemas"]["NormalbaeImageProcessorInvocation"] | components["schemas"]["MlsdImageProcessorInvocation"] | components["schemas"]["PidiImageProcessorInvocation"] | components["schemas"]["ContentShuffleImageProcessorInvocation"] | components["schemas"]["ZoeDepthImageProcessorInvocation"] | components["schemas"]["MediapipeFaceProcessorInvocation"] | components["schemas"]["LeresImageProcessorInvocation"] | components["schemas"]["TileResamplerProcessorInvocation"] | components["schemas"]["SegmentAnythingProcessorInvocation"]; + "application/json": components["schemas"]["BooleanInvocation"] | components["schemas"]["BooleanCollectionInvocation"] | components["schemas"]["IntegerInvocation"] | components["schemas"]["IntegerCollectionInvocation"] | components["schemas"]["FloatInvocation"] | components["schemas"]["FloatCollectionInvocation"] | components["schemas"]["StringInvocation"] | components["schemas"]["StringCollectionInvocation"] | components["schemas"]["ImageInvocation"] | components["schemas"]["ImageCollectionInvocation"] | components["schemas"]["LatentsInvocation"] | components["schemas"]["LatentsCollectionInvocation"] | components["schemas"]["ColorInvocation"] | components["schemas"]["ConditioningInvocation"] | components["schemas"]["ConditioningCollectionInvocation"] | components["schemas"]["ControlNetInvocation"] | components["schemas"]["ImageProcessorInvocation"] | components["schemas"]["MainModelLoaderInvocation"] | components["schemas"]["LoraLoaderInvocation"] | components["schemas"]["SDXLLoraLoaderInvocation"] | components["schemas"]["VaeLoaderInvocation"] | components["schemas"]["SeamlessModeInvocation"] | components["schemas"]["MetadataAccumulatorInvocation"] | components["schemas"]["RangeInvocation"] | components["schemas"]["RangeOfSizeInvocation"] | components["schemas"]["RandomRangeInvocation"] | components["schemas"]["CompelInvocation"] | components["schemas"]["SDXLCompelPromptInvocation"] | components["schemas"]["SDXLRefinerCompelPromptInvocation"] | components["schemas"]["ClipSkipInvocation"] | components["schemas"]["CvInpaintInvocation"] | components["schemas"]["ShowImageInvocation"] | components["schemas"]["BlankImageInvocation"] | components["schemas"]["ImageCropInvocation"] | components["schemas"]["ImagePasteInvocation"] | components["schemas"]["MaskFromAlphaInvocation"] | components["schemas"]["ImageMultiplyInvocation"] | components["schemas"]["ImageChannelInvocation"] | components["schemas"]["ImageConvertInvocation"] | components["schemas"]["ImageBlurInvocation"] | components["schemas"]["ImageResizeInvocation"] | components["schemas"]["ImageScaleInvocation"] | components["schemas"]["ImageLerpInvocation"] | components["schemas"]["ImageInverseLerpInvocation"] | components["schemas"]["ImageNSFWBlurInvocation"] | components["schemas"]["ImageWatermarkInvocation"] | components["schemas"]["MaskEdgeInvocation"] | components["schemas"]["MaskCombineInvocation"] | components["schemas"]["ColorCorrectInvocation"] | components["schemas"]["ImageHueAdjustmentInvocation"] | components["schemas"]["ImageLuminosityAdjustmentInvocation"] | components["schemas"]["ImageSaturationAdjustmentInvocation"] | components["schemas"]["InfillColorInvocation"] | components["schemas"]["InfillTileInvocation"] | components["schemas"]["InfillPatchMatchInvocation"] | components["schemas"]["LaMaInfillInvocation"] | components["schemas"]["CV2InfillInvocation"] | components["schemas"]["SchedulerInvocation"] | components["schemas"]["CreateDenoiseMaskInvocation"] | components["schemas"]["DenoiseLatentsInvocation"] | components["schemas"]["LatentsToImageInvocation"] | components["schemas"]["ResizeLatentsInvocation"] | components["schemas"]["ScaleLatentsInvocation"] | components["schemas"]["ImageToLatentsInvocation"] | components["schemas"]["BlendLatentsInvocation"] | components["schemas"]["AddInvocation"] | components["schemas"]["SubtractInvocation"] | components["schemas"]["MultiplyInvocation"] | components["schemas"]["DivideInvocation"] | components["schemas"]["RandomIntInvocation"] | components["schemas"]["NoiseInvocation"] | components["schemas"]["ONNXPromptInvocation"] | components["schemas"]["ONNXTextToLatentsInvocation"] | components["schemas"]["ONNXLatentsToImageInvocation"] | components["schemas"]["OnnxModelLoaderInvocation"] | components["schemas"]["FloatLinearRangeInvocation"] | components["schemas"]["StepParamEasingInvocation"] | components["schemas"]["DynamicPromptInvocation"] | components["schemas"]["PromptsFromFileInvocation"] | components["schemas"]["SDXLModelLoaderInvocation"] | components["schemas"]["SDXLRefinerModelLoaderInvocation"] | components["schemas"]["ESRGANInvocation"] | components["schemas"]["GraphInvocation"] | components["schemas"]["IterateInvocation"] | components["schemas"]["CollectInvocation"] | components["schemas"]["CannyImageProcessorInvocation"] | components["schemas"]["HedImageProcessorInvocation"] | components["schemas"]["LineartImageProcessorInvocation"] | components["schemas"]["LineartAnimeImageProcessorInvocation"] | components["schemas"]["OpenposeImageProcessorInvocation"] | components["schemas"]["MidasDepthImageProcessorInvocation"] | components["schemas"]["NormalbaeImageProcessorInvocation"] | components["schemas"]["MlsdImageProcessorInvocation"] | components["schemas"]["PidiImageProcessorInvocation"] | components["schemas"]["ContentShuffleImageProcessorInvocation"] | components["schemas"]["ZoeDepthImageProcessorInvocation"] | components["schemas"]["MediapipeFaceProcessorInvocation"] | components["schemas"]["LeresImageProcessorInvocation"] | components["schemas"]["TileResamplerProcessorInvocation"] | components["schemas"]["SegmentAnythingProcessorInvocation"]; }; }; responses: { From 5151798a16432fab6f0b6c6a2ace02809ed1f160 Mon Sep 17 00:00:00 2001 From: Sergey Borisov Date: Fri, 1 Sep 2023 20:50:39 +0300 Subject: [PATCH 07/26] Cleanup memory after model run --- invokeai/backend/image_util/lama.py | 1 + 1 file changed, 1 insertion(+) diff --git a/invokeai/backend/image_util/lama.py b/invokeai/backend/image_util/lama.py index 9c5e0153c4..1a60fc9a05 100644 --- a/invokeai/backend/image_util/lama.py +++ b/invokeai/backend/image_util/lama.py @@ -53,5 +53,6 @@ class LaMA: del model gc.collect() + torch.cuda.empty_cache() return infilled_image From a36cf2f1ddc94bcb9a7c83cca6ecca310d727dc7 Mon Sep 17 00:00:00 2001 From: Sergey Borisov Date: Fri, 1 Sep 2023 23:08:46 +0300 Subject: [PATCH 08/26] Add scale to patchmatch --- invokeai/app/invocations/infill.py | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/invokeai/app/invocations/infill.py b/invokeai/app/invocations/infill.py index 69d2a04b75..c783ac3058 100644 --- a/invokeai/app/invocations/infill.py +++ b/invokeai/app/invocations/infill.py @@ -14,6 +14,7 @@ from invokeai.backend.image_util.patchmatch import PatchMatch from ..models.image import ImageCategory, ResourceOrigin from .baseinvocation import BaseInvocation, InputField, InvocationContext, invocation +from .image import PIL_RESAMPLING_MODES, PIL_RESAMPLING_MAP def infill_methods() -> list[str]: @@ -193,15 +194,35 @@ class InfillPatchMatchInvocation(BaseInvocation): """Infills transparent areas of an image using the PatchMatch algorithm""" image: ImageField = InputField(description="The image to infill") + downscale: float = InputField(default=2.0, gt=0, description="Run patchmatch on downscaled image to speedup infill") + resample_mode: PIL_RESAMPLING_MODES = InputField(default="bicubic", description="The resampling mode") def invoke(self, context: InvocationContext) -> ImageOutput: - image = context.services.images.get_pil_image(self.image.image_name) + image = context.services.images.get_pil_image(self.image.image_name).convert("RGBA") + + resample_mode = PIL_RESAMPLING_MAP[self.resample_mode] + + infill_image = image.copy() + width = int(image.width / self.downscale) + height = int(image.height / self.downscale) + infill_image = infill_image.resize( + (width, height), + resample=resample_mode, + ) if PatchMatch.patchmatch_available(): - infilled = infill_patchmatch(image.copy()) + infilled = infill_patchmatch(infill_image) else: raise ValueError("PatchMatch is not available on this system") + infilled = infilled.resize( + (image.width, image.height), + resample=resample_mode, + ) + + infilled.paste(image, (0, 0), mask=image.split()[-1]) + #image.paste(infilled, (0, 0), mask=image.split()[-1]) + image_dto = context.services.images.create( image=infilled, image_origin=ResourceOrigin.INTERNAL, From 469fc49a2fc6126b82344a14a57e363afc6f5ecb Mon Sep 17 00:00:00 2001 From: blessedcoolant <54517381+blessedcoolant@users.noreply.github.com> Date: Sat, 2 Sep 2023 08:36:01 +1200 Subject: [PATCH 09/26] ui: Make patchmatch downscale options optional --- invokeai/app/invocations/infill.py | 10 ++++++---- invokeai/frontend/web/src/services/api/schema.d.ts | 13 +++++++++++++ 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/invokeai/app/invocations/infill.py b/invokeai/app/invocations/infill.py index c783ac3058..1b9581b8f7 100644 --- a/invokeai/app/invocations/infill.py +++ b/invokeai/app/invocations/infill.py @@ -14,7 +14,7 @@ from invokeai.backend.image_util.patchmatch import PatchMatch from ..models.image import ImageCategory, ResourceOrigin from .baseinvocation import BaseInvocation, InputField, InvocationContext, invocation -from .image import PIL_RESAMPLING_MODES, PIL_RESAMPLING_MAP +from .image import PIL_RESAMPLING_MAP, PIL_RESAMPLING_MODES def infill_methods() -> list[str]: @@ -194,8 +194,10 @@ class InfillPatchMatchInvocation(BaseInvocation): """Infills transparent areas of an image using the PatchMatch algorithm""" image: ImageField = InputField(description="The image to infill") - downscale: float = InputField(default=2.0, gt=0, description="Run patchmatch on downscaled image to speedup infill") - resample_mode: PIL_RESAMPLING_MODES = InputField(default="bicubic", description="The resampling mode") + downscale: Optional[float] = InputField( + default=2.0, gt=0, description="Run patchmatch on downscaled image to speedup infill" + ) + resample_mode: Optional[PIL_RESAMPLING_MODES] = InputField(default="bicubic", description="The resampling mode") def invoke(self, context: InvocationContext) -> ImageOutput: image = context.services.images.get_pil_image(self.image.image_name).convert("RGBA") @@ -221,7 +223,7 @@ class InfillPatchMatchInvocation(BaseInvocation): ) infilled.paste(image, (0, 0), mask=image.split()[-1]) - #image.paste(infilled, (0, 0), mask=image.split()[-1]) + # image.paste(infilled, (0, 0), mask=image.split()[-1]) image_dto = context.services.images.create( image=infilled, diff --git a/invokeai/frontend/web/src/services/api/schema.d.ts b/invokeai/frontend/web/src/services/api/schema.d.ts index 863498879d..7658601715 100644 --- a/invokeai/frontend/web/src/services/api/schema.d.ts +++ b/invokeai/frontend/web/src/services/api/schema.d.ts @@ -3519,6 +3519,19 @@ export type components = { * @description The image to infill */ image?: components["schemas"]["ImageField"]; + /** + * Downscale + * @description Run patchmatch on downscaled image to speedup infill + * @default 2 + */ + downscale?: number; + /** + * Resample Mode + * @description The resampling mode + * @default bicubic + * @enum {string} + */ + resample_mode?: "nearest" | "box" | "bilinear" | "hamming" | "bicubic" | "lanczos"; /** * Type * @default infill_patchmatch From b73216ef8178b86f651f0937b7f156230245bab6 Mon Sep 17 00:00:00 2001 From: blessedcoolant <54517381+blessedcoolant@users.noreply.github.com> Date: Sat, 2 Sep 2023 10:23:14 +1200 Subject: [PATCH 10/26] feat: Decrement Brush Size by 1 for values under 5 for more precision --- .../IAICanvasToolbar/IAICanvasToolChooserOptions.tsx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/invokeai/frontend/web/src/features/canvas/components/IAICanvasToolbar/IAICanvasToolChooserOptions.tsx b/invokeai/frontend/web/src/features/canvas/components/IAICanvasToolbar/IAICanvasToolChooserOptions.tsx index a3e8f6af8b..10e01ccac4 100644 --- a/invokeai/frontend/web/src/features/canvas/components/IAICanvasToolbar/IAICanvasToolChooserOptions.tsx +++ b/invokeai/frontend/web/src/features/canvas/components/IAICanvasToolbar/IAICanvasToolChooserOptions.tsx @@ -118,7 +118,11 @@ const IAICanvasToolChooserOptions = () => { useHotkeys( ['BracketLeft'], () => { - dispatch(setBrushSize(Math.max(brushSize - 5, 5))); + if (brushSize - 5 <= 5) { + dispatch(setBrushSize(Math.max(brushSize - 1, 1))); + } else { + dispatch(setBrushSize(Math.max(brushSize - 5, 1))); + } }, { enabled: () => !isStaging, From 497f66e6823e1adf119cb46590df8cadd810e837 Mon Sep 17 00:00:00 2001 From: blessedcoolant <54517381+blessedcoolant@users.noreply.github.com> Date: Sat, 2 Sep 2023 10:24:32 +1200 Subject: [PATCH 11/26] feat: Add Patchmatch Downscale control to UI + refine the ui there --- invokeai/frontend/web/public/locales/en.json | 1 + .../graphBuilders/buildCanvasOutpaintGraph.ts | 6 +- .../buildCanvasSDXLOutpaintGraph.ts | 5 +- .../ParamInfillAndScalingCollapse.tsx | 4 +- .../InfillAndScaling/ParamInfillOptions.tsx | 29 +++++++++ .../ParamInfillPatchmatchDownscaleSize.tsx | 59 +++++++++++++++++++ .../InfillAndScaling/ParamInfillTilesize.tsx | 14 ++--- .../parameters/store/generationSlice.ts | 21 +++++-- 8 files changed, 120 insertions(+), 19 deletions(-) create mode 100644 invokeai/frontend/web/src/features/parameters/components/Parameters/Canvas/InfillAndScaling/ParamInfillOptions.tsx create mode 100644 invokeai/frontend/web/src/features/parameters/components/Parameters/Canvas/InfillAndScaling/ParamInfillPatchmatchDownscaleSize.tsx diff --git a/invokeai/frontend/web/public/locales/en.json b/invokeai/frontend/web/public/locales/en.json index 32144749bd..bcca3fc8e7 100644 --- a/invokeai/frontend/web/public/locales/en.json +++ b/invokeai/frontend/web/public/locales/en.json @@ -520,6 +520,7 @@ "scaledHeight": "Scaled H", "infillMethod": "Infill Method", "tileSize": "Tile Size", + "patchmatchDownScaleSize": "Downscale", "boundingBoxHeader": "Bounding Box", "seamCorrectionHeader": "Seam Correction", "infillScalingHeader": "Infill and Scaling", diff --git a/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasOutpaintGraph.ts b/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasOutpaintGraph.ts index 64c60206fd..20f81611fe 100644 --- a/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasOutpaintGraph.ts +++ b/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasOutpaintGraph.ts @@ -73,7 +73,8 @@ export const buildCanvasOutpaintGraph = ( maskBlur, canvasCoherenceSteps, canvasCoherenceStrength, - tileSize, + infillTileSize, + infillPatchmatchDownscaleSize, infillMethod, clipSkip, seamlessXAxis, @@ -495,6 +496,7 @@ export const buildCanvasOutpaintGraph = ( type: 'infill_patchmatch', id: INPAINT_INFILL, is_intermediate: true, + downscale: infillPatchmatchDownscaleSize, }; } @@ -519,7 +521,7 @@ export const buildCanvasOutpaintGraph = ( type: 'infill_tile', id: INPAINT_INFILL, is_intermediate: true, - tile_size: tileSize, + tile_size: infillTileSize, }; } diff --git a/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasSDXLOutpaintGraph.ts b/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasSDXLOutpaintGraph.ts index 6ab1e7e7b2..bd06228beb 100644 --- a/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasSDXLOutpaintGraph.ts +++ b/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasSDXLOutpaintGraph.ts @@ -74,7 +74,7 @@ export const buildCanvasSDXLOutpaintGraph = ( maskBlur, canvasCoherenceSteps, canvasCoherenceStrength, - tileSize, + infillTileSize, infillMethod, seamlessXAxis, seamlessYAxis, @@ -510,6 +510,7 @@ export const buildCanvasSDXLOutpaintGraph = ( type: 'infill_patchmatch', id: INPAINT_INFILL, is_intermediate: true, + downscale: infillPatchmatchDownscaleSize, }; } @@ -534,7 +535,7 @@ export const buildCanvasSDXLOutpaintGraph = ( type: 'infill_tile', id: INPAINT_INFILL, is_intermediate: true, - tile_size: tileSize, + tile_size: infillTileSize, }; } diff --git a/invokeai/frontend/web/src/features/parameters/components/Parameters/Canvas/InfillAndScaling/ParamInfillAndScalingCollapse.tsx b/invokeai/frontend/web/src/features/parameters/components/Parameters/Canvas/InfillAndScaling/ParamInfillAndScalingCollapse.tsx index 8907e46e5f..b9c5e218ce 100644 --- a/invokeai/frontend/web/src/features/parameters/components/Parameters/Canvas/InfillAndScaling/ParamInfillAndScalingCollapse.tsx +++ b/invokeai/frontend/web/src/features/parameters/components/Parameters/Canvas/InfillAndScaling/ParamInfillAndScalingCollapse.tsx @@ -5,7 +5,7 @@ import { useTranslation } from 'react-i18next'; import IAICollapse from 'common/components/IAICollapse'; import SubParametersWrapper from '../../SubParametersWrapper'; import ParamInfillMethod from './ParamInfillMethod'; -import ParamInfillTilesize from './ParamInfillTilesize'; +import ParamInfillOptions from './ParamInfillOptions'; import ParamScaleBeforeProcessing from './ParamScaleBeforeProcessing'; import ParamScaledHeight from './ParamScaledHeight'; import ParamScaledWidth from './ParamScaledWidth'; @@ -18,7 +18,7 @@ const ParamInfillCollapse = () => { - + diff --git a/invokeai/frontend/web/src/features/parameters/components/Parameters/Canvas/InfillAndScaling/ParamInfillOptions.tsx b/invokeai/frontend/web/src/features/parameters/components/Parameters/Canvas/InfillAndScaling/ParamInfillOptions.tsx new file mode 100644 index 0000000000..14c2663d5e --- /dev/null +++ b/invokeai/frontend/web/src/features/parameters/components/Parameters/Canvas/InfillAndScaling/ParamInfillOptions.tsx @@ -0,0 +1,29 @@ +import { Flex } from '@chakra-ui/react'; +import { createSelector } from '@reduxjs/toolkit'; +import { useAppSelector } from 'app/store/storeHooks'; +import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions'; +import { generationSelector } from 'features/parameters/store/generationSelectors'; +import ParamInfillPatchmatchDownscaleSize from './ParamInfillPatchmatchDownscaleSize'; +import ParamInfillTilesize from './ParamInfillTilesize'; + +const selector = createSelector( + [generationSelector], + (parameters) => { + const { infillMethod } = parameters; + + return { + infillMethod, + }; + }, + defaultSelectorOptions +); + +export default function ParamInfillOptions() { + const { infillMethod } = useAppSelector(selector); + return ( + + {infillMethod === 'tile' && } + {infillMethod === 'patchmatch' && } + + ); +} diff --git a/invokeai/frontend/web/src/features/parameters/components/Parameters/Canvas/InfillAndScaling/ParamInfillPatchmatchDownscaleSize.tsx b/invokeai/frontend/web/src/features/parameters/components/Parameters/Canvas/InfillAndScaling/ParamInfillPatchmatchDownscaleSize.tsx new file mode 100644 index 0000000000..d8e9749422 --- /dev/null +++ b/invokeai/frontend/web/src/features/parameters/components/Parameters/Canvas/InfillAndScaling/ParamInfillPatchmatchDownscaleSize.tsx @@ -0,0 +1,59 @@ +import { createSelector } from '@reduxjs/toolkit'; +import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; +import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions'; +import IAISlider from 'common/components/IAISlider'; +import { generationSelector } from 'features/parameters/store/generationSelectors'; +import { setInfillPatchmatchDownscaleSize } from 'features/parameters/store/generationSlice'; +import { memo, useCallback } from 'react'; + +import { useTranslation } from 'react-i18next'; + +const selector = createSelector( + [generationSelector], + (parameters) => { + const { infillPatchmatchDownscaleSize, infillMethod } = parameters; + + return { + infillPatchmatchDownscaleSize, + infillMethod, + }; + }, + defaultSelectorOptions +); + +const ParamInfillPatchmatchDownscaleSize = () => { + const dispatch = useAppDispatch(); + const { infillPatchmatchDownscaleSize, infillMethod } = + useAppSelector(selector); + + const { t } = useTranslation(); + + const handleChange = useCallback( + (v: number) => { + dispatch(setInfillPatchmatchDownscaleSize(v)); + }, + [dispatch] + ); + + const handleReset = useCallback(() => { + dispatch(setInfillPatchmatchDownscaleSize(2)); + }, [dispatch]); + + return ( + + ); +}; + +export default memo(ParamInfillPatchmatchDownscaleSize); diff --git a/invokeai/frontend/web/src/features/parameters/components/Parameters/Canvas/InfillAndScaling/ParamInfillTilesize.tsx b/invokeai/frontend/web/src/features/parameters/components/Parameters/Canvas/InfillAndScaling/ParamInfillTilesize.tsx index fc6f02184c..4cb587767e 100644 --- a/invokeai/frontend/web/src/features/parameters/components/Parameters/Canvas/InfillAndScaling/ParamInfillTilesize.tsx +++ b/invokeai/frontend/web/src/features/parameters/components/Parameters/Canvas/InfillAndScaling/ParamInfillTilesize.tsx @@ -3,7 +3,7 @@ import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions'; import IAISlider from 'common/components/IAISlider'; import { generationSelector } from 'features/parameters/store/generationSelectors'; -import { setTileSize } from 'features/parameters/store/generationSlice'; +import { setInfillTileSize } from 'features/parameters/store/generationSlice'; import { memo, useCallback } from 'react'; import { useTranslation } from 'react-i18next'; @@ -11,10 +11,10 @@ import { useTranslation } from 'react-i18next'; const selector = createSelector( [generationSelector], (parameters) => { - const { tileSize, infillMethod } = parameters; + const { infillTileSize, infillMethod } = parameters; return { - tileSize, + infillTileSize, infillMethod, }; }, @@ -23,19 +23,19 @@ const selector = createSelector( const ParamInfillTileSize = () => { const dispatch = useAppDispatch(); - const { tileSize, infillMethod } = useAppSelector(selector); + const { infillTileSize, infillMethod } = useAppSelector(selector); const { t } = useTranslation(); const handleChange = useCallback( (v: number) => { - dispatch(setTileSize(v)); + dispatch(setInfillTileSize(v)); }, [dispatch] ); const handleReset = useCallback(() => { - dispatch(setTileSize(32)); + dispatch(setInfillTileSize(32)); }, [dispatch]); return ( @@ -45,7 +45,7 @@ const ParamInfillTileSize = () => { min={16} max={64} sliderNumberInputProps={{ max: 256 }} - value={tileSize} + value={infillTileSize} onChange={handleChange} withInput withSliderMarks diff --git a/invokeai/frontend/web/src/features/parameters/store/generationSlice.ts b/invokeai/frontend/web/src/features/parameters/store/generationSlice.ts index 5a830b6e95..7bbfc5149d 100644 --- a/invokeai/frontend/web/src/features/parameters/store/generationSlice.ts +++ b/invokeai/frontend/web/src/features/parameters/store/generationSlice.ts @@ -47,7 +47,8 @@ export interface GenerationState { shouldUseNoiseSettings: boolean; steps: StepsParam; threshold: number; - tileSize: number; + infillTileSize: number; + infillPatchmatchDownscaleSize: number; variationAmount: number; width: WidthParam; shouldUseSymmetry: boolean; @@ -87,7 +88,8 @@ export const initialGenerationState: GenerationState = { shouldUseNoiseSettings: false, steps: 50, threshold: 0, - tileSize: 32, + infillTileSize: 32, + infillPatchmatchDownscaleSize: 2, variationAmount: 0.1, width: 512, shouldUseSymmetry: false, @@ -212,12 +214,18 @@ export const generationSlice = createSlice({ setCanvasCoherenceStrength: (state, action: PayloadAction) => { state.canvasCoherenceStrength = action.payload; }, - setTileSize: (state, action: PayloadAction) => { - state.tileSize = action.payload; - }, setInfillMethod: (state, action: PayloadAction) => { state.infillMethod = action.payload; }, + setInfillTileSize: (state, action: PayloadAction) => { + state.infillTileSize = action.payload; + }, + setInfillPatchmatchDownscaleSize: ( + state, + action: PayloadAction + ) => { + state.infillPatchmatchDownscaleSize = action.payload; + }, setShouldUseSymmetry: (state, action: PayloadAction) => { state.shouldUseSymmetry = action.payload; }, @@ -332,7 +340,8 @@ export const { setShouldRandomizeSeed, setSteps, setThreshold, - setTileSize, + setInfillTileSize, + setInfillPatchmatchDownscaleSize, setVariationAmount, setShouldUseSymmetry, setHorizontalSymmetrySteps, From fded8bee39ab5499840d8bb7bef99d40ea620e4b Mon Sep 17 00:00:00 2001 From: blessedcoolant <54517381+blessedcoolant@users.noreply.github.com> Date: Sat, 2 Sep 2023 23:13:29 +1200 Subject: [PATCH 12/26] chore: Regen schema --- .../frontend/web/src/services/api/schema.d.ts | 38 +++++++++---------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/invokeai/frontend/web/src/services/api/schema.d.ts b/invokeai/frontend/web/src/services/api/schema.d.ts index 7658601715..821bd8bd2c 100644 --- a/invokeai/frontend/web/src/services/api/schema.d.ts +++ b/invokeai/frontend/web/src/services/api/schema.d.ts @@ -1678,15 +1678,15 @@ export type components = { */ refiner_scheduler?: string; /** - * Refiner Positive Aesthetic Store + * Refiner Positive Aesthetic Score * @description The aesthetic score used for the refiner */ - refiner_positive_aesthetic_store?: number; + refiner_positive_aesthetic_score?: number; /** - * Refiner Negative Aesthetic Store + * Refiner Negative Aesthetic Score * @description The aesthetic score used for the refiner */ - refiner_negative_aesthetic_store?: number; + refiner_negative_aesthetic_score?: number; /** * Refiner Start * @description The start value used for refiner denoising @@ -4627,15 +4627,15 @@ export type components = { */ refiner_scheduler?: string; /** - * Refiner Positive Aesthetic Store + * Refiner Positive Aesthetic Score * @description The aesthetic score used for the refiner */ - refiner_positive_aesthetic_store?: number; + refiner_positive_aesthetic_score?: number; /** - * Refiner Negative Aesthetic Store + * Refiner Negative Aesthetic Score * @description The aesthetic score used for the refiner */ - refiner_negative_aesthetic_store?: number; + refiner_negative_aesthetic_score?: number; /** * Refiner Start * @description The start value used for refiner denoising @@ -5852,12 +5852,12 @@ export type components = { */ target_height?: number; /** - * Clip + * CLIP 1 * @description CLIP (tokenizer, text encoder, LoRAs) and skipped layer count */ clip?: components["schemas"]["ClipField"]; /** - * Clip2 + * CLIP 2 * @description CLIP (tokenizer, text encoder, LoRAs) and skipped layer count */ clip2?: components["schemas"]["ClipField"]; @@ -5901,7 +5901,7 @@ export type components = { */ weight?: number; /** - * UNET + * UNet * @description UNet (scheduler, LoRAs) */ unet?: components["schemas"]["UNetField"]; @@ -7081,12 +7081,6 @@ export type components = { /** Ui Order */ ui_order?: number; }; - /** - * StableDiffusion1ModelFormat - * @description An enumeration. - * @enum {string} - */ - StableDiffusion1ModelFormat: "checkpoint" | "diffusers"; /** * StableDiffusion2ModelFormat * @description An enumeration. @@ -7100,17 +7094,23 @@ export type components = { */ StableDiffusionXLModelFormat: "checkpoint" | "diffusers"; /** - * StableDiffusionOnnxModelFormat + * StableDiffusion1ModelFormat * @description An enumeration. * @enum {string} */ - StableDiffusionOnnxModelFormat: "olive" | "onnx"; + StableDiffusion1ModelFormat: "checkpoint" | "diffusers"; /** * ControlNetModelFormat * @description An enumeration. * @enum {string} */ ControlNetModelFormat: "checkpoint" | "diffusers"; + /** + * StableDiffusionOnnxModelFormat + * @description An enumeration. + * @enum {string} + */ + StableDiffusionOnnxModelFormat: "olive" | "onnx"; }; responses: never; parameters: never; From b5f42bedce4827562d709b4c42d6e673199be4f9 Mon Sep 17 00:00:00 2001 From: blessedcoolant <54517381+blessedcoolant@users.noreply.github.com> Date: Sun, 3 Sep 2023 00:34:37 +1200 Subject: [PATCH 13/26] feat: Add Coherence Mode --- invokeai/frontend/web/public/locales/en.json | 1 + .../nodes/util/graphBuilders/addVAEToGraph.ts | 26 +-- .../graphBuilders/buildCanvasInpaintGraph.ts | 145 +++++++------- .../graphBuilders/buildCanvasOutpaintGraph.ts | 186 +++++++++-------- .../buildCanvasSDXLInpaintGraph.ts | 145 +++++++------- .../buildCanvasSDXLOutpaintGraph.ts | 187 +++++++++--------- .../ParamCanvasCoherenceMode.tsx | 41 ++++ .../ParamCompositingSettingsCollapse.tsx | 2 + .../parameters/store/generationSlice.ts | 10 + .../parameters/types/parameterSchemas.ts | 16 ++ 10 files changed, 422 insertions(+), 337 deletions(-) create mode 100644 invokeai/frontend/web/src/features/parameters/components/Parameters/Canvas/Compositing/CoherencePass/ParamCanvasCoherenceMode.tsx diff --git a/invokeai/frontend/web/public/locales/en.json b/invokeai/frontend/web/public/locales/en.json index bcca3fc8e7..125554fc40 100644 --- a/invokeai/frontend/web/public/locales/en.json +++ b/invokeai/frontend/web/public/locales/en.json @@ -511,6 +511,7 @@ "maskBlur": "Blur", "maskBlurMethod": "Blur Method", "coherencePassHeader": "Coherence Pass", + "coherenceMode": "Mode", "coherenceSteps": "Steps", "coherenceStrength": "Strength", "seamLowThreshold": "Low", diff --git a/invokeai/frontend/web/src/features/nodes/util/graphBuilders/addVAEToGraph.ts b/invokeai/frontend/web/src/features/nodes/util/graphBuilders/addVAEToGraph.ts index 34d37e9b17..8e77799293 100644 --- a/invokeai/frontend/web/src/features/nodes/util/graphBuilders/addVAEToGraph.ts +++ b/invokeai/frontend/web/src/features/nodes/util/graphBuilders/addVAEToGraph.ts @@ -32,7 +32,7 @@ export const addVAEToGraph = ( graph: NonNullableGraph, modelLoaderNodeId: string = MAIN_MODEL_LOADER ): void => { - const { vae } = state.generation; + const { vae, canvasCoherenceMode } = state.generation; const { boundingBoxScaleMethod } = state.canvas; const { shouldUseSDXLRefiner } = state.sdxl; @@ -136,16 +136,6 @@ export const addVAEToGraph = ( field: 'vae', }, }, - { - source: { - node_id: isAutoVae ? modelLoaderNodeId : VAE_LOADER, - field: isAutoVae && isOnnxModel ? 'vae_decoder' : 'vae', - }, - destination: { - node_id: CANVAS_COHERENCE_INPAINT_CREATE_MASK, - field: 'vae', - }, - }, { source: { node_id: isAutoVae ? modelLoaderNodeId : VAE_LOADER, @@ -157,6 +147,20 @@ export const addVAEToGraph = ( }, } ); + + // Handle Coherence Mode + if (canvasCoherenceMode === 'edge') { + graph.edges.push({ + source: { + node_id: isAutoVae ? modelLoaderNodeId : VAE_LOADER, + field: isAutoVae && isOnnxModel ? 'vae_decoder' : 'vae', + }, + destination: { + node_id: CANVAS_COHERENCE_INPAINT_CREATE_MASK, + field: 'vae', + }, + }); + } } if (shouldUseSDXLRefiner) { diff --git a/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasInpaintGraph.ts b/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasInpaintGraph.ts index 1783174079..a87d20a08d 100644 --- a/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasInpaintGraph.ts +++ b/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasInpaintGraph.ts @@ -70,6 +70,7 @@ export const buildCanvasInpaintGraph = ( shouldUseCpuNoise, maskBlur, maskBlurMethod, + canvasCoherenceMode, canvasCoherenceSteps, canvasCoherenceStrength, clipSkip, @@ -176,21 +177,6 @@ export const buildCanvasInpaintGraph = ( b: 1, is_intermediate: true, }, - [CANVAS_COHERENCE_MASK_EDGE]: { - type: 'mask_edge', - id: CANVAS_COHERENCE_MASK_EDGE, - is_intermediate: true, - edge_blur: maskBlur, - edge_size: maskBlur * 2, - low_threshold: 100, - high_threshold: 200, - }, - [CANVAS_COHERENCE_INPAINT_CREATE_MASK]: { - type: 'create_denoise_mask', - id: CANVAS_COHERENCE_INPAINT_CREATE_MASK, - is_intermediate: true, - fp32: vaePrecision === 'fp32' ? true : false, - }, [CANVAS_COHERENCE_DENOISE_LATENTS]: { type: 'denoise_latents', id: CANVAS_COHERENCE_DENOISE_LATENTS, @@ -333,27 +319,6 @@ export const buildCanvasInpaintGraph = ( field: 'denoise_mask', }, }, - // Create Coherence Mask - { - source: { - node_id: CANVAS_COHERENCE_MASK_EDGE, - field: 'image', - }, - destination: { - node_id: CANVAS_COHERENCE_INPAINT_CREATE_MASK, - field: 'mask', - }, - }, - { - source: { - node_id: CANVAS_COHERENCE_INPAINT_CREATE_MASK, - field: 'denoise_mask', - }, - destination: { - node_id: CANVAS_COHERENCE_DENOISE_LATENTS, - field: 'denoise_mask', - }, - }, // Iterate { source: { @@ -537,26 +502,6 @@ export const buildCanvasInpaintGraph = ( field: 'image', }, }, - { - source: { - node_id: INPAINT_IMAGE_RESIZE_UP, - field: 'image', - }, - destination: { - node_id: CANVAS_COHERENCE_INPAINT_CREATE_MASK, - field: 'image', - }, - }, - { - source: { - node_id: MASK_RESIZE_UP, - field: 'image', - }, - destination: { - node_id: CANVAS_COHERENCE_MASK_EDGE, - field: 'image', - }, - }, // Color Correct The Inpainted Result { source: { @@ -618,16 +563,6 @@ export const buildCanvasInpaintGraph = ( ...(graph.nodes[INPAINT_CREATE_MASK] as CreateDenoiseMaskInvocation), image: canvasInitImage, }; - graph.nodes[CANVAS_COHERENCE_INPAINT_CREATE_MASK] = { - ...(graph.nodes[ - CANVAS_COHERENCE_INPAINT_CREATE_MASK - ] as CreateDenoiseMaskInvocation), - image: canvasInitImage, - }; - graph.nodes[CANVAS_COHERENCE_MASK_EDGE] = { - ...(graph.nodes[CANVAS_COHERENCE_MASK_EDGE] as MaskEdgeInvocation), - image: canvasMaskImage, - }; graph.edges.push( // Color Correct The Inpainted Result @@ -654,6 +589,84 @@ export const buildCanvasInpaintGraph = ( ); } + // Handle Coherence Mode + if (canvasCoherenceMode === 'edge') { + graph.nodes[CANVAS_COHERENCE_MASK_EDGE] = { + type: 'mask_edge', + id: CANVAS_COHERENCE_MASK_EDGE, + is_intermediate: true, + edge_blur: maskBlur, + edge_size: maskBlur * 2, + low_threshold: 100, + high_threshold: 200, + }; + graph.nodes[CANVAS_COHERENCE_INPAINT_CREATE_MASK] = { + type: 'create_denoise_mask', + id: CANVAS_COHERENCE_INPAINT_CREATE_MASK, + is_intermediate: true, + fp32: vaePrecision === 'fp32' ? true : false, + }; + + if (isUsingScaledDimensions) { + graph.edges.push( + { + source: { + node_id: MASK_RESIZE_UP, + field: 'image', + }, + destination: { + node_id: CANVAS_COHERENCE_MASK_EDGE, + field: 'image', + }, + }, + { + source: { + node_id: INPAINT_IMAGE_RESIZE_UP, + field: 'image', + }, + destination: { + node_id: CANVAS_COHERENCE_INPAINT_CREATE_MASK, + field: 'image', + }, + } + ); + } else { + graph.nodes[CANVAS_COHERENCE_INPAINT_CREATE_MASK] = { + ...(graph.nodes[ + CANVAS_COHERENCE_INPAINT_CREATE_MASK + ] as CreateDenoiseMaskInvocation), + image: canvasInitImage, + }; + graph.nodes[CANVAS_COHERENCE_MASK_EDGE] = { + ...(graph.nodes[CANVAS_COHERENCE_MASK_EDGE] as MaskEdgeInvocation), + image: canvasMaskImage, + }; + } + + graph.edges.push( + { + source: { + node_id: CANVAS_COHERENCE_MASK_EDGE, + field: 'image', + }, + destination: { + node_id: CANVAS_COHERENCE_INPAINT_CREATE_MASK, + field: 'mask', + }, + }, + { + source: { + node_id: CANVAS_COHERENCE_INPAINT_CREATE_MASK, + field: 'denoise_mask', + }, + destination: { + node_id: CANVAS_COHERENCE_DENOISE_LATENTS, + field: 'denoise_mask', + }, + } + ); + } + // Handle Seed if (shouldRandomizeSeed) { // Random int node to generate the starting seed diff --git a/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasOutpaintGraph.ts b/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasOutpaintGraph.ts index 20f81611fe..fe2d3f1698 100644 --- a/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasOutpaintGraph.ts +++ b/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasOutpaintGraph.ts @@ -71,6 +71,7 @@ export const buildCanvasOutpaintGraph = ( shouldUseNoiseSettings, shouldUseCpuNoise, maskBlur, + canvasCoherenceMode, canvasCoherenceSteps, canvasCoherenceStrength, infillTileSize, @@ -185,21 +186,6 @@ export const buildCanvasOutpaintGraph = ( b: 1, is_intermediate: true, }, - [CANVAS_COHERENCE_MASK_EDGE]: { - type: 'mask_edge', - id: CANVAS_COHERENCE_MASK_EDGE, - is_intermediate: true, - edge_blur: maskBlur, - edge_size: maskBlur * 2, - low_threshold: 100, - high_threshold: 200, - }, - [CANVAS_COHERENCE_INPAINT_CREATE_MASK]: { - type: 'create_denoise_mask', - id: CANVAS_COHERENCE_INPAINT_CREATE_MASK, - is_intermediate: true, - fp32: vaePrecision === 'fp32' ? true : false, - }, [CANVAS_COHERENCE_DENOISE_LATENTS]: { type: 'denoise_latents', id: CANVAS_COHERENCE_DENOISE_LATENTS, @@ -363,27 +349,6 @@ export const buildCanvasOutpaintGraph = ( field: 'denoise_mask', }, }, - // Create Coherence Mask - { - source: { - node_id: CANVAS_COHERENCE_MASK_EDGE, - field: 'image', - }, - destination: { - node_id: CANVAS_COHERENCE_INPAINT_CREATE_MASK, - field: 'mask', - }, - }, - { - source: { - node_id: CANVAS_COHERENCE_INPAINT_CREATE_MASK, - field: 'denoise_mask', - }, - destination: { - node_id: CANVAS_COHERENCE_DENOISE_LATENTS, - field: 'denoise_mask', - }, - }, // Iterate { source: { @@ -476,6 +441,16 @@ export const buildCanvasOutpaintGraph = ( field: 'latents', }, }, + { + source: { + node_id: INPAINT_INFILL, + field: 'image', + }, + destination: { + node_id: INPAINT_CREATE_MASK, + field: 'image', + }, + }, // Decode the result from Inpaint { source: { @@ -588,26 +563,7 @@ export const buildCanvasOutpaintGraph = ( field: 'image', }, }, - { - source: { - node_id: INPAINT_INFILL, - field: 'image', - }, - destination: { - node_id: INPAINT_CREATE_MASK, - field: 'image', - }, - }, - { - source: { - node_id: INPAINT_INFILL, - field: 'image', - }, - destination: { - node_id: CANVAS_COHERENCE_INPAINT_CREATE_MASK, - field: 'image', - }, - }, + // Take combined mask and resize and then blur { source: { @@ -619,16 +575,7 @@ export const buildCanvasOutpaintGraph = ( field: 'image', }, }, - { - source: { - node_id: MASK_RESIZE_UP, - field: 'image', - }, - destination: { - node_id: CANVAS_COHERENCE_MASK_EDGE, - field: 'image', - }, - }, + // Resize Results Down { source: { @@ -712,37 +659,6 @@ export const buildCanvasOutpaintGraph = ( }; graph.edges.push( - // Take combined mask and plug it to blur - { - source: { - node_id: INPAINT_INFILL, - field: 'image', - }, - destination: { - node_id: INPAINT_CREATE_MASK, - field: 'image', - }, - }, - { - source: { - node_id: MASK_COMBINE, - field: 'image', - }, - destination: { - node_id: CANVAS_COHERENCE_MASK_EDGE, - field: 'image', - }, - }, - { - source: { - node_id: INPAINT_INFILL, - field: 'image', - }, - destination: { - node_id: CANVAS_COHERENCE_INPAINT_CREATE_MASK, - field: 'image', - }, - }, // Color Correct The Inpainted Result { source: { @@ -777,6 +693,82 @@ export const buildCanvasOutpaintGraph = ( ); } + // Handle Coherence Mode + if (canvasCoherenceMode === 'edge') { + graph.nodes[CANVAS_COHERENCE_MASK_EDGE] = { + type: 'mask_edge', + id: CANVAS_COHERENCE_MASK_EDGE, + is_intermediate: true, + edge_blur: maskBlur, + edge_size: maskBlur * 2, + low_threshold: 100, + high_threshold: 200, + }; + graph.nodes[CANVAS_COHERENCE_INPAINT_CREATE_MASK] = { + type: 'create_denoise_mask', + id: CANVAS_COHERENCE_INPAINT_CREATE_MASK, + is_intermediate: true, + fp32: vaePrecision === 'fp32' ? true : false, + }; + + if (isUsingScaledDimensions) { + graph.edges.push({ + source: { + node_id: MASK_RESIZE_UP, + field: 'image', + }, + destination: { + node_id: CANVAS_COHERENCE_MASK_EDGE, + field: 'image', + }, + }); + } else { + graph.edges.push({ + source: { + node_id: MASK_COMBINE, + field: 'image', + }, + destination: { + node_id: CANVAS_COHERENCE_MASK_EDGE, + field: 'image', + }, + }); + } + + graph.edges.push( + { + source: { + node_id: INPAINT_INFILL, + field: 'image', + }, + destination: { + node_id: CANVAS_COHERENCE_INPAINT_CREATE_MASK, + field: 'image', + }, + }, + { + source: { + node_id: CANVAS_COHERENCE_MASK_EDGE, + field: 'image', + }, + destination: { + node_id: CANVAS_COHERENCE_INPAINT_CREATE_MASK, + field: 'mask', + }, + }, + { + source: { + node_id: CANVAS_COHERENCE_INPAINT_CREATE_MASK, + field: 'denoise_mask', + }, + destination: { + node_id: CANVAS_COHERENCE_DENOISE_LATENTS, + field: 'denoise_mask', + }, + } + ); + } + // Handle Seed if (shouldRandomizeSeed) { // Random int node to generate the starting seed diff --git a/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasSDXLInpaintGraph.ts b/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasSDXLInpaintGraph.ts index ca3f39257e..6b898e1db6 100644 --- a/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasSDXLInpaintGraph.ts +++ b/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasSDXLInpaintGraph.ts @@ -71,6 +71,7 @@ export const buildCanvasSDXLInpaintGraph = ( shouldUseCpuNoise, maskBlur, maskBlurMethod, + canvasCoherenceMode, canvasCoherenceSteps, canvasCoherenceStrength, seamlessXAxis, @@ -182,21 +183,6 @@ export const buildCanvasSDXLInpaintGraph = ( b: 1, is_intermediate: true, }, - [CANVAS_COHERENCE_MASK_EDGE]: { - type: 'mask_edge', - id: CANVAS_COHERENCE_MASK_EDGE, - is_intermediate: true, - edge_blur: maskBlur, - edge_size: maskBlur * 2, - low_threshold: 100, - high_threshold: 200, - }, - [CANVAS_COHERENCE_INPAINT_CREATE_MASK]: { - type: 'create_denoise_mask', - id: CANVAS_COHERENCE_INPAINT_CREATE_MASK, - is_intermediate: true, - fp32: vaePrecision === 'fp32' ? true : false, - }, [CANVAS_COHERENCE_DENOISE_LATENTS]: { type: 'denoise_latents', id: CANVAS_COHERENCE_DENOISE_LATENTS, @@ -348,27 +334,6 @@ export const buildCanvasSDXLInpaintGraph = ( field: 'denoise_mask', }, }, - // Create Coherence Mask - { - source: { - node_id: CANVAS_COHERENCE_MASK_EDGE, - field: 'image', - }, - destination: { - node_id: CANVAS_COHERENCE_INPAINT_CREATE_MASK, - field: 'mask', - }, - }, - { - source: { - node_id: CANVAS_COHERENCE_INPAINT_CREATE_MASK, - field: 'denoise_mask', - }, - destination: { - node_id: CANVAS_COHERENCE_DENOISE_LATENTS, - field: 'denoise_mask', - }, - }, // Iterate { source: { @@ -552,26 +517,6 @@ export const buildCanvasSDXLInpaintGraph = ( field: 'image', }, }, - { - source: { - node_id: INPAINT_IMAGE_RESIZE_UP, - field: 'image', - }, - destination: { - node_id: CANVAS_COHERENCE_INPAINT_CREATE_MASK, - field: 'image', - }, - }, - { - source: { - node_id: MASK_RESIZE_UP, - field: 'image', - }, - destination: { - node_id: CANVAS_COHERENCE_MASK_EDGE, - field: 'image', - }, - }, // Color Correct The Inpainted Result { source: { @@ -633,16 +578,6 @@ export const buildCanvasSDXLInpaintGraph = ( ...(graph.nodes[INPAINT_CREATE_MASK] as CreateDenoiseMaskInvocation), image: canvasInitImage, }; - graph.nodes[CANVAS_COHERENCE_INPAINT_CREATE_MASK] = { - ...(graph.nodes[ - CANVAS_COHERENCE_INPAINT_CREATE_MASK - ] as CreateDenoiseMaskInvocation), - image: canvasInitImage, - }; - graph.nodes[CANVAS_COHERENCE_MASK_EDGE] = { - ...(graph.nodes[CANVAS_COHERENCE_MASK_EDGE] as MaskEdgeInvocation), - image: canvasMaskImage, - }; graph.edges.push( // Color Correct The Inpainted Result @@ -669,6 +604,84 @@ export const buildCanvasSDXLInpaintGraph = ( ); } + // Handle Coherence Mode + if (canvasCoherenceMode === 'edge') { + graph.nodes[CANVAS_COHERENCE_MASK_EDGE] = { + type: 'mask_edge', + id: CANVAS_COHERENCE_MASK_EDGE, + is_intermediate: true, + edge_blur: maskBlur, + edge_size: maskBlur * 2, + low_threshold: 100, + high_threshold: 200, + }; + graph.nodes[CANVAS_COHERENCE_INPAINT_CREATE_MASK] = { + type: 'create_denoise_mask', + id: CANVAS_COHERENCE_INPAINT_CREATE_MASK, + is_intermediate: true, + fp32: vaePrecision === 'fp32' ? true : false, + }; + + if (isUsingScaledDimensions) { + graph.edges.push( + { + source: { + node_id: MASK_RESIZE_UP, + field: 'image', + }, + destination: { + node_id: CANVAS_COHERENCE_MASK_EDGE, + field: 'image', + }, + }, + { + source: { + node_id: INPAINT_IMAGE_RESIZE_UP, + field: 'image', + }, + destination: { + node_id: CANVAS_COHERENCE_INPAINT_CREATE_MASK, + field: 'image', + }, + } + ); + } else { + graph.nodes[CANVAS_COHERENCE_INPAINT_CREATE_MASK] = { + ...(graph.nodes[ + CANVAS_COHERENCE_INPAINT_CREATE_MASK + ] as CreateDenoiseMaskInvocation), + image: canvasInitImage, + }; + graph.nodes[CANVAS_COHERENCE_MASK_EDGE] = { + ...(graph.nodes[CANVAS_COHERENCE_MASK_EDGE] as MaskEdgeInvocation), + image: canvasMaskImage, + }; + } + + graph.edges.push( + { + source: { + node_id: CANVAS_COHERENCE_MASK_EDGE, + field: 'image', + }, + destination: { + node_id: CANVAS_COHERENCE_INPAINT_CREATE_MASK, + field: 'mask', + }, + }, + { + source: { + node_id: CANVAS_COHERENCE_INPAINT_CREATE_MASK, + field: 'denoise_mask', + }, + destination: { + node_id: CANVAS_COHERENCE_DENOISE_LATENTS, + field: 'denoise_mask', + }, + } + ); + } + // Handle Seed if (shouldRandomizeSeed) { // Random int node to generate the starting seed diff --git a/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasSDXLOutpaintGraph.ts b/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasSDXLOutpaintGraph.ts index bd06228beb..c839815f98 100644 --- a/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasSDXLOutpaintGraph.ts +++ b/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasSDXLOutpaintGraph.ts @@ -72,9 +72,11 @@ export const buildCanvasSDXLOutpaintGraph = ( shouldUseNoiseSettings, shouldUseCpuNoise, maskBlur, + canvasCoherenceMode, canvasCoherenceSteps, canvasCoherenceStrength, infillTileSize, + infillPatchmatchDownscaleSize, infillMethod, seamlessXAxis, seamlessYAxis, @@ -190,21 +192,6 @@ export const buildCanvasSDXLOutpaintGraph = ( b: 1, is_intermediate: true, }, - [CANVAS_COHERENCE_MASK_EDGE]: { - type: 'mask_edge', - id: CANVAS_COHERENCE_MASK_EDGE, - is_intermediate: true, - edge_blur: maskBlur, - edge_size: maskBlur * 2, - low_threshold: 100, - high_threshold: 200, - }, - [CANVAS_COHERENCE_INPAINT_CREATE_MASK]: { - type: 'create_denoise_mask', - id: CANVAS_COHERENCE_INPAINT_CREATE_MASK, - is_intermediate: true, - fp32: vaePrecision === 'fp32' ? true : false, - }, [CANVAS_COHERENCE_DENOISE_LATENTS]: { type: 'denoise_latents', id: CANVAS_COHERENCE_DENOISE_LATENTS, @@ -377,27 +364,6 @@ export const buildCanvasSDXLOutpaintGraph = ( field: 'denoise_mask', }, }, - // Create Coherence Mask - { - source: { - node_id: CANVAS_COHERENCE_MASK_EDGE, - field: 'image', - }, - destination: { - node_id: CANVAS_COHERENCE_INPAINT_CREATE_MASK, - field: 'mask', - }, - }, - { - source: { - node_id: CANVAS_COHERENCE_INPAINT_CREATE_MASK, - field: 'denoise_mask', - }, - destination: { - node_id: CANVAS_COHERENCE_DENOISE_LATENTS, - field: 'denoise_mask', - }, - }, // Iterate { source: { @@ -490,6 +456,16 @@ export const buildCanvasSDXLOutpaintGraph = ( field: 'latents', }, }, + { + source: { + node_id: INPAINT_INFILL, + field: 'image', + }, + destination: { + node_id: INPAINT_CREATE_MASK, + field: 'image', + }, + }, // Decode inpainted latents to image { source: { @@ -602,26 +578,7 @@ export const buildCanvasSDXLOutpaintGraph = ( field: 'image', }, }, - { - source: { - node_id: INPAINT_INFILL, - field: 'image', - }, - destination: { - node_id: INPAINT_CREATE_MASK, - field: 'image', - }, - }, - { - source: { - node_id: INPAINT_INFILL, - field: 'image', - }, - destination: { - node_id: CANVAS_COHERENCE_INPAINT_CREATE_MASK, - field: 'image', - }, - }, + // Take combined mask and resize and then blur { source: { @@ -633,16 +590,7 @@ export const buildCanvasSDXLOutpaintGraph = ( field: 'image', }, }, - { - source: { - node_id: MASK_RESIZE_UP, - field: 'image', - }, - destination: { - node_id: CANVAS_COHERENCE_MASK_EDGE, - field: 'image', - }, - }, + // Resize Results Down { source: { @@ -726,37 +674,6 @@ export const buildCanvasSDXLOutpaintGraph = ( }; graph.edges.push( - // Take combined mask and plug it to blur - { - source: { - node_id: INPAINT_INFILL, - field: 'image', - }, - destination: { - node_id: INPAINT_CREATE_MASK, - field: 'image', - }, - }, - { - source: { - node_id: MASK_COMBINE, - field: 'image', - }, - destination: { - node_id: CANVAS_COHERENCE_MASK_EDGE, - field: 'image', - }, - }, - { - source: { - node_id: INPAINT_INFILL, - field: 'image', - }, - destination: { - node_id: CANVAS_COHERENCE_INPAINT_CREATE_MASK, - field: 'image', - }, - }, // Color Correct The Inpainted Result { source: { @@ -791,6 +708,82 @@ export const buildCanvasSDXLOutpaintGraph = ( ); } + // Handle Coherence Mode + if (canvasCoherenceMode === 'edge') { + graph.nodes[CANVAS_COHERENCE_MASK_EDGE] = { + type: 'mask_edge', + id: CANVAS_COHERENCE_MASK_EDGE, + is_intermediate: true, + edge_blur: maskBlur, + edge_size: maskBlur * 2, + low_threshold: 100, + high_threshold: 200, + }; + graph.nodes[CANVAS_COHERENCE_INPAINT_CREATE_MASK] = { + type: 'create_denoise_mask', + id: CANVAS_COHERENCE_INPAINT_CREATE_MASK, + is_intermediate: true, + fp32: vaePrecision === 'fp32' ? true : false, + }; + + if (isUsingScaledDimensions) { + graph.edges.push({ + source: { + node_id: MASK_RESIZE_UP, + field: 'image', + }, + destination: { + node_id: CANVAS_COHERENCE_MASK_EDGE, + field: 'image', + }, + }); + } else { + graph.edges.push({ + source: { + node_id: MASK_COMBINE, + field: 'image', + }, + destination: { + node_id: CANVAS_COHERENCE_MASK_EDGE, + field: 'image', + }, + }); + } + + graph.edges.push( + { + source: { + node_id: INPAINT_INFILL, + field: 'image', + }, + destination: { + node_id: CANVAS_COHERENCE_INPAINT_CREATE_MASK, + field: 'image', + }, + }, + { + source: { + node_id: CANVAS_COHERENCE_MASK_EDGE, + field: 'image', + }, + destination: { + node_id: CANVAS_COHERENCE_INPAINT_CREATE_MASK, + field: 'mask', + }, + }, + { + source: { + node_id: CANVAS_COHERENCE_INPAINT_CREATE_MASK, + field: 'denoise_mask', + }, + destination: { + node_id: CANVAS_COHERENCE_DENOISE_LATENTS, + field: 'denoise_mask', + }, + } + ); + } + // Handle Seed if (shouldRandomizeSeed) { // Random int node to generate the starting seed diff --git a/invokeai/frontend/web/src/features/parameters/components/Parameters/Canvas/Compositing/CoherencePass/ParamCanvasCoherenceMode.tsx b/invokeai/frontend/web/src/features/parameters/components/Parameters/Canvas/Compositing/CoherencePass/ParamCanvasCoherenceMode.tsx new file mode 100644 index 0000000000..398a11957c --- /dev/null +++ b/invokeai/frontend/web/src/features/parameters/components/Parameters/Canvas/Compositing/CoherencePass/ParamCanvasCoherenceMode.tsx @@ -0,0 +1,41 @@ +import type { RootState } from 'app/store/store'; +import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; +import { IAISelectDataType } from 'common/components/IAIMantineSearchableSelect'; +import IAIMantineSelect from 'common/components/IAIMantineSelect'; +import { setCanvasCoherenceMode } from 'features/parameters/store/generationSlice'; +import { CanvasCoherenceModeParam } from 'features/parameters/types/parameterSchemas'; + +import { memo } from 'react'; +import { useTranslation } from 'react-i18next'; + +const coherenceModeSelectData: IAISelectDataType[] = [ + { label: 'Full', value: 'full' }, + { label: 'Edge', value: 'edge' }, +]; + +const ParamCanvasCoherenceMode = () => { + const dispatch = useAppDispatch(); + const canvasCoherenceMode = useAppSelector( + (state: RootState) => state.generation.canvasCoherenceMode + ); + const { t } = useTranslation(); + + const handleCoherenceModeChange = (v: string | null) => { + if (!v) { + return; + } + + dispatch(setCanvasCoherenceMode(v as CanvasCoherenceModeParam)); + }; + + return ( + + ); +}; + +export default memo(ParamCanvasCoherenceMode); diff --git a/invokeai/frontend/web/src/features/parameters/components/Parameters/Canvas/Compositing/ParamCompositingSettingsCollapse.tsx b/invokeai/frontend/web/src/features/parameters/components/Parameters/Canvas/Compositing/ParamCompositingSettingsCollapse.tsx index c3c978e8a1..e06287c7c7 100644 --- a/invokeai/frontend/web/src/features/parameters/components/Parameters/Canvas/Compositing/ParamCompositingSettingsCollapse.tsx +++ b/invokeai/frontend/web/src/features/parameters/components/Parameters/Canvas/Compositing/ParamCompositingSettingsCollapse.tsx @@ -3,6 +3,7 @@ import IAICollapse from 'common/components/IAICollapse'; import { memo } from 'react'; import { useTranslation } from 'react-i18next'; import SubParametersWrapper from '../../SubParametersWrapper'; +import ParamCanvasCoherenceMode from './CoherencePass/ParamCanvasCoherenceMode'; import ParamCanvasCoherenceSteps from './CoherencePass/ParamCanvasCoherenceSteps'; import ParamCanvasCoherenceStrength from './CoherencePass/ParamCanvasCoherenceStrength'; import ParamMaskBlur from './MaskAdjustment/ParamMaskBlur'; @@ -20,6 +21,7 @@ const ParamCompositingSettingsCollapse = () => { + diff --git a/invokeai/frontend/web/src/features/parameters/store/generationSlice.ts b/invokeai/frontend/web/src/features/parameters/store/generationSlice.ts index 7bbfc5149d..7703376e43 100644 --- a/invokeai/frontend/web/src/features/parameters/store/generationSlice.ts +++ b/invokeai/frontend/web/src/features/parameters/store/generationSlice.ts @@ -7,6 +7,7 @@ import { ImageDTO } from 'services/api/types'; import { clipSkipMap } from '../types/constants'; import { + CanvasCoherenceModeParam, CfgScaleParam, HeightParam, MainModelParam, @@ -37,6 +38,7 @@ export interface GenerationState { scheduler: SchedulerParam; maskBlur: number; maskBlurMethod: MaskBlurMethodParam; + canvasCoherenceMode: CanvasCoherenceModeParam; canvasCoherenceSteps: number; canvasCoherenceStrength: StrengthParam; seed: SeedParam; @@ -78,6 +80,7 @@ export const initialGenerationState: GenerationState = { scheduler: 'euler', maskBlur: 16, maskBlurMethod: 'box', + canvasCoherenceMode: 'edge', canvasCoherenceSteps: 20, canvasCoherenceStrength: 0.3, seed: 0, @@ -208,6 +211,12 @@ export const generationSlice = createSlice({ setMaskBlurMethod: (state, action: PayloadAction) => { state.maskBlurMethod = action.payload; }, + setCanvasCoherenceMode: ( + state, + action: PayloadAction + ) => { + state.canvasCoherenceMode = action.payload; + }, setCanvasCoherenceSteps: (state, action: PayloadAction) => { state.canvasCoherenceSteps = action.payload; }, @@ -331,6 +340,7 @@ export const { setScheduler, setMaskBlur, setMaskBlurMethod, + setCanvasCoherenceMode, setCanvasCoherenceSteps, setCanvasCoherenceStrength, setSeed, diff --git a/invokeai/frontend/web/src/features/parameters/types/parameterSchemas.ts b/invokeai/frontend/web/src/features/parameters/types/parameterSchemas.ts index e210efc414..e53749582b 100644 --- a/invokeai/frontend/web/src/features/parameters/types/parameterSchemas.ts +++ b/invokeai/frontend/web/src/features/parameters/types/parameterSchemas.ts @@ -418,6 +418,22 @@ export const isValidMaskBlurMethod = ( val: unknown ): val is MaskBlurMethodParam => zMaskBlurMethod.safeParse(val).success; +/** + * Zod schema for a Canvas Coherence Mode method parameter + */ +export const zCanvasCoherenceMode = z.enum(['full', 'edge']); +/** + * Type alias for Canvas Coherence Mode parameter, inferred from its zod schema + */ +export type CanvasCoherenceModeParam = z.infer; +/** + * Validates/type-guards a value as a mask blur method parameter + */ +export const isValidCoherenceModeParam = ( + val: unknown +): val is CanvasCoherenceModeParam => + zCanvasCoherenceMode.safeParse(val).success; + // /** // * Zod schema for BaseModelType // */ From 6cfabc585a579a3ce031e32ba2f6b614d901602d Mon Sep 17 00:00:00 2001 From: blessedcoolant <54517381+blessedcoolant@users.noreply.github.com> Date: Sun, 3 Sep 2023 01:26:32 +1200 Subject: [PATCH 14/26] feat: Add Coherence Mode - Mask --- .../nodes/util/graphBuilders/addVAEToGraph.ts | 2 +- .../graphBuilders/buildCanvasInpaintGraph.ts | 130 ++++++++++------ .../graphBuilders/buildCanvasOutpaintGraph.ts | 144 +++++++++++------- .../buildCanvasSDXLInpaintGraph.ts | 130 ++++++++++------ .../buildCanvasSDXLOutpaintGraph.ts | 143 ++++++++++------- .../ParamCanvasCoherenceMode.tsx | 5 +- .../parameters/types/parameterSchemas.ts | 2 +- 7 files changed, 343 insertions(+), 213 deletions(-) diff --git a/invokeai/frontend/web/src/features/nodes/util/graphBuilders/addVAEToGraph.ts b/invokeai/frontend/web/src/features/nodes/util/graphBuilders/addVAEToGraph.ts index 8e77799293..696c8afff2 100644 --- a/invokeai/frontend/web/src/features/nodes/util/graphBuilders/addVAEToGraph.ts +++ b/invokeai/frontend/web/src/features/nodes/util/graphBuilders/addVAEToGraph.ts @@ -149,7 +149,7 @@ export const addVAEToGraph = ( ); // Handle Coherence Mode - if (canvasCoherenceMode === 'edge') { + if (canvasCoherenceMode !== 'unmasked') { graph.edges.push({ source: { node_id: isAutoVae ? modelLoaderNodeId : VAE_LOADER, diff --git a/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasInpaintGraph.ts b/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasInpaintGraph.ts index a87d20a08d..ea6ec17999 100644 --- a/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasInpaintGraph.ts +++ b/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasInpaintGraph.ts @@ -590,16 +590,8 @@ export const buildCanvasInpaintGraph = ( } // Handle Coherence Mode - if (canvasCoherenceMode === 'edge') { - graph.nodes[CANVAS_COHERENCE_MASK_EDGE] = { - type: 'mask_edge', - id: CANVAS_COHERENCE_MASK_EDGE, - is_intermediate: true, - edge_blur: maskBlur, - edge_size: maskBlur * 2, - low_threshold: 100, - high_threshold: 200, - }; + if (canvasCoherenceMode !== 'unmasked') { + // Create Mask If Coherence Mode Is Not Full graph.nodes[CANVAS_COHERENCE_INPAINT_CREATE_MASK] = { type: 'create_denoise_mask', id: CANVAS_COHERENCE_INPAINT_CREATE_MASK, @@ -607,9 +599,65 @@ export const buildCanvasInpaintGraph = ( fp32: vaePrecision === 'fp32' ? true : false, }; + // Handle Image Input For Mask Creation if (isUsingScaledDimensions) { - graph.edges.push( - { + graph.edges.push({ + source: { + node_id: INPAINT_IMAGE_RESIZE_UP, + field: 'image', + }, + destination: { + node_id: CANVAS_COHERENCE_INPAINT_CREATE_MASK, + field: 'image', + }, + }); + } else { + graph.nodes[CANVAS_COHERENCE_INPAINT_CREATE_MASK] = { + ...(graph.nodes[ + CANVAS_COHERENCE_INPAINT_CREATE_MASK + ] as CreateDenoiseMaskInvocation), + image: canvasInitImage, + }; + } + + // Create Mask If Coherence Mode Is Mask + if (canvasCoherenceMode === 'mask') { + if (isUsingScaledDimensions) { + graph.edges.push({ + source: { + node_id: MASK_RESIZE_UP, + field: 'image', + }, + destination: { + node_id: CANVAS_COHERENCE_INPAINT_CREATE_MASK, + field: 'mask', + }, + }); + } else { + graph.nodes[CANVAS_COHERENCE_INPAINT_CREATE_MASK] = { + ...(graph.nodes[ + CANVAS_COHERENCE_INPAINT_CREATE_MASK + ] as CreateDenoiseMaskInvocation), + mask: canvasMaskImage, + }; + } + } + + // Create Mask Edge If Coherence Mode Is Edge + if (canvasCoherenceMode === 'edge') { + graph.nodes[CANVAS_COHERENCE_MASK_EDGE] = { + type: 'mask_edge', + id: CANVAS_COHERENCE_MASK_EDGE, + is_intermediate: true, + edge_blur: maskBlur, + edge_size: maskBlur * 2, + low_threshold: 100, + high_threshold: 200, + }; + + // Handle Scaled Dimensions For Mask Edge + if (isUsingScaledDimensions) { + graph.edges.push({ source: { node_id: MASK_RESIZE_UP, field: 'image', @@ -618,33 +666,15 @@ export const buildCanvasInpaintGraph = ( node_id: CANVAS_COHERENCE_MASK_EDGE, field: 'image', }, - }, - { - source: { - node_id: INPAINT_IMAGE_RESIZE_UP, - field: 'image', - }, - destination: { - node_id: CANVAS_COHERENCE_INPAINT_CREATE_MASK, - field: 'image', - }, - } - ); - } else { - graph.nodes[CANVAS_COHERENCE_INPAINT_CREATE_MASK] = { - ...(graph.nodes[ - CANVAS_COHERENCE_INPAINT_CREATE_MASK - ] as CreateDenoiseMaskInvocation), - image: canvasInitImage, - }; - graph.nodes[CANVAS_COHERENCE_MASK_EDGE] = { - ...(graph.nodes[CANVAS_COHERENCE_MASK_EDGE] as MaskEdgeInvocation), - image: canvasMaskImage, - }; - } + }); + } else { + graph.nodes[CANVAS_COHERENCE_MASK_EDGE] = { + ...(graph.nodes[CANVAS_COHERENCE_MASK_EDGE] as MaskEdgeInvocation), + image: canvasMaskImage, + }; + } - graph.edges.push( - { + graph.edges.push({ source: { node_id: CANVAS_COHERENCE_MASK_EDGE, field: 'image', @@ -653,18 +683,20 @@ export const buildCanvasInpaintGraph = ( node_id: CANVAS_COHERENCE_INPAINT_CREATE_MASK, field: 'mask', }, + }); + } + + // Plug Denoise Mask To Coherence Denoise Latents + graph.edges.push({ + source: { + node_id: CANVAS_COHERENCE_INPAINT_CREATE_MASK, + field: 'denoise_mask', }, - { - source: { - node_id: CANVAS_COHERENCE_INPAINT_CREATE_MASK, - field: 'denoise_mask', - }, - destination: { - node_id: CANVAS_COHERENCE_DENOISE_LATENTS, - field: 'denoise_mask', - }, - } - ); + destination: { + node_id: CANVAS_COHERENCE_DENOISE_LATENTS, + field: 'denoise_mask', + }, + }); } // Handle Seed diff --git a/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasOutpaintGraph.ts b/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasOutpaintGraph.ts index fe2d3f1698..60e606e6da 100644 --- a/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasOutpaintGraph.ts +++ b/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasOutpaintGraph.ts @@ -563,7 +563,6 @@ export const buildCanvasOutpaintGraph = ( field: 'image', }, }, - // Take combined mask and resize and then blur { source: { @@ -694,16 +693,7 @@ export const buildCanvasOutpaintGraph = ( } // Handle Coherence Mode - if (canvasCoherenceMode === 'edge') { - graph.nodes[CANVAS_COHERENCE_MASK_EDGE] = { - type: 'mask_edge', - id: CANVAS_COHERENCE_MASK_EDGE, - is_intermediate: true, - edge_blur: maskBlur, - edge_size: maskBlur * 2, - low_threshold: 100, - high_threshold: 200, - }; + if (canvasCoherenceMode !== 'unmasked') { graph.nodes[CANVAS_COHERENCE_INPAINT_CREATE_MASK] = { type: 'create_denoise_mask', id: CANVAS_COHERENCE_INPAINT_CREATE_MASK, @@ -711,42 +701,82 @@ export const buildCanvasOutpaintGraph = ( fp32: vaePrecision === 'fp32' ? true : false, }; - if (isUsingScaledDimensions) { - graph.edges.push({ - source: { - node_id: MASK_RESIZE_UP, - field: 'image', - }, - destination: { - node_id: CANVAS_COHERENCE_MASK_EDGE, - field: 'image', - }, - }); - } else { - graph.edges.push({ - source: { - node_id: MASK_COMBINE, - field: 'image', - }, - destination: { - node_id: CANVAS_COHERENCE_MASK_EDGE, - field: 'image', - }, - }); + // Handle Image Input For Mask Creation + graph.edges.push({ + source: { + node_id: INPAINT_INFILL, + field: 'image', + }, + destination: { + node_id: CANVAS_COHERENCE_INPAINT_CREATE_MASK, + field: 'image', + }, + }); + + // Create Mask If Coherence Mode Is Mask + if (canvasCoherenceMode === 'mask') { + if (isUsingScaledDimensions) { + graph.edges.push({ + source: { + node_id: MASK_RESIZE_UP, + field: 'image', + }, + destination: { + node_id: CANVAS_COHERENCE_INPAINT_CREATE_MASK, + field: 'mask', + }, + }); + } else { + graph.edges.push({ + source: { + node_id: MASK_COMBINE, + field: 'image', + }, + destination: { + node_id: CANVAS_COHERENCE_INPAINT_CREATE_MASK, + field: 'mask', + }, + }); + } } - graph.edges.push( - { - source: { - node_id: INPAINT_INFILL, - field: 'image', - }, - destination: { - node_id: CANVAS_COHERENCE_INPAINT_CREATE_MASK, - field: 'image', - }, - }, - { + if (canvasCoherenceMode === 'edge') { + graph.nodes[CANVAS_COHERENCE_MASK_EDGE] = { + type: 'mask_edge', + id: CANVAS_COHERENCE_MASK_EDGE, + is_intermediate: true, + edge_blur: maskBlur, + edge_size: maskBlur * 2, + low_threshold: 100, + high_threshold: 200, + }; + + // Handle Scaled Dimensions For Mask Edge + if (isUsingScaledDimensions) { + graph.edges.push({ + source: { + node_id: MASK_RESIZE_UP, + field: 'image', + }, + destination: { + node_id: CANVAS_COHERENCE_MASK_EDGE, + field: 'image', + }, + }); + } else { + graph.edges.push({ + source: { + node_id: MASK_COMBINE, + field: 'image', + }, + destination: { + node_id: CANVAS_COHERENCE_MASK_EDGE, + field: 'image', + }, + }); + } + + graph.edges.push({ source: { node_id: CANVAS_COHERENCE_MASK_EDGE, field: 'image', @@ -755,18 +785,20 @@ export const buildCanvasOutpaintGraph = ( node_id: CANVAS_COHERENCE_INPAINT_CREATE_MASK, field: 'mask', }, + }); + } + + // Plug Denoise Mask To Coherence Denoise Latents + graph.edges.push({ + source: { + node_id: CANVAS_COHERENCE_INPAINT_CREATE_MASK, + field: 'denoise_mask', }, - { - source: { - node_id: CANVAS_COHERENCE_INPAINT_CREATE_MASK, - field: 'denoise_mask', - }, - destination: { - node_id: CANVAS_COHERENCE_DENOISE_LATENTS, - field: 'denoise_mask', - }, - } - ); + destination: { + node_id: CANVAS_COHERENCE_DENOISE_LATENTS, + field: 'denoise_mask', + }, + }); } // Handle Seed diff --git a/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasSDXLInpaintGraph.ts b/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasSDXLInpaintGraph.ts index 6b898e1db6..f26a34a2b7 100644 --- a/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasSDXLInpaintGraph.ts +++ b/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasSDXLInpaintGraph.ts @@ -605,16 +605,8 @@ export const buildCanvasSDXLInpaintGraph = ( } // Handle Coherence Mode - if (canvasCoherenceMode === 'edge') { - graph.nodes[CANVAS_COHERENCE_MASK_EDGE] = { - type: 'mask_edge', - id: CANVAS_COHERENCE_MASK_EDGE, - is_intermediate: true, - edge_blur: maskBlur, - edge_size: maskBlur * 2, - low_threshold: 100, - high_threshold: 200, - }; + if (canvasCoherenceMode !== 'unmasked') { + // Create Mask If Coherence Mode Is Not Full graph.nodes[CANVAS_COHERENCE_INPAINT_CREATE_MASK] = { type: 'create_denoise_mask', id: CANVAS_COHERENCE_INPAINT_CREATE_MASK, @@ -622,9 +614,65 @@ export const buildCanvasSDXLInpaintGraph = ( fp32: vaePrecision === 'fp32' ? true : false, }; + // Handle Image Input For Mask Creation if (isUsingScaledDimensions) { - graph.edges.push( - { + graph.edges.push({ + source: { + node_id: INPAINT_IMAGE_RESIZE_UP, + field: 'image', + }, + destination: { + node_id: CANVAS_COHERENCE_INPAINT_CREATE_MASK, + field: 'image', + }, + }); + } else { + graph.nodes[CANVAS_COHERENCE_INPAINT_CREATE_MASK] = { + ...(graph.nodes[ + CANVAS_COHERENCE_INPAINT_CREATE_MASK + ] as CreateDenoiseMaskInvocation), + image: canvasInitImage, + }; + } + + // Create Mask If Coherence Mode Is Mask + if (canvasCoherenceMode === 'mask') { + if (isUsingScaledDimensions) { + graph.edges.push({ + source: { + node_id: MASK_RESIZE_UP, + field: 'image', + }, + destination: { + node_id: CANVAS_COHERENCE_INPAINT_CREATE_MASK, + field: 'mask', + }, + }); + } else { + graph.nodes[CANVAS_COHERENCE_INPAINT_CREATE_MASK] = { + ...(graph.nodes[ + CANVAS_COHERENCE_INPAINT_CREATE_MASK + ] as CreateDenoiseMaskInvocation), + mask: canvasMaskImage, + }; + } + } + + // Create Mask Edge If Coherence Mode Is Edge + if (canvasCoherenceMode === 'edge') { + graph.nodes[CANVAS_COHERENCE_MASK_EDGE] = { + type: 'mask_edge', + id: CANVAS_COHERENCE_MASK_EDGE, + is_intermediate: true, + edge_blur: maskBlur, + edge_size: maskBlur * 2, + low_threshold: 100, + high_threshold: 200, + }; + + // Handle Scaled Dimensions For Mask Edge + if (isUsingScaledDimensions) { + graph.edges.push({ source: { node_id: MASK_RESIZE_UP, field: 'image', @@ -633,33 +681,15 @@ export const buildCanvasSDXLInpaintGraph = ( node_id: CANVAS_COHERENCE_MASK_EDGE, field: 'image', }, - }, - { - source: { - node_id: INPAINT_IMAGE_RESIZE_UP, - field: 'image', - }, - destination: { - node_id: CANVAS_COHERENCE_INPAINT_CREATE_MASK, - field: 'image', - }, - } - ); - } else { - graph.nodes[CANVAS_COHERENCE_INPAINT_CREATE_MASK] = { - ...(graph.nodes[ - CANVAS_COHERENCE_INPAINT_CREATE_MASK - ] as CreateDenoiseMaskInvocation), - image: canvasInitImage, - }; - graph.nodes[CANVAS_COHERENCE_MASK_EDGE] = { - ...(graph.nodes[CANVAS_COHERENCE_MASK_EDGE] as MaskEdgeInvocation), - image: canvasMaskImage, - }; - } + }); + } else { + graph.nodes[CANVAS_COHERENCE_MASK_EDGE] = { + ...(graph.nodes[CANVAS_COHERENCE_MASK_EDGE] as MaskEdgeInvocation), + image: canvasMaskImage, + }; + } - graph.edges.push( - { + graph.edges.push({ source: { node_id: CANVAS_COHERENCE_MASK_EDGE, field: 'image', @@ -668,18 +698,20 @@ export const buildCanvasSDXLInpaintGraph = ( node_id: CANVAS_COHERENCE_INPAINT_CREATE_MASK, field: 'mask', }, + }); + } + + // Plug Denoise Mask To Coherence Denoise Latents + graph.edges.push({ + source: { + node_id: CANVAS_COHERENCE_INPAINT_CREATE_MASK, + field: 'denoise_mask', }, - { - source: { - node_id: CANVAS_COHERENCE_INPAINT_CREATE_MASK, - field: 'denoise_mask', - }, - destination: { - node_id: CANVAS_COHERENCE_DENOISE_LATENTS, - field: 'denoise_mask', - }, - } - ); + destination: { + node_id: CANVAS_COHERENCE_DENOISE_LATENTS, + field: 'denoise_mask', + }, + }); } // Handle Seed diff --git a/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasSDXLOutpaintGraph.ts b/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasSDXLOutpaintGraph.ts index c839815f98..da796f8a87 100644 --- a/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasSDXLOutpaintGraph.ts +++ b/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasSDXLOutpaintGraph.ts @@ -709,16 +709,7 @@ export const buildCanvasSDXLOutpaintGraph = ( } // Handle Coherence Mode - if (canvasCoherenceMode === 'edge') { - graph.nodes[CANVAS_COHERENCE_MASK_EDGE] = { - type: 'mask_edge', - id: CANVAS_COHERENCE_MASK_EDGE, - is_intermediate: true, - edge_blur: maskBlur, - edge_size: maskBlur * 2, - low_threshold: 100, - high_threshold: 200, - }; + if (canvasCoherenceMode !== 'unmasked') { graph.nodes[CANVAS_COHERENCE_INPAINT_CREATE_MASK] = { type: 'create_denoise_mask', id: CANVAS_COHERENCE_INPAINT_CREATE_MASK, @@ -726,42 +717,82 @@ export const buildCanvasSDXLOutpaintGraph = ( fp32: vaePrecision === 'fp32' ? true : false, }; - if (isUsingScaledDimensions) { - graph.edges.push({ - source: { - node_id: MASK_RESIZE_UP, - field: 'image', - }, - destination: { - node_id: CANVAS_COHERENCE_MASK_EDGE, - field: 'image', - }, - }); - } else { - graph.edges.push({ - source: { - node_id: MASK_COMBINE, - field: 'image', - }, - destination: { - node_id: CANVAS_COHERENCE_MASK_EDGE, - field: 'image', - }, - }); + // Handle Image Input For Mask Creation + graph.edges.push({ + source: { + node_id: INPAINT_INFILL, + field: 'image', + }, + destination: { + node_id: CANVAS_COHERENCE_INPAINT_CREATE_MASK, + field: 'image', + }, + }); + + // Create Mask If Coherence Mode Is Mask + if (canvasCoherenceMode === 'mask') { + if (isUsingScaledDimensions) { + graph.edges.push({ + source: { + node_id: MASK_RESIZE_UP, + field: 'image', + }, + destination: { + node_id: CANVAS_COHERENCE_INPAINT_CREATE_MASK, + field: 'mask', + }, + }); + } else { + graph.edges.push({ + source: { + node_id: MASK_COMBINE, + field: 'image', + }, + destination: { + node_id: CANVAS_COHERENCE_INPAINT_CREATE_MASK, + field: 'mask', + }, + }); + } } - graph.edges.push( - { - source: { - node_id: INPAINT_INFILL, - field: 'image', - }, - destination: { - node_id: CANVAS_COHERENCE_INPAINT_CREATE_MASK, - field: 'image', - }, - }, - { + if (canvasCoherenceMode === 'edge') { + graph.nodes[CANVAS_COHERENCE_MASK_EDGE] = { + type: 'mask_edge', + id: CANVAS_COHERENCE_MASK_EDGE, + is_intermediate: true, + edge_blur: maskBlur, + edge_size: maskBlur * 2, + low_threshold: 100, + high_threshold: 200, + }; + + // Handle Scaled Dimensions For Mask Edge + if (isUsingScaledDimensions) { + graph.edges.push({ + source: { + node_id: MASK_RESIZE_UP, + field: 'image', + }, + destination: { + node_id: CANVAS_COHERENCE_MASK_EDGE, + field: 'image', + }, + }); + } else { + graph.edges.push({ + source: { + node_id: MASK_COMBINE, + field: 'image', + }, + destination: { + node_id: CANVAS_COHERENCE_MASK_EDGE, + field: 'image', + }, + }); + } + + graph.edges.push({ source: { node_id: CANVAS_COHERENCE_MASK_EDGE, field: 'image', @@ -770,18 +801,20 @@ export const buildCanvasSDXLOutpaintGraph = ( node_id: CANVAS_COHERENCE_INPAINT_CREATE_MASK, field: 'mask', }, + }); + } + + // Plug Denoise Mask To Coherence Denoise Latents + graph.edges.push({ + source: { + node_id: CANVAS_COHERENCE_INPAINT_CREATE_MASK, + field: 'denoise_mask', }, - { - source: { - node_id: CANVAS_COHERENCE_INPAINT_CREATE_MASK, - field: 'denoise_mask', - }, - destination: { - node_id: CANVAS_COHERENCE_DENOISE_LATENTS, - field: 'denoise_mask', - }, - } - ); + destination: { + node_id: CANVAS_COHERENCE_DENOISE_LATENTS, + field: 'denoise_mask', + }, + }); } // Handle Seed diff --git a/invokeai/frontend/web/src/features/parameters/components/Parameters/Canvas/Compositing/CoherencePass/ParamCanvasCoherenceMode.tsx b/invokeai/frontend/web/src/features/parameters/components/Parameters/Canvas/Compositing/CoherencePass/ParamCanvasCoherenceMode.tsx index 398a11957c..afc68c94ac 100644 --- a/invokeai/frontend/web/src/features/parameters/components/Parameters/Canvas/Compositing/CoherencePass/ParamCanvasCoherenceMode.tsx +++ b/invokeai/frontend/web/src/features/parameters/components/Parameters/Canvas/Compositing/CoherencePass/ParamCanvasCoherenceMode.tsx @@ -9,8 +9,9 @@ import { memo } from 'react'; import { useTranslation } from 'react-i18next'; const coherenceModeSelectData: IAISelectDataType[] = [ - { label: 'Full', value: 'full' }, - { label: 'Edge', value: 'edge' }, + { label: 'Unmasked', value: 'unmasked' }, + { label: 'Mask', value: 'mask' }, + { label: 'Mask Edge', value: 'edge' }, ]; const ParamCanvasCoherenceMode = () => { diff --git a/invokeai/frontend/web/src/features/parameters/types/parameterSchemas.ts b/invokeai/frontend/web/src/features/parameters/types/parameterSchemas.ts index e53749582b..5a77231739 100644 --- a/invokeai/frontend/web/src/features/parameters/types/parameterSchemas.ts +++ b/invokeai/frontend/web/src/features/parameters/types/parameterSchemas.ts @@ -421,7 +421,7 @@ export const isValidMaskBlurMethod = ( /** * Zod schema for a Canvas Coherence Mode method parameter */ -export const zCanvasCoherenceMode = z.enum(['full', 'edge']); +export const zCanvasCoherenceMode = z.enum(['unmasked', 'mask', 'edge']); /** * Type alias for Canvas Coherence Mode parameter, inferred from its zod schema */ From 4fa66b2ba8d4fbca37026526abca1eccd3e1738a Mon Sep 17 00:00:00 2001 From: blessedcoolant <54517381+blessedcoolant@users.noreply.github.com> Date: Sun, 3 Sep 2023 01:39:01 +1200 Subject: [PATCH 15/26] ui: Move Coherence settings above mask settings --- .../Compositing/ParamCompositingSettingsCollapse.tsx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/invokeai/frontend/web/src/features/parameters/components/Parameters/Canvas/Compositing/ParamCompositingSettingsCollapse.tsx b/invokeai/frontend/web/src/features/parameters/components/Parameters/Canvas/Compositing/ParamCompositingSettingsCollapse.tsx index e06287c7c7..d0a0ff8f01 100644 --- a/invokeai/frontend/web/src/features/parameters/components/Parameters/Canvas/Compositing/ParamCompositingSettingsCollapse.tsx +++ b/invokeai/frontend/web/src/features/parameters/components/Parameters/Canvas/Compositing/ParamCompositingSettingsCollapse.tsx @@ -15,16 +15,16 @@ const ParamCompositingSettingsCollapse = () => { return ( - - - - - + + + + + ); From fee5cd9c7e060ea129dee52bcf8ccdae036baead Mon Sep 17 00:00:00 2001 From: Darren Ringer Date: Sun, 3 Sep 2023 02:37:36 -0400 Subject: [PATCH 16/26] Update communityNodes.md with a few more nodes Adds my (@dwringer's) released nodes to the community nodes page. --- docs/nodes/communityNodes.md | 80 ++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) diff --git a/docs/nodes/communityNodes.md b/docs/nodes/communityNodes.md index 7fc610081e..34dfbdb443 100644 --- a/docs/nodes/communityNodes.md +++ b/docs/nodes/communityNodes.md @@ -109,6 +109,86 @@ a Text-Generation-Webui instance (might work remotely too, but I never tried it) This node works best with SDXL models, especially as the style can be described independantly of the LLM's output. +-------------------------------- +### Depth Map from Wavefront OBJ + +**Description:** Render depth maps from Wavefront .obj files (triangulated) using this simple 3D renderer utilizing numpy and matplotlib to compute and color the scene. + +To be imported, an .obj must use triangulated meshes, so make sure to enable that option if exporting from a 3D modeling program. This renderer makes each triangle a solid color based on its average depth, so it will cause anomalies if your .obj has large triangles. In Blender, the Remesh modifier can be helpful to subdivide a mesh into small pieces that work well given these limitations. + +There are simple parameters to change the FOV, camera position, and model orientation. + +Additional parameters like different image sizes will probably be added, and things like more sophisticated rotations are planned but this node is experimental and may or may not change much. + +**Node Link:** https://github.com/dwringer/invoke-nodes/blob/main/depth_from_obj.py + +-------------------------------- +### Enhance Image + +**Description:** Boost or reduce color saturation, contrast, brightness, sharpness, or invert colors of any image at any stage with this simple wrapper for pillow [PIL]'s ImageEnhance module. + +Color inversion is toggled with a simple switch, while each of the four enhancer modes are activated by entering a value other than 1 in each corresponding input field. Values less than 1 will reduce the corresponding property, while values greater than 1 will enhance it. + +**Node Link:** https://github.com/dwringer/invoke-nodes/blob/main/image_enhance.py + +-------------------------------- +### Generative Grammar-Based Prompt Nodes + +**Description:** This generates prompts from simple user-defined grammar rules (loaded from custom files - examples provided below). The prompts are made by recursively expanding a special template string, replacing nonterminal "parts-of-speech" until no more nonterminal terms remain in the string. + +**Three nodes are included:** +- *Lookup Table from File* - loads a YAML file "prompt" section (or of a whole folder of YAML's) into a JSON-ified dictionary (Lookups output) +- *Lookups Entry from Prompt* - places a single entry in a new Lookups output under the specified heading +- *Prompt from LookupTable* - uses a Collection of Lookups as grammar rules from which to randomly generate prompts. + +**Node Link:** https://github.com/dwringer/invoke-nodes/blob/main/lookuptables.py + +**Example Templates:** +- https://github.com/dwringer/invoke-nodes/blob/main/example_template.yaml +- https://github.com/dwringer/invoke-nodes/blob/main/movies.yaml +- https://github.com/dwringer/invoke-nodes/blob/main/photograph.yaml + +**Example Usage:** +![lookups usage example graph](https://raw.githubusercontent.com/dwringer/invoke-nodes/main/lookuptables_usage.jpg) + +-------------------------------- +### Ideal Size Stepper + +**Description:** Plug in your full size dimensions as well as JPPhoto's Ideal Size node's output dimensions, and get 1, 2, or 3 intermediate pairs of dimensions for upscaling based on the natural log of the image area. Thus, each successive generation (from ideal size to full size) adds approximately the same percentage of new pixels to the image. Note this does not output the ideal size or full size dimensions. The 1, 2, or 3 outputs of this node are only the intermediate step sizes. + +There are up to three stages which determine how many intermediate sizes to compute and output. With Tapers B and C disabled, outputs A, B, and C will be the same (inactive outputs yield copies of the previous pair). With a taper assigned to B, Width/Height A and B will both be active with progressively larger intermediate resolutions, and if Taper C is activated, active outputs will be calculated with even finer gradations. + +**Node Link:** https://github.com/dwringer/invoke-nodes/blob/main/ideal_size_stepper.py + +-------------------------------- +### Image Compositor + +**Description:** Take a subject from an image with a flat backdrop and layer it on another image using a chroma key to specify a color value/threshold to remove backdrop pixels, or leave the color blank and a "flood select" will be used from the image corners. + +The subject image may be scaled using the fill X and fill Y options (enable both to stretch-fit). Final subject position may also be adjusted with X offset and Y offset. If used, chroma key may be specified either as an (R, G, B) tuple, or a CSS-3 color string. + +**Node Link:** https://github.com/dwringer/invoke-nodes/blob/main/image_composite.py + +-------------------------------- +### Final Size & Orientation / Random Switch (Integers) + +**Description:** Input two integers, get two out in random, landscape, or portrait orientations. + +Pretty self explanatory. You can just enter your height/width in the two inputs and then get the requested configurations of WxH or HxW from the two outputs. + +Contains two nodes: Final Size & Orientation, and Random Switch (Integer) which was the original, slightly more generalized version. + +**Node Link:** https://github.com/dwringer/invoke-nodes/blob/main/random_switch.py + +-------------------------------- +### Text Mask (simple 2D) + +**Description:** Create a white on black (or black on white) text image for use with controlnets or further processing in other nodes. Specify any TTF/OTF font file available to Invoke and control parameters to resize, rotate, and reposition the text. + +Currently this only generates one line of text, but it can be layered with other images using the Image Compositor node or any other such tool. + +**Node Link:** https://github.com/dwringer/invoke-nodes/blob/main/text_mask.py + -------------------------------- ### Example Node Template From b1ef3370fa0ef3c4025764d90f838cd7f4cf4e91 Mon Sep 17 00:00:00 2001 From: blessedcoolant <54517381+blessedcoolant@users.noreply.github.com> Date: Tue, 5 Sep 2023 09:56:34 +1200 Subject: [PATCH 17/26] chore: Regen Schema --- .../frontend/web/src/services/api/schema.d.ts | 62 ++++++++++++++++--- 1 file changed, 54 insertions(+), 8 deletions(-) diff --git a/invokeai/frontend/web/src/services/api/schema.d.ts b/invokeai/frontend/web/src/services/api/schema.d.ts index 6e00d1b38b..027db814d9 100644 --- a/invokeai/frontend/web/src/services/api/schema.d.ts +++ b/invokeai/frontend/web/src/services/api/schema.d.ts @@ -780,6 +780,39 @@ export type components = { */ type: "boolean_output"; }; + /** + * CV2 Infill + * @description Infills transparent areas of an image using OpenCV Inpainting + */ + CV2InfillInvocation: { + /** + * 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; + /** + * Workflow + * @description The workflow to save with the image + */ + workflow?: string; + /** + * Image + * @description The image to infill + */ + image?: components["schemas"]["ImageField"]; + /** + * Type + * @default infill_cv2 + * @enum {string} + */ + type: "infill_cv2"; + }; /** * Canny Processor * @description Canny edge detection for ControlNet @@ -2212,7 +2245,7 @@ export type components = { * @description The nodes in this graph */ nodes?: { - [key: string]: components["schemas"]["BooleanInvocation"] | components["schemas"]["BooleanCollectionInvocation"] | components["schemas"]["IntegerInvocation"] | components["schemas"]["IntegerCollectionInvocation"] | components["schemas"]["FloatInvocation"] | components["schemas"]["FloatCollectionInvocation"] | components["schemas"]["StringInvocation"] | components["schemas"]["StringCollectionInvocation"] | components["schemas"]["ImageInvocation"] | components["schemas"]["ImageCollectionInvocation"] | components["schemas"]["LatentsInvocation"] | components["schemas"]["LatentsCollectionInvocation"] | components["schemas"]["ColorInvocation"] | components["schemas"]["ConditioningInvocation"] | components["schemas"]["ConditioningCollectionInvocation"] | components["schemas"]["ControlNetInvocation"] | components["schemas"]["ImageProcessorInvocation"] | components["schemas"]["MainModelLoaderInvocation"] | components["schemas"]["LoraLoaderInvocation"] | components["schemas"]["SDXLLoraLoaderInvocation"] | components["schemas"]["VaeLoaderInvocation"] | components["schemas"]["SeamlessModeInvocation"] | components["schemas"]["MetadataAccumulatorInvocation"] | components["schemas"]["SDXLModelLoaderInvocation"] | components["schemas"]["SDXLRefinerModelLoaderInvocation"] | components["schemas"]["CompelInvocation"] | components["schemas"]["SDXLCompelPromptInvocation"] | components["schemas"]["SDXLRefinerCompelPromptInvocation"] | components["schemas"]["ClipSkipInvocation"] | components["schemas"]["SchedulerInvocation"] | components["schemas"]["CreateDenoiseMaskInvocation"] | components["schemas"]["DenoiseLatentsInvocation"] | components["schemas"]["LatentsToImageInvocation"] | components["schemas"]["ResizeLatentsInvocation"] | components["schemas"]["ScaleLatentsInvocation"] | components["schemas"]["ImageToLatentsInvocation"] | components["schemas"]["BlendLatentsInvocation"] | components["schemas"]["ONNXPromptInvocation"] | components["schemas"]["ONNXTextToLatentsInvocation"] | components["schemas"]["ONNXLatentsToImageInvocation"] | components["schemas"]["OnnxModelLoaderInvocation"] | components["schemas"]["ShowImageInvocation"] | components["schemas"]["BlankImageInvocation"] | components["schemas"]["ImageCropInvocation"] | components["schemas"]["ImagePasteInvocation"] | components["schemas"]["MaskFromAlphaInvocation"] | components["schemas"]["ImageMultiplyInvocation"] | components["schemas"]["ImageChannelInvocation"] | components["schemas"]["ImageConvertInvocation"] | components["schemas"]["ImageBlurInvocation"] | components["schemas"]["ImageResizeInvocation"] | components["schemas"]["ImageScaleInvocation"] | components["schemas"]["ImageLerpInvocation"] | components["schemas"]["ImageInverseLerpInvocation"] | components["schemas"]["ImageNSFWBlurInvocation"] | components["schemas"]["ImageWatermarkInvocation"] | components["schemas"]["MaskEdgeInvocation"] | components["schemas"]["MaskCombineInvocation"] | components["schemas"]["ColorCorrectInvocation"] | components["schemas"]["ImageHueAdjustmentInvocation"] | components["schemas"]["ImageLuminosityAdjustmentInvocation"] | components["schemas"]["ImageSaturationAdjustmentInvocation"] | components["schemas"]["DynamicPromptInvocation"] | components["schemas"]["PromptsFromFileInvocation"] | components["schemas"]["CvInpaintInvocation"] | components["schemas"]["FloatLinearRangeInvocation"] | components["schemas"]["StepParamEasingInvocation"] | components["schemas"]["AddInvocation"] | components["schemas"]["SubtractInvocation"] | components["schemas"]["MultiplyInvocation"] | components["schemas"]["DivideInvocation"] | components["schemas"]["RandomIntInvocation"] | components["schemas"]["NoiseInvocation"] | components["schemas"]["RangeInvocation"] | components["schemas"]["RangeOfSizeInvocation"] | components["schemas"]["RandomRangeInvocation"] | components["schemas"]["ESRGANInvocation"] | components["schemas"]["InfillColorInvocation"] | components["schemas"]["InfillTileInvocation"] | components["schemas"]["InfillPatchMatchInvocation"] | components["schemas"]["LaMaInfillInvocation"] | components["schemas"]["GraphInvocation"] | components["schemas"]["IterateInvocation"] | components["schemas"]["CollectInvocation"] | components["schemas"]["CannyImageProcessorInvocation"] | components["schemas"]["HedImageProcessorInvocation"] | components["schemas"]["LineartImageProcessorInvocation"] | components["schemas"]["LineartAnimeImageProcessorInvocation"] | components["schemas"]["OpenposeImageProcessorInvocation"] | components["schemas"]["MidasDepthImageProcessorInvocation"] | components["schemas"]["NormalbaeImageProcessorInvocation"] | components["schemas"]["MlsdImageProcessorInvocation"] | components["schemas"]["PidiImageProcessorInvocation"] | components["schemas"]["ContentShuffleImageProcessorInvocation"] | components["schemas"]["ZoeDepthImageProcessorInvocation"] | components["schemas"]["MediapipeFaceProcessorInvocation"] | components["schemas"]["LeresImageProcessorInvocation"] | components["schemas"]["TileResamplerProcessorInvocation"] | components["schemas"]["SegmentAnythingProcessorInvocation"]; + [key: string]: components["schemas"]["BooleanInvocation"] | components["schemas"]["BooleanCollectionInvocation"] | components["schemas"]["IntegerInvocation"] | components["schemas"]["IntegerCollectionInvocation"] | components["schemas"]["FloatInvocation"] | components["schemas"]["FloatCollectionInvocation"] | components["schemas"]["StringInvocation"] | components["schemas"]["StringCollectionInvocation"] | components["schemas"]["ImageInvocation"] | components["schemas"]["ImageCollectionInvocation"] | components["schemas"]["LatentsInvocation"] | components["schemas"]["LatentsCollectionInvocation"] | components["schemas"]["ColorInvocation"] | components["schemas"]["ConditioningInvocation"] | components["schemas"]["ConditioningCollectionInvocation"] | components["schemas"]["ControlNetInvocation"] | components["schemas"]["ImageProcessorInvocation"] | components["schemas"]["MainModelLoaderInvocation"] | components["schemas"]["LoraLoaderInvocation"] | components["schemas"]["SDXLLoraLoaderInvocation"] | components["schemas"]["VaeLoaderInvocation"] | components["schemas"]["SeamlessModeInvocation"] | components["schemas"]["MetadataAccumulatorInvocation"] | components["schemas"]["RangeInvocation"] | components["schemas"]["RangeOfSizeInvocation"] | components["schemas"]["RandomRangeInvocation"] | components["schemas"]["CompelInvocation"] | components["schemas"]["SDXLCompelPromptInvocation"] | components["schemas"]["SDXLRefinerCompelPromptInvocation"] | components["schemas"]["ClipSkipInvocation"] | components["schemas"]["CvInpaintInvocation"] | components["schemas"]["ShowImageInvocation"] | components["schemas"]["BlankImageInvocation"] | components["schemas"]["ImageCropInvocation"] | components["schemas"]["ImagePasteInvocation"] | components["schemas"]["MaskFromAlphaInvocation"] | components["schemas"]["ImageMultiplyInvocation"] | components["schemas"]["ImageChannelInvocation"] | components["schemas"]["ImageConvertInvocation"] | components["schemas"]["ImageBlurInvocation"] | components["schemas"]["ImageResizeInvocation"] | components["schemas"]["ImageScaleInvocation"] | components["schemas"]["ImageLerpInvocation"] | components["schemas"]["ImageInverseLerpInvocation"] | components["schemas"]["ImageNSFWBlurInvocation"] | components["schemas"]["ImageWatermarkInvocation"] | components["schemas"]["MaskEdgeInvocation"] | components["schemas"]["MaskCombineInvocation"] | components["schemas"]["ColorCorrectInvocation"] | components["schemas"]["ImageHueAdjustmentInvocation"] | components["schemas"]["ImageLuminosityAdjustmentInvocation"] | components["schemas"]["ImageSaturationAdjustmentInvocation"] | components["schemas"]["InfillColorInvocation"] | components["schemas"]["InfillTileInvocation"] | components["schemas"]["InfillPatchMatchInvocation"] | components["schemas"]["LaMaInfillInvocation"] | components["schemas"]["CV2InfillInvocation"] | components["schemas"]["SchedulerInvocation"] | components["schemas"]["CreateDenoiseMaskInvocation"] | components["schemas"]["DenoiseLatentsInvocation"] | components["schemas"]["LatentsToImageInvocation"] | components["schemas"]["ResizeLatentsInvocation"] | components["schemas"]["ScaleLatentsInvocation"] | components["schemas"]["ImageToLatentsInvocation"] | components["schemas"]["BlendLatentsInvocation"] | components["schemas"]["AddInvocation"] | components["schemas"]["SubtractInvocation"] | components["schemas"]["MultiplyInvocation"] | components["schemas"]["DivideInvocation"] | components["schemas"]["RandomIntInvocation"] | components["schemas"]["NoiseInvocation"] | components["schemas"]["ONNXPromptInvocation"] | components["schemas"]["ONNXTextToLatentsInvocation"] | components["schemas"]["ONNXLatentsToImageInvocation"] | components["schemas"]["OnnxModelLoaderInvocation"] | components["schemas"]["FloatLinearRangeInvocation"] | components["schemas"]["StepParamEasingInvocation"] | components["schemas"]["DynamicPromptInvocation"] | components["schemas"]["PromptsFromFileInvocation"] | components["schemas"]["SDXLModelLoaderInvocation"] | components["schemas"]["SDXLRefinerModelLoaderInvocation"] | components["schemas"]["ESRGANInvocation"] | components["schemas"]["GraphInvocation"] | components["schemas"]["IterateInvocation"] | components["schemas"]["CollectInvocation"] | components["schemas"]["CannyImageProcessorInvocation"] | components["schemas"]["HedImageProcessorInvocation"] | components["schemas"]["LineartImageProcessorInvocation"] | components["schemas"]["LineartAnimeImageProcessorInvocation"] | components["schemas"]["OpenposeImageProcessorInvocation"] | components["schemas"]["MidasDepthImageProcessorInvocation"] | components["schemas"]["NormalbaeImageProcessorInvocation"] | components["schemas"]["MlsdImageProcessorInvocation"] | components["schemas"]["PidiImageProcessorInvocation"] | components["schemas"]["ContentShuffleImageProcessorInvocation"] | components["schemas"]["ZoeDepthImageProcessorInvocation"] | components["schemas"]["MediapipeFaceProcessorInvocation"] | components["schemas"]["LeresImageProcessorInvocation"] | components["schemas"]["TileResamplerProcessorInvocation"] | components["schemas"]["SegmentAnythingProcessorInvocation"]; }; /** * Edges @@ -2255,7 +2288,7 @@ export type components = { * @description The results of node executions */ results: { - [key: string]: components["schemas"]["BooleanOutput"] | components["schemas"]["BooleanCollectionOutput"] | components["schemas"]["IntegerOutput"] | components["schemas"]["IntegerCollectionOutput"] | components["schemas"]["FloatOutput"] | components["schemas"]["FloatCollectionOutput"] | components["schemas"]["StringOutput"] | components["schemas"]["StringCollectionOutput"] | components["schemas"]["ImageOutput"] | components["schemas"]["ImageCollectionOutput"] | components["schemas"]["DenoiseMaskOutput"] | components["schemas"]["LatentsOutput"] | components["schemas"]["LatentsCollectionOutput"] | components["schemas"]["ColorOutput"] | components["schemas"]["ColorCollectionOutput"] | components["schemas"]["ConditioningOutput"] | components["schemas"]["ConditioningCollectionOutput"] | components["schemas"]["ControlOutput"] | components["schemas"]["ModelLoaderOutput"] | components["schemas"]["LoraLoaderOutput"] | components["schemas"]["SDXLLoraLoaderOutput"] | components["schemas"]["VaeLoaderOutput"] | components["schemas"]["SeamlessModeOutput"] | components["schemas"]["MetadataAccumulatorOutput"] | components["schemas"]["SDXLModelLoaderOutput"] | components["schemas"]["SDXLRefinerModelLoaderOutput"] | components["schemas"]["ClipSkipInvocationOutput"] | components["schemas"]["SchedulerOutput"] | components["schemas"]["ONNXModelLoaderOutput"] | components["schemas"]["NoiseOutput"] | components["schemas"]["GraphInvocationOutput"] | components["schemas"]["IterateInvocationOutput"] | components["schemas"]["CollectInvocationOutput"]; + [key: string]: components["schemas"]["BooleanOutput"] | components["schemas"]["BooleanCollectionOutput"] | components["schemas"]["IntegerOutput"] | components["schemas"]["IntegerCollectionOutput"] | components["schemas"]["FloatOutput"] | components["schemas"]["FloatCollectionOutput"] | components["schemas"]["StringOutput"] | components["schemas"]["StringCollectionOutput"] | components["schemas"]["ImageOutput"] | components["schemas"]["ImageCollectionOutput"] | components["schemas"]["DenoiseMaskOutput"] | components["schemas"]["LatentsOutput"] | components["schemas"]["LatentsCollectionOutput"] | components["schemas"]["ColorOutput"] | components["schemas"]["ColorCollectionOutput"] | components["schemas"]["ConditioningOutput"] | components["schemas"]["ConditioningCollectionOutput"] | components["schemas"]["ControlOutput"] | components["schemas"]["ModelLoaderOutput"] | components["schemas"]["LoraLoaderOutput"] | components["schemas"]["SDXLLoraLoaderOutput"] | components["schemas"]["VaeLoaderOutput"] | components["schemas"]["SeamlessModeOutput"] | components["schemas"]["MetadataAccumulatorOutput"] | components["schemas"]["ClipSkipInvocationOutput"] | components["schemas"]["SchedulerOutput"] | components["schemas"]["NoiseOutput"] | components["schemas"]["ONNXModelLoaderOutput"] | components["schemas"]["SDXLModelLoaderOutput"] | components["schemas"]["SDXLRefinerModelLoaderOutput"] | components["schemas"]["GraphInvocationOutput"] | components["schemas"]["IterateInvocationOutput"] | components["schemas"]["CollectInvocationOutput"]; }; /** * Errors @@ -3485,6 +3518,19 @@ export type components = { * @description The image to infill */ image?: components["schemas"]["ImageField"]; + /** + * Downscale + * @description Run patchmatch on downscaled image to speedup infill + * @default 2 + */ + downscale?: number; + /** + * Resample Mode + * @description The resampling mode + * @default bicubic + * @enum {string} + */ + resample_mode?: "nearest" | "box" | "bilinear" | "hamming" | "bicubic" | "lanczos"; /** * Type * @default infill_patchmatch @@ -7048,11 +7094,11 @@ export type components = { */ StableDiffusion1ModelFormat: "checkpoint" | "diffusers"; /** - * StableDiffusionXLModelFormat + * ControlNetModelFormat * @description An enumeration. * @enum {string} */ - StableDiffusionXLModelFormat: "checkpoint" | "diffusers"; + ControlNetModelFormat: "checkpoint" | "diffusers"; /** * StableDiffusion2ModelFormat * @description An enumeration. @@ -7060,11 +7106,11 @@ export type components = { */ StableDiffusion2ModelFormat: "checkpoint" | "diffusers"; /** - * ControlNetModelFormat + * StableDiffusionXLModelFormat * @description An enumeration. * @enum {string} */ - ControlNetModelFormat: "checkpoint" | "diffusers"; + StableDiffusionXLModelFormat: "checkpoint" | "diffusers"; /** * StableDiffusionOnnxModelFormat * @description An enumeration. @@ -7187,7 +7233,7 @@ export type operations = { }; requestBody: { content: { - "application/json": components["schemas"]["BooleanInvocation"] | components["schemas"]["BooleanCollectionInvocation"] | components["schemas"]["IntegerInvocation"] | components["schemas"]["IntegerCollectionInvocation"] | components["schemas"]["FloatInvocation"] | components["schemas"]["FloatCollectionInvocation"] | components["schemas"]["StringInvocation"] | components["schemas"]["StringCollectionInvocation"] | components["schemas"]["ImageInvocation"] | components["schemas"]["ImageCollectionInvocation"] | components["schemas"]["LatentsInvocation"] | components["schemas"]["LatentsCollectionInvocation"] | components["schemas"]["ColorInvocation"] | components["schemas"]["ConditioningInvocation"] | components["schemas"]["ConditioningCollectionInvocation"] | components["schemas"]["ControlNetInvocation"] | components["schemas"]["ImageProcessorInvocation"] | components["schemas"]["MainModelLoaderInvocation"] | components["schemas"]["LoraLoaderInvocation"] | components["schemas"]["SDXLLoraLoaderInvocation"] | components["schemas"]["VaeLoaderInvocation"] | components["schemas"]["SeamlessModeInvocation"] | components["schemas"]["MetadataAccumulatorInvocation"] | components["schemas"]["SDXLModelLoaderInvocation"] | components["schemas"]["SDXLRefinerModelLoaderInvocation"] | components["schemas"]["CompelInvocation"] | components["schemas"]["SDXLCompelPromptInvocation"] | components["schemas"]["SDXLRefinerCompelPromptInvocation"] | components["schemas"]["ClipSkipInvocation"] | components["schemas"]["SchedulerInvocation"] | components["schemas"]["CreateDenoiseMaskInvocation"] | components["schemas"]["DenoiseLatentsInvocation"] | components["schemas"]["LatentsToImageInvocation"] | components["schemas"]["ResizeLatentsInvocation"] | components["schemas"]["ScaleLatentsInvocation"] | components["schemas"]["ImageToLatentsInvocation"] | components["schemas"]["BlendLatentsInvocation"] | components["schemas"]["ONNXPromptInvocation"] | components["schemas"]["ONNXTextToLatentsInvocation"] | components["schemas"]["ONNXLatentsToImageInvocation"] | components["schemas"]["OnnxModelLoaderInvocation"] | components["schemas"]["ShowImageInvocation"] | components["schemas"]["BlankImageInvocation"] | components["schemas"]["ImageCropInvocation"] | components["schemas"]["ImagePasteInvocation"] | components["schemas"]["MaskFromAlphaInvocation"] | components["schemas"]["ImageMultiplyInvocation"] | components["schemas"]["ImageChannelInvocation"] | components["schemas"]["ImageConvertInvocation"] | components["schemas"]["ImageBlurInvocation"] | components["schemas"]["ImageResizeInvocation"] | components["schemas"]["ImageScaleInvocation"] | components["schemas"]["ImageLerpInvocation"] | components["schemas"]["ImageInverseLerpInvocation"] | components["schemas"]["ImageNSFWBlurInvocation"] | components["schemas"]["ImageWatermarkInvocation"] | components["schemas"]["MaskEdgeInvocation"] | components["schemas"]["MaskCombineInvocation"] | components["schemas"]["ColorCorrectInvocation"] | components["schemas"]["ImageHueAdjustmentInvocation"] | components["schemas"]["ImageLuminosityAdjustmentInvocation"] | components["schemas"]["ImageSaturationAdjustmentInvocation"] | components["schemas"]["DynamicPromptInvocation"] | components["schemas"]["PromptsFromFileInvocation"] | components["schemas"]["CvInpaintInvocation"] | components["schemas"]["FloatLinearRangeInvocation"] | components["schemas"]["StepParamEasingInvocation"] | components["schemas"]["AddInvocation"] | components["schemas"]["SubtractInvocation"] | components["schemas"]["MultiplyInvocation"] | components["schemas"]["DivideInvocation"] | components["schemas"]["RandomIntInvocation"] | components["schemas"]["NoiseInvocation"] | components["schemas"]["RangeInvocation"] | components["schemas"]["RangeOfSizeInvocation"] | components["schemas"]["RandomRangeInvocation"] | components["schemas"]["ESRGANInvocation"] | components["schemas"]["InfillColorInvocation"] | components["schemas"]["InfillTileInvocation"] | components["schemas"]["InfillPatchMatchInvocation"] | components["schemas"]["LaMaInfillInvocation"] | components["schemas"]["GraphInvocation"] | components["schemas"]["IterateInvocation"] | components["schemas"]["CollectInvocation"] | components["schemas"]["CannyImageProcessorInvocation"] | components["schemas"]["HedImageProcessorInvocation"] | components["schemas"]["LineartImageProcessorInvocation"] | components["schemas"]["LineartAnimeImageProcessorInvocation"] | components["schemas"]["OpenposeImageProcessorInvocation"] | components["schemas"]["MidasDepthImageProcessorInvocation"] | components["schemas"]["NormalbaeImageProcessorInvocation"] | components["schemas"]["MlsdImageProcessorInvocation"] | components["schemas"]["PidiImageProcessorInvocation"] | components["schemas"]["ContentShuffleImageProcessorInvocation"] | components["schemas"]["ZoeDepthImageProcessorInvocation"] | components["schemas"]["MediapipeFaceProcessorInvocation"] | components["schemas"]["LeresImageProcessorInvocation"] | components["schemas"]["TileResamplerProcessorInvocation"] | components["schemas"]["SegmentAnythingProcessorInvocation"]; + "application/json": components["schemas"]["BooleanInvocation"] | components["schemas"]["BooleanCollectionInvocation"] | components["schemas"]["IntegerInvocation"] | components["schemas"]["IntegerCollectionInvocation"] | components["schemas"]["FloatInvocation"] | components["schemas"]["FloatCollectionInvocation"] | components["schemas"]["StringInvocation"] | components["schemas"]["StringCollectionInvocation"] | components["schemas"]["ImageInvocation"] | components["schemas"]["ImageCollectionInvocation"] | components["schemas"]["LatentsInvocation"] | components["schemas"]["LatentsCollectionInvocation"] | components["schemas"]["ColorInvocation"] | components["schemas"]["ConditioningInvocation"] | components["schemas"]["ConditioningCollectionInvocation"] | components["schemas"]["ControlNetInvocation"] | components["schemas"]["ImageProcessorInvocation"] | components["schemas"]["MainModelLoaderInvocation"] | components["schemas"]["LoraLoaderInvocation"] | components["schemas"]["SDXLLoraLoaderInvocation"] | components["schemas"]["VaeLoaderInvocation"] | components["schemas"]["SeamlessModeInvocation"] | components["schemas"]["MetadataAccumulatorInvocation"] | components["schemas"]["RangeInvocation"] | components["schemas"]["RangeOfSizeInvocation"] | components["schemas"]["RandomRangeInvocation"] | components["schemas"]["CompelInvocation"] | components["schemas"]["SDXLCompelPromptInvocation"] | components["schemas"]["SDXLRefinerCompelPromptInvocation"] | components["schemas"]["ClipSkipInvocation"] | components["schemas"]["CvInpaintInvocation"] | components["schemas"]["ShowImageInvocation"] | components["schemas"]["BlankImageInvocation"] | components["schemas"]["ImageCropInvocation"] | components["schemas"]["ImagePasteInvocation"] | components["schemas"]["MaskFromAlphaInvocation"] | components["schemas"]["ImageMultiplyInvocation"] | components["schemas"]["ImageChannelInvocation"] | components["schemas"]["ImageConvertInvocation"] | components["schemas"]["ImageBlurInvocation"] | components["schemas"]["ImageResizeInvocation"] | components["schemas"]["ImageScaleInvocation"] | components["schemas"]["ImageLerpInvocation"] | components["schemas"]["ImageInverseLerpInvocation"] | components["schemas"]["ImageNSFWBlurInvocation"] | components["schemas"]["ImageWatermarkInvocation"] | components["schemas"]["MaskEdgeInvocation"] | components["schemas"]["MaskCombineInvocation"] | components["schemas"]["ColorCorrectInvocation"] | components["schemas"]["ImageHueAdjustmentInvocation"] | components["schemas"]["ImageLuminosityAdjustmentInvocation"] | components["schemas"]["ImageSaturationAdjustmentInvocation"] | components["schemas"]["InfillColorInvocation"] | components["schemas"]["InfillTileInvocation"] | components["schemas"]["InfillPatchMatchInvocation"] | components["schemas"]["LaMaInfillInvocation"] | components["schemas"]["CV2InfillInvocation"] | components["schemas"]["SchedulerInvocation"] | components["schemas"]["CreateDenoiseMaskInvocation"] | components["schemas"]["DenoiseLatentsInvocation"] | components["schemas"]["LatentsToImageInvocation"] | components["schemas"]["ResizeLatentsInvocation"] | components["schemas"]["ScaleLatentsInvocation"] | components["schemas"]["ImageToLatentsInvocation"] | components["schemas"]["BlendLatentsInvocation"] | components["schemas"]["AddInvocation"] | components["schemas"]["SubtractInvocation"] | components["schemas"]["MultiplyInvocation"] | components["schemas"]["DivideInvocation"] | components["schemas"]["RandomIntInvocation"] | components["schemas"]["NoiseInvocation"] | components["schemas"]["ONNXPromptInvocation"] | components["schemas"]["ONNXTextToLatentsInvocation"] | components["schemas"]["ONNXLatentsToImageInvocation"] | components["schemas"]["OnnxModelLoaderInvocation"] | components["schemas"]["FloatLinearRangeInvocation"] | components["schemas"]["StepParamEasingInvocation"] | components["schemas"]["DynamicPromptInvocation"] | components["schemas"]["PromptsFromFileInvocation"] | components["schemas"]["SDXLModelLoaderInvocation"] | components["schemas"]["SDXLRefinerModelLoaderInvocation"] | components["schemas"]["ESRGANInvocation"] | components["schemas"]["GraphInvocation"] | components["schemas"]["IterateInvocation"] | components["schemas"]["CollectInvocation"] | components["schemas"]["CannyImageProcessorInvocation"] | components["schemas"]["HedImageProcessorInvocation"] | components["schemas"]["LineartImageProcessorInvocation"] | components["schemas"]["LineartAnimeImageProcessorInvocation"] | components["schemas"]["OpenposeImageProcessorInvocation"] | components["schemas"]["MidasDepthImageProcessorInvocation"] | components["schemas"]["NormalbaeImageProcessorInvocation"] | components["schemas"]["MlsdImageProcessorInvocation"] | components["schemas"]["PidiImageProcessorInvocation"] | components["schemas"]["ContentShuffleImageProcessorInvocation"] | components["schemas"]["ZoeDepthImageProcessorInvocation"] | components["schemas"]["MediapipeFaceProcessorInvocation"] | components["schemas"]["LeresImageProcessorInvocation"] | components["schemas"]["TileResamplerProcessorInvocation"] | components["schemas"]["SegmentAnythingProcessorInvocation"]; }; }; responses: { @@ -7228,7 +7274,7 @@ export type operations = { }; requestBody: { content: { - "application/json": components["schemas"]["BooleanInvocation"] | components["schemas"]["BooleanCollectionInvocation"] | components["schemas"]["IntegerInvocation"] | components["schemas"]["IntegerCollectionInvocation"] | components["schemas"]["FloatInvocation"] | components["schemas"]["FloatCollectionInvocation"] | components["schemas"]["StringInvocation"] | components["schemas"]["StringCollectionInvocation"] | components["schemas"]["ImageInvocation"] | components["schemas"]["ImageCollectionInvocation"] | components["schemas"]["LatentsInvocation"] | components["schemas"]["LatentsCollectionInvocation"] | components["schemas"]["ColorInvocation"] | components["schemas"]["ConditioningInvocation"] | components["schemas"]["ConditioningCollectionInvocation"] | components["schemas"]["ControlNetInvocation"] | components["schemas"]["ImageProcessorInvocation"] | components["schemas"]["MainModelLoaderInvocation"] | components["schemas"]["LoraLoaderInvocation"] | components["schemas"]["SDXLLoraLoaderInvocation"] | components["schemas"]["VaeLoaderInvocation"] | components["schemas"]["SeamlessModeInvocation"] | components["schemas"]["MetadataAccumulatorInvocation"] | components["schemas"]["SDXLModelLoaderInvocation"] | components["schemas"]["SDXLRefinerModelLoaderInvocation"] | components["schemas"]["CompelInvocation"] | components["schemas"]["SDXLCompelPromptInvocation"] | components["schemas"]["SDXLRefinerCompelPromptInvocation"] | components["schemas"]["ClipSkipInvocation"] | components["schemas"]["SchedulerInvocation"] | components["schemas"]["CreateDenoiseMaskInvocation"] | components["schemas"]["DenoiseLatentsInvocation"] | components["schemas"]["LatentsToImageInvocation"] | components["schemas"]["ResizeLatentsInvocation"] | components["schemas"]["ScaleLatentsInvocation"] | components["schemas"]["ImageToLatentsInvocation"] | components["schemas"]["BlendLatentsInvocation"] | components["schemas"]["ONNXPromptInvocation"] | components["schemas"]["ONNXTextToLatentsInvocation"] | components["schemas"]["ONNXLatentsToImageInvocation"] | components["schemas"]["OnnxModelLoaderInvocation"] | components["schemas"]["ShowImageInvocation"] | components["schemas"]["BlankImageInvocation"] | components["schemas"]["ImageCropInvocation"] | components["schemas"]["ImagePasteInvocation"] | components["schemas"]["MaskFromAlphaInvocation"] | components["schemas"]["ImageMultiplyInvocation"] | components["schemas"]["ImageChannelInvocation"] | components["schemas"]["ImageConvertInvocation"] | components["schemas"]["ImageBlurInvocation"] | components["schemas"]["ImageResizeInvocation"] | components["schemas"]["ImageScaleInvocation"] | components["schemas"]["ImageLerpInvocation"] | components["schemas"]["ImageInverseLerpInvocation"] | components["schemas"]["ImageNSFWBlurInvocation"] | components["schemas"]["ImageWatermarkInvocation"] | components["schemas"]["MaskEdgeInvocation"] | components["schemas"]["MaskCombineInvocation"] | components["schemas"]["ColorCorrectInvocation"] | components["schemas"]["ImageHueAdjustmentInvocation"] | components["schemas"]["ImageLuminosityAdjustmentInvocation"] | components["schemas"]["ImageSaturationAdjustmentInvocation"] | components["schemas"]["DynamicPromptInvocation"] | components["schemas"]["PromptsFromFileInvocation"] | components["schemas"]["CvInpaintInvocation"] | components["schemas"]["FloatLinearRangeInvocation"] | components["schemas"]["StepParamEasingInvocation"] | components["schemas"]["AddInvocation"] | components["schemas"]["SubtractInvocation"] | components["schemas"]["MultiplyInvocation"] | components["schemas"]["DivideInvocation"] | components["schemas"]["RandomIntInvocation"] | components["schemas"]["NoiseInvocation"] | components["schemas"]["RangeInvocation"] | components["schemas"]["RangeOfSizeInvocation"] | components["schemas"]["RandomRangeInvocation"] | components["schemas"]["ESRGANInvocation"] | components["schemas"]["InfillColorInvocation"] | components["schemas"]["InfillTileInvocation"] | components["schemas"]["InfillPatchMatchInvocation"] | components["schemas"]["LaMaInfillInvocation"] | components["schemas"]["GraphInvocation"] | components["schemas"]["IterateInvocation"] | components["schemas"]["CollectInvocation"] | components["schemas"]["CannyImageProcessorInvocation"] | components["schemas"]["HedImageProcessorInvocation"] | components["schemas"]["LineartImageProcessorInvocation"] | components["schemas"]["LineartAnimeImageProcessorInvocation"] | components["schemas"]["OpenposeImageProcessorInvocation"] | components["schemas"]["MidasDepthImageProcessorInvocation"] | components["schemas"]["NormalbaeImageProcessorInvocation"] | components["schemas"]["MlsdImageProcessorInvocation"] | components["schemas"]["PidiImageProcessorInvocation"] | components["schemas"]["ContentShuffleImageProcessorInvocation"] | components["schemas"]["ZoeDepthImageProcessorInvocation"] | components["schemas"]["MediapipeFaceProcessorInvocation"] | components["schemas"]["LeresImageProcessorInvocation"] | components["schemas"]["TileResamplerProcessorInvocation"] | components["schemas"]["SegmentAnythingProcessorInvocation"]; + "application/json": components["schemas"]["BooleanInvocation"] | components["schemas"]["BooleanCollectionInvocation"] | components["schemas"]["IntegerInvocation"] | components["schemas"]["IntegerCollectionInvocation"] | components["schemas"]["FloatInvocation"] | components["schemas"]["FloatCollectionInvocation"] | components["schemas"]["StringInvocation"] | components["schemas"]["StringCollectionInvocation"] | components["schemas"]["ImageInvocation"] | components["schemas"]["ImageCollectionInvocation"] | components["schemas"]["LatentsInvocation"] | components["schemas"]["LatentsCollectionInvocation"] | components["schemas"]["ColorInvocation"] | components["schemas"]["ConditioningInvocation"] | components["schemas"]["ConditioningCollectionInvocation"] | components["schemas"]["ControlNetInvocation"] | components["schemas"]["ImageProcessorInvocation"] | components["schemas"]["MainModelLoaderInvocation"] | components["schemas"]["LoraLoaderInvocation"] | components["schemas"]["SDXLLoraLoaderInvocation"] | components["schemas"]["VaeLoaderInvocation"] | components["schemas"]["SeamlessModeInvocation"] | components["schemas"]["MetadataAccumulatorInvocation"] | components["schemas"]["RangeInvocation"] | components["schemas"]["RangeOfSizeInvocation"] | components["schemas"]["RandomRangeInvocation"] | components["schemas"]["CompelInvocation"] | components["schemas"]["SDXLCompelPromptInvocation"] | components["schemas"]["SDXLRefinerCompelPromptInvocation"] | components["schemas"]["ClipSkipInvocation"] | components["schemas"]["CvInpaintInvocation"] | components["schemas"]["ShowImageInvocation"] | components["schemas"]["BlankImageInvocation"] | components["schemas"]["ImageCropInvocation"] | components["schemas"]["ImagePasteInvocation"] | components["schemas"]["MaskFromAlphaInvocation"] | components["schemas"]["ImageMultiplyInvocation"] | components["schemas"]["ImageChannelInvocation"] | components["schemas"]["ImageConvertInvocation"] | components["schemas"]["ImageBlurInvocation"] | components["schemas"]["ImageResizeInvocation"] | components["schemas"]["ImageScaleInvocation"] | components["schemas"]["ImageLerpInvocation"] | components["schemas"]["ImageInverseLerpInvocation"] | components["schemas"]["ImageNSFWBlurInvocation"] | components["schemas"]["ImageWatermarkInvocation"] | components["schemas"]["MaskEdgeInvocation"] | components["schemas"]["MaskCombineInvocation"] | components["schemas"]["ColorCorrectInvocation"] | components["schemas"]["ImageHueAdjustmentInvocation"] | components["schemas"]["ImageLuminosityAdjustmentInvocation"] | components["schemas"]["ImageSaturationAdjustmentInvocation"] | components["schemas"]["InfillColorInvocation"] | components["schemas"]["InfillTileInvocation"] | components["schemas"]["InfillPatchMatchInvocation"] | components["schemas"]["LaMaInfillInvocation"] | components["schemas"]["CV2InfillInvocation"] | components["schemas"]["SchedulerInvocation"] | components["schemas"]["CreateDenoiseMaskInvocation"] | components["schemas"]["DenoiseLatentsInvocation"] | components["schemas"]["LatentsToImageInvocation"] | components["schemas"]["ResizeLatentsInvocation"] | components["schemas"]["ScaleLatentsInvocation"] | components["schemas"]["ImageToLatentsInvocation"] | components["schemas"]["BlendLatentsInvocation"] | components["schemas"]["AddInvocation"] | components["schemas"]["SubtractInvocation"] | components["schemas"]["MultiplyInvocation"] | components["schemas"]["DivideInvocation"] | components["schemas"]["RandomIntInvocation"] | components["schemas"]["NoiseInvocation"] | components["schemas"]["ONNXPromptInvocation"] | components["schemas"]["ONNXTextToLatentsInvocation"] | components["schemas"]["ONNXLatentsToImageInvocation"] | components["schemas"]["OnnxModelLoaderInvocation"] | components["schemas"]["FloatLinearRangeInvocation"] | components["schemas"]["StepParamEasingInvocation"] | components["schemas"]["DynamicPromptInvocation"] | components["schemas"]["PromptsFromFileInvocation"] | components["schemas"]["SDXLModelLoaderInvocation"] | components["schemas"]["SDXLRefinerModelLoaderInvocation"] | components["schemas"]["ESRGANInvocation"] | components["schemas"]["GraphInvocation"] | components["schemas"]["IterateInvocation"] | components["schemas"]["CollectInvocation"] | components["schemas"]["CannyImageProcessorInvocation"] | components["schemas"]["HedImageProcessorInvocation"] | components["schemas"]["LineartImageProcessorInvocation"] | components["schemas"]["LineartAnimeImageProcessorInvocation"] | components["schemas"]["OpenposeImageProcessorInvocation"] | components["schemas"]["MidasDepthImageProcessorInvocation"] | components["schemas"]["NormalbaeImageProcessorInvocation"] | components["schemas"]["MlsdImageProcessorInvocation"] | components["schemas"]["PidiImageProcessorInvocation"] | components["schemas"]["ContentShuffleImageProcessorInvocation"] | components["schemas"]["ZoeDepthImageProcessorInvocation"] | components["schemas"]["MediapipeFaceProcessorInvocation"] | components["schemas"]["LeresImageProcessorInvocation"] | components["schemas"]["TileResamplerProcessorInvocation"] | components["schemas"]["SegmentAnythingProcessorInvocation"]; }; }; responses: { From edd64bd53718f5ebeba9dcad4f9186b590b0fed1 Mon Sep 17 00:00:00 2001 From: Darren Ringer Date: Mon, 4 Sep 2023 19:25:12 -0400 Subject: [PATCH 18/26] Replace links to .py files with repo links, and consolidate some nodes Revised links to my node py files, replacing them with links to independent repos. Additionally I consolidated some nodes together (Image and Mask Composition Pack, Size Stepper nodes). --- docs/nodes/communityNodes.md | 71 ++++++++++++++++-------------------- 1 file changed, 32 insertions(+), 39 deletions(-) diff --git a/docs/nodes/communityNodes.md b/docs/nodes/communityNodes.md index 34dfbdb443..e4d5dbdd68 100644 --- a/docs/nodes/communityNodes.md +++ b/docs/nodes/communityNodes.md @@ -120,74 +120,67 @@ There are simple parameters to change the FOV, camera position, and model orient Additional parameters like different image sizes will probably be added, and things like more sophisticated rotations are planned but this node is experimental and may or may not change much. -**Node Link:** https://github.com/dwringer/invoke-nodes/blob/main/depth_from_obj.py +**Node Link:** https://github.com/dwringer/depth-from-obj-node + +**Example Usage:** +![depth from obj usage graph](https://raw.githubusercontent.com/dwringer/depth-from-obj-node/main/depth_from_obj_usage.jpg) -------------------------------- -### Enhance Image +### Enhance Image (simple adjustments) **Description:** Boost or reduce color saturation, contrast, brightness, sharpness, or invert colors of any image at any stage with this simple wrapper for pillow [PIL]'s ImageEnhance module. Color inversion is toggled with a simple switch, while each of the four enhancer modes are activated by entering a value other than 1 in each corresponding input field. Values less than 1 will reduce the corresponding property, while values greater than 1 will enhance it. -**Node Link:** https://github.com/dwringer/invoke-nodes/blob/main/image_enhance.py +**Node Link:** https://github.com/dwringer/image-enhance-node + +**Example Usage:** +![enhance image usage graph](https://raw.githubusercontent.com/dwringer/image-enhance-node/main/image_enhance_usage.jpg) -------------------------------- ### Generative Grammar-Based Prompt Nodes -**Description:** This generates prompts from simple user-defined grammar rules (loaded from custom files - examples provided below). The prompts are made by recursively expanding a special template string, replacing nonterminal "parts-of-speech" until no more nonterminal terms remain in the string. +**Description:** This set of 3 nodes generates prompts from simple user-defined grammar rules (loaded from custom files - examples provided below). The prompts are made by recursively expanding a special template string, replacing nonterminal "parts-of-speech" until no more nonterminal terms remain in the string. -**Three nodes are included:** +This includes 3 Nodes: - *Lookup Table from File* - loads a YAML file "prompt" section (or of a whole folder of YAML's) into a JSON-ified dictionary (Lookups output) - *Lookups Entry from Prompt* - places a single entry in a new Lookups output under the specified heading -- *Prompt from LookupTable* - uses a Collection of Lookups as grammar rules from which to randomly generate prompts. +- *Prompt from Lookup Table* - uses a Collection of Lookups as grammar rules from which to randomly generate prompts. -**Node Link:** https://github.com/dwringer/invoke-nodes/blob/main/lookuptables.py - -**Example Templates:** -- https://github.com/dwringer/invoke-nodes/blob/main/example_template.yaml -- https://github.com/dwringer/invoke-nodes/blob/main/movies.yaml -- https://github.com/dwringer/invoke-nodes/blob/main/photograph.yaml +**Node Link:** https://github.com/dwringer/generative-grammar-prompt-nodes **Example Usage:** -![lookups usage example graph](https://raw.githubusercontent.com/dwringer/invoke-nodes/main/lookuptables_usage.jpg) +![lookups usage example graph](https://raw.githubusercontent.com/dwringer/generative-grammar-prompt-nodes/main/lookuptables_usage.jpg) -------------------------------- -### Ideal Size Stepper +### Image and Mask Composition Pack -**Description:** Plug in your full size dimensions as well as JPPhoto's Ideal Size node's output dimensions, and get 1, 2, or 3 intermediate pairs of dimensions for upscaling based on the natural log of the image area. Thus, each successive generation (from ideal size to full size) adds approximately the same percentage of new pixels to the image. Note this does not output the ideal size or full size dimensions. The 1, 2, or 3 outputs of this node are only the intermediate step sizes. +**Description:** This is a pack of nodes for composing masks and images, including a simple text mask creator and both image and latent offset nodes. The offsets wrap around, so these can be used in conjunction with the Seamless node to progressively generate centered on different parts of the seamless tiling. -There are up to three stages which determine how many intermediate sizes to compute and output. With Tapers B and C disabled, outputs A, B, and C will be the same (inactive outputs yield copies of the previous pair). With a taper assigned to B, Width/Height A and B will both be active with progressively larger intermediate resolutions, and if Taper C is activated, active outputs will be calculated with even finer gradations. +This includes 4 Nodes: +- Text Mask (simple 2D) - create and position a white on black (or black on white) line of text using any font locally available to Invoke. +- Image Compositor - Take a subject from an image with a flat backdrop and layer it on another image using a chroma key or flood select background removal. +- Offset Latents - Offset a latents tensor in the vertical and/or horizontal dimensions, wrapping it around. +- Offset Image - Offset an image in the vertical and/or horizontal dimensions, wrapping it around. -**Node Link:** https://github.com/dwringer/invoke-nodes/blob/main/ideal_size_stepper.py +**Node Link:** https://github.com/dwringer/composition-nodes + +**Example Usage:** +![composition nodes usage graph](https://raw.githubusercontent.com/dwringer/composition-nodes/main/composition_nodes_usage.jpg) -------------------------------- -### Image Compositor +### Size Stepper Nodes -**Description:** Take a subject from an image with a flat backdrop and layer it on another image using a chroma key to specify a color value/threshold to remove backdrop pixels, or leave the color blank and a "flood select" will be used from the image corners. +**Description:** This is a set of nodes for calculating the necessary size increments for doing upscaling workflows. Use the Final Size & Orientation node to enter your full size dimensions and orientation (portrait/landscape/random), then plug that and your initial generation dimensions into the Ideal Size Stepper and get 1, 2, or 3 intermediate pairs of dimensions for upscaling. Note this does not output the initial size or full size dimensions. The 1, 2, or 3 outputs of this node are only the intermediate sizes. -The subject image may be scaled using the fill X and fill Y options (enable both to stretch-fit). Final subject position may also be adjusted with X offset and Y offset. If used, chroma key may be specified either as an (R, G, B) tuple, or a CSS-3 color string. +For the Ideal Size Stepper, there are up to three stages which determine how many intermediate sizes to compute and output. With Tapers B and C disabled, outputs A, B, and C will be the same (inactive outputs yield copies of the previous pair). With a taper assigned to B, Width/Height A and B will both be active with progressively larger intermediate resolutions, and if Taper C is activated, active outputs will be calculated with even finer gradations. -**Node Link:** https://github.com/dwringer/invoke-nodes/blob/main/image_composite.py +A third node is included, Random Switch (Integers), which is just a generic version of Final Size with no orientation selection. --------------------------------- -### Final Size & Orientation / Random Switch (Integers) +**Node Link:** https://github.com/dwringer/size-stepper-nodes -**Description:** Input two integers, get two out in random, landscape, or portrait orientations. - -Pretty self explanatory. You can just enter your height/width in the two inputs and then get the requested configurations of WxH or HxW from the two outputs. - -Contains two nodes: Final Size & Orientation, and Random Switch (Integer) which was the original, slightly more generalized version. - -**Node Link:** https://github.com/dwringer/invoke-nodes/blob/main/random_switch.py - --------------------------------- -### Text Mask (simple 2D) - -**Description:** Create a white on black (or black on white) text image for use with controlnets or further processing in other nodes. Specify any TTF/OTF font file available to Invoke and control parameters to resize, rotate, and reposition the text. - -Currently this only generates one line of text, but it can be layered with other images using the Image Compositor node or any other such tool. - -**Node Link:** https://github.com/dwringer/invoke-nodes/blob/main/text_mask.py +**Example Usage:** +![size stepper usage graph](https://raw.githubusercontent.com/dwringer/size-stepper-nodes/main/size_nodes_usage.jpg) -------------------------------- From ac3bf81ca45525453517694010f9779423912a75 Mon Sep 17 00:00:00 2001 From: Darren Ringer Date: Mon, 4 Sep 2023 20:21:48 -0400 Subject: [PATCH 19/26] Update communityNodes.md for consistency and conciseness Trims down a couple of my node descriptions and adjusts the formatting a little bit for consistency. --- docs/nodes/communityNodes.md | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/docs/nodes/communityNodes.md b/docs/nodes/communityNodes.md index e4d5dbdd68..ffb562f09e 100644 --- a/docs/nodes/communityNodes.md +++ b/docs/nodes/communityNodes.md @@ -112,14 +112,10 @@ This node works best with SDXL models, especially as the style can be described -------------------------------- ### Depth Map from Wavefront OBJ -**Description:** Render depth maps from Wavefront .obj files (triangulated) using this simple 3D renderer utilizing numpy and matplotlib to compute and color the scene. +**Description:** Render depth maps from Wavefront .obj files (triangulated) using this simple 3D renderer utilizing numpy and matplotlib to compute and color the scene. There are simple parameters to change the FOV, camera position, and model orientation. To be imported, an .obj must use triangulated meshes, so make sure to enable that option if exporting from a 3D modeling program. This renderer makes each triangle a solid color based on its average depth, so it will cause anomalies if your .obj has large triangles. In Blender, the Remesh modifier can be helpful to subdivide a mesh into small pieces that work well given these limitations. -There are simple parameters to change the FOV, camera position, and model orientation. - -Additional parameters like different image sizes will probably be added, and things like more sophisticated rotations are planned but this node is experimental and may or may not change much. - **Node Link:** https://github.com/dwringer/depth-from-obj-node **Example Usage:** @@ -158,10 +154,10 @@ This includes 3 Nodes: **Description:** This is a pack of nodes for composing masks and images, including a simple text mask creator and both image and latent offset nodes. The offsets wrap around, so these can be used in conjunction with the Seamless node to progressively generate centered on different parts of the seamless tiling. This includes 4 Nodes: -- Text Mask (simple 2D) - create and position a white on black (or black on white) line of text using any font locally available to Invoke. -- Image Compositor - Take a subject from an image with a flat backdrop and layer it on another image using a chroma key or flood select background removal. -- Offset Latents - Offset a latents tensor in the vertical and/or horizontal dimensions, wrapping it around. -- Offset Image - Offset an image in the vertical and/or horizontal dimensions, wrapping it around. +- *Text Mask (simple 2D)* - create and position a white on black (or black on white) line of text using any font locally available to Invoke. +- *Image Compositor* - Take a subject from an image with a flat backdrop and layer it on another image using a chroma key or flood select background removal. +- *Offset Latents* - Offset a latents tensor in the vertical and/or horizontal dimensions, wrapping it around. +- *Offset Image* - Offset an image in the vertical and/or horizontal dimensions, wrapping it around. **Node Link:** https://github.com/dwringer/composition-nodes @@ -171,11 +167,9 @@ This includes 4 Nodes: -------------------------------- ### Size Stepper Nodes -**Description:** This is a set of nodes for calculating the necessary size increments for doing upscaling workflows. Use the Final Size & Orientation node to enter your full size dimensions and orientation (portrait/landscape/random), then plug that and your initial generation dimensions into the Ideal Size Stepper and get 1, 2, or 3 intermediate pairs of dimensions for upscaling. Note this does not output the initial size or full size dimensions. The 1, 2, or 3 outputs of this node are only the intermediate sizes. +**Description:** This is a set of nodes for calculating the necessary size increments for doing upscaling workflows. Use the *Final Size & Orientation* node to enter your full size dimensions and orientation (portrait/landscape/random), then plug that and your initial generation dimensions into the *Ideal Size Stepper* and get 1, 2, or 3 intermediate pairs of dimensions for upscaling. Note this does not output the initial size or full size dimensions: the 1, 2, or 3 outputs of this node are only the intermediate sizes. -For the Ideal Size Stepper, there are up to three stages which determine how many intermediate sizes to compute and output. With Tapers B and C disabled, outputs A, B, and C will be the same (inactive outputs yield copies of the previous pair). With a taper assigned to B, Width/Height A and B will both be active with progressively larger intermediate resolutions, and if Taper C is activated, active outputs will be calculated with even finer gradations. - -A third node is included, Random Switch (Integers), which is just a generic version of Final Size with no orientation selection. +A third node is included, *Random Switch (Integers)*, which is just a generic version of Final Size with no orientation selection. **Node Link:** https://github.com/dwringer/size-stepper-nodes From 10eec546adabe95ab07a51001095dec94fa8d532 Mon Sep 17 00:00:00 2001 From: dunkeroni Date: Mon, 4 Sep 2023 21:18:37 -0400 Subject: [PATCH 20/26] Consolidate and generalize saturation/luminosity adjusters (#4425) * Consolidated saturation/luminosity adjust. Now allows increasing and inverting. Accepts any color PIL format and channel designation. * Updated docs/nodes/defaultNodes.md * shortened tags list to channel types only * fix typo in mode list * split features into offset and multiply nodes * Updated documentation * Change invert to discrete boolean. Previous math was unclear and had issues with 0 values. * chore: black * chore(ui): typegen --------- Co-authored-by: psychedelicious <4822129+psychedelicious@users.noreply.github.com> --- docs/nodes/defaultNodes.md | 4 +- invokeai/app/invocations/image.py | 152 ++++++++++---- .../frontend/web/src/services/api/schema.d.ts | 192 ++++++++++-------- 3 files changed, 223 insertions(+), 125 deletions(-) diff --git a/docs/nodes/defaultNodes.md b/docs/nodes/defaultNodes.md index 7748f635cb..8bc304216d 100644 --- a/docs/nodes/defaultNodes.md +++ b/docs/nodes/defaultNodes.md @@ -35,13 +35,13 @@ The table below contains a list of the default nodes shipped with InvokeAI and t |Inverse Lerp Image | Inverse linear interpolation of all pixels of an image| |Image Primitive | An image primitive value| |Lerp Image | Linear interpolation of all pixels of an image| -|Image Luminosity Adjustment | Adjusts the Luminosity (Value) of an image.| +|Offset Image Channel | Add to or subtract from an image color channel by a uniform value.| +|Multiply Image Channel | Multiply or Invert an image color channel by a scalar value.| |Multiply Images | Multiplies two images together using `PIL.ImageChops.multiply()`.| |Blur NSFW Image | Add blur to NSFW-flagged images| |Paste Image | Pastes an image into another image.| |ImageProcessor | Base class for invocations that preprocess images for ControlNet| |Resize Image | Resizes an image to specific dimensions| -|Image Saturation Adjustment | Adjusts the Saturation of an image.| |Scale Image | Scales an image by a factor| |Image to Latents | Encodes an image into latents.| |Add Invisible Watermark | Add an invisible watermark to an image| diff --git a/invokeai/app/invocations/image.py b/invokeai/app/invocations/image.py index b6f7cc405b..af7b5fe589 100644 --- a/invokeai/app/invocations/image.py +++ b/invokeai/app/invocations/image.py @@ -773,39 +773,95 @@ class ImageHueAdjustmentInvocation(BaseInvocation): ) +COLOR_CHANNELS = Literal[ + "Red (RGBA)", + "Green (RGBA)", + "Blue (RGBA)", + "Alpha (RGBA)", + "Cyan (CMYK)", + "Magenta (CMYK)", + "Yellow (CMYK)", + "Black (CMYK)", + "Hue (HSV)", + "Saturation (HSV)", + "Value (HSV)", + "Luminosity (LAB)", + "A (LAB)", + "B (LAB)", + "Y (YCbCr)", + "Cb (YCbCr)", + "Cr (YCbCr)", +] + +CHANNEL_FORMATS = { + "Red (RGBA)": ("RGBA", 0), + "Green (RGBA)": ("RGBA", 1), + "Blue (RGBA)": ("RGBA", 2), + "Alpha (RGBA)": ("RGBA", 3), + "Cyan (CMYK)": ("CMYK", 0), + "Magenta (CMYK)": ("CMYK", 1), + "Yellow (CMYK)": ("CMYK", 2), + "Black (CMYK)": ("CMYK", 3), + "Hue (HSV)": ("HSV", 0), + "Saturation (HSV)": ("HSV", 1), + "Value (HSV)": ("HSV", 2), + "Luminosity (LAB)": ("LAB", 0), + "A (LAB)": ("LAB", 1), + "B (LAB)": ("LAB", 2), + "Y (YCbCr)": ("YCbCr", 0), + "Cb (YCbCr)": ("YCbCr", 1), + "Cr (YCbCr)": ("YCbCr", 2), +} + + @invocation( - "img_luminosity_adjust", - title="Adjust Image Luminosity", - tags=["image", "luminosity", "hsl"], + "img_channel_offset", + title="Offset Image Channel", + tags=[ + "image", + "offset", + "red", + "green", + "blue", + "alpha", + "cyan", + "magenta", + "yellow", + "black", + "hue", + "saturation", + "luminosity", + "value", + ], category="image", version="1.0.0", ) -class ImageLuminosityAdjustmentInvocation(BaseInvocation): - """Adjusts the Luminosity (Value) of an image.""" +class ImageChannelOffsetInvocation(BaseInvocation): + """Add or subtract a value from a specific color channel of an image.""" image: ImageField = InputField(description="The image to adjust") - luminosity: float = InputField( - default=1.0, ge=0, le=1, description="The factor by which to adjust the luminosity (value)" - ) + channel: COLOR_CHANNELS = InputField(description="Which channel to adjust") + offset: int = InputField(default=0, ge=-255, le=255, description="The amount to adjust the channel by") def invoke(self, context: InvocationContext) -> ImageOutput: pil_image = context.services.images.get_pil_image(self.image.image_name) - # Convert PIL image to OpenCV format (numpy array), note color channel - # ordering is changed from RGB to BGR - image = numpy.array(pil_image.convert("RGB"))[:, :, ::-1] + # extract the channel and mode from the input and reference tuple + mode = CHANNEL_FORMATS[self.channel][0] + channel_number = CHANNEL_FORMATS[self.channel][1] - # Convert image to HSV color space - hsv_image = cv2.cvtColor(image, cv2.COLOR_BGR2HSV) + # Convert PIL image to new format + converted_image = numpy.array(pil_image.convert(mode)).astype(int) + image_channel = converted_image[:, :, channel_number] - # Adjust the luminosity (value) - hsv_image[:, :, 2] = numpy.clip(hsv_image[:, :, 2] * self.luminosity, 0, 255) + # Adjust the value, clipping to 0..255 + image_channel = numpy.clip(image_channel + self.offset, 0, 255) - # Convert image back to BGR color space - image = cv2.cvtColor(hsv_image, cv2.COLOR_HSV2BGR) + # Put the channel back into the image + converted_image[:, :, channel_number] = image_channel - # Convert back to PIL format and to original color mode - pil_image = Image.fromarray(image[:, :, ::-1], "RGB").convert("RGBA") + # Convert back to RGBA format and output + pil_image = Image.fromarray(converted_image.astype(numpy.uint8), mode=mode).convert("RGBA") image_dto = context.services.images.create( image=pil_image, @@ -827,36 +883,60 @@ class ImageLuminosityAdjustmentInvocation(BaseInvocation): @invocation( - "img_saturation_adjust", - title="Adjust Image Saturation", - tags=["image", "saturation", "hsl"], + "img_channel_multiply", + title="Multiply Image Channel", + tags=[ + "image", + "invert", + "scale", + "multiply", + "red", + "green", + "blue", + "alpha", + "cyan", + "magenta", + "yellow", + "black", + "hue", + "saturation", + "luminosity", + "value", + ], category="image", version="1.0.0", ) -class ImageSaturationAdjustmentInvocation(BaseInvocation): - """Adjusts the Saturation of an image.""" +class ImageChannelMultiplyInvocation(BaseInvocation): + """Scale a specific color channel of an image.""" image: ImageField = InputField(description="The image to adjust") - saturation: float = InputField(default=1.0, ge=0, le=1, description="The factor by which to adjust the saturation") + channel: COLOR_CHANNELS = InputField(description="Which channel to adjust") + scale: float = InputField(default=1.0, ge=0.0, description="The amount to scale the channel by.") + invert_channel: bool = InputField(default=False, description="Invert the channel after scaling") def invoke(self, context: InvocationContext) -> ImageOutput: pil_image = context.services.images.get_pil_image(self.image.image_name) - # Convert PIL image to OpenCV format (numpy array), note color channel - # ordering is changed from RGB to BGR - image = numpy.array(pil_image.convert("RGB"))[:, :, ::-1] + # extract the channel and mode from the input and reference tuple + mode = CHANNEL_FORMATS[self.channel][0] + channel_number = CHANNEL_FORMATS[self.channel][1] - # Convert image to HSV color space - hsv_image = cv2.cvtColor(image, cv2.COLOR_BGR2HSV) + # Convert PIL image to new format + converted_image = numpy.array(pil_image.convert(mode)).astype(float) + image_channel = converted_image[:, :, channel_number] - # Adjust the saturation - hsv_image[:, :, 1] = numpy.clip(hsv_image[:, :, 1] * self.saturation, 0, 255) + # Adjust the value, clipping to 0..255 + image_channel = numpy.clip(image_channel * self.scale, 0, 255) - # Convert image back to BGR color space - image = cv2.cvtColor(hsv_image, cv2.COLOR_HSV2BGR) + # Invert the channel if requested + if self.invert_channel: + image_channel = 255 - image_channel - # Convert back to PIL format and to original color mode - pil_image = Image.fromarray(image[:, :, ::-1], "RGB").convert("RGBA") + # Put the channel back into the image + converted_image[:, :, channel_number] = image_channel + + # Convert back to RGBA format and output + pil_image = Image.fromarray(converted_image.astype(numpy.uint8), mode=mode).convert("RGBA") image_dto = context.services.images.create( image=pil_image, diff --git a/invokeai/frontend/web/src/services/api/schema.d.ts b/invokeai/frontend/web/src/services/api/schema.d.ts index 6e00d1b38b..986cade3b6 100644 --- a/invokeai/frontend/web/src/services/api/schema.d.ts +++ b/invokeai/frontend/web/src/services/api/schema.d.ts @@ -2212,7 +2212,7 @@ export type components = { * @description The nodes in this graph */ nodes?: { - [key: string]: components["schemas"]["BooleanInvocation"] | components["schemas"]["BooleanCollectionInvocation"] | components["schemas"]["IntegerInvocation"] | components["schemas"]["IntegerCollectionInvocation"] | components["schemas"]["FloatInvocation"] | components["schemas"]["FloatCollectionInvocation"] | components["schemas"]["StringInvocation"] | components["schemas"]["StringCollectionInvocation"] | components["schemas"]["ImageInvocation"] | components["schemas"]["ImageCollectionInvocation"] | components["schemas"]["LatentsInvocation"] | components["schemas"]["LatentsCollectionInvocation"] | components["schemas"]["ColorInvocation"] | components["schemas"]["ConditioningInvocation"] | components["schemas"]["ConditioningCollectionInvocation"] | components["schemas"]["ControlNetInvocation"] | components["schemas"]["ImageProcessorInvocation"] | components["schemas"]["MainModelLoaderInvocation"] | components["schemas"]["LoraLoaderInvocation"] | components["schemas"]["SDXLLoraLoaderInvocation"] | components["schemas"]["VaeLoaderInvocation"] | components["schemas"]["SeamlessModeInvocation"] | components["schemas"]["MetadataAccumulatorInvocation"] | components["schemas"]["SDXLModelLoaderInvocation"] | components["schemas"]["SDXLRefinerModelLoaderInvocation"] | components["schemas"]["CompelInvocation"] | components["schemas"]["SDXLCompelPromptInvocation"] | components["schemas"]["SDXLRefinerCompelPromptInvocation"] | components["schemas"]["ClipSkipInvocation"] | components["schemas"]["SchedulerInvocation"] | components["schemas"]["CreateDenoiseMaskInvocation"] | components["schemas"]["DenoiseLatentsInvocation"] | components["schemas"]["LatentsToImageInvocation"] | components["schemas"]["ResizeLatentsInvocation"] | components["schemas"]["ScaleLatentsInvocation"] | components["schemas"]["ImageToLatentsInvocation"] | components["schemas"]["BlendLatentsInvocation"] | components["schemas"]["ONNXPromptInvocation"] | components["schemas"]["ONNXTextToLatentsInvocation"] | components["schemas"]["ONNXLatentsToImageInvocation"] | components["schemas"]["OnnxModelLoaderInvocation"] | components["schemas"]["ShowImageInvocation"] | components["schemas"]["BlankImageInvocation"] | components["schemas"]["ImageCropInvocation"] | components["schemas"]["ImagePasteInvocation"] | components["schemas"]["MaskFromAlphaInvocation"] | components["schemas"]["ImageMultiplyInvocation"] | components["schemas"]["ImageChannelInvocation"] | components["schemas"]["ImageConvertInvocation"] | components["schemas"]["ImageBlurInvocation"] | components["schemas"]["ImageResizeInvocation"] | components["schemas"]["ImageScaleInvocation"] | components["schemas"]["ImageLerpInvocation"] | components["schemas"]["ImageInverseLerpInvocation"] | components["schemas"]["ImageNSFWBlurInvocation"] | components["schemas"]["ImageWatermarkInvocation"] | components["schemas"]["MaskEdgeInvocation"] | components["schemas"]["MaskCombineInvocation"] | components["schemas"]["ColorCorrectInvocation"] | components["schemas"]["ImageHueAdjustmentInvocation"] | components["schemas"]["ImageLuminosityAdjustmentInvocation"] | components["schemas"]["ImageSaturationAdjustmentInvocation"] | components["schemas"]["DynamicPromptInvocation"] | components["schemas"]["PromptsFromFileInvocation"] | components["schemas"]["CvInpaintInvocation"] | components["schemas"]["FloatLinearRangeInvocation"] | components["schemas"]["StepParamEasingInvocation"] | components["schemas"]["AddInvocation"] | components["schemas"]["SubtractInvocation"] | components["schemas"]["MultiplyInvocation"] | components["schemas"]["DivideInvocation"] | components["schemas"]["RandomIntInvocation"] | components["schemas"]["NoiseInvocation"] | components["schemas"]["RangeInvocation"] | components["schemas"]["RangeOfSizeInvocation"] | components["schemas"]["RandomRangeInvocation"] | components["schemas"]["ESRGANInvocation"] | components["schemas"]["InfillColorInvocation"] | components["schemas"]["InfillTileInvocation"] | components["schemas"]["InfillPatchMatchInvocation"] | components["schemas"]["LaMaInfillInvocation"] | components["schemas"]["GraphInvocation"] | components["schemas"]["IterateInvocation"] | components["schemas"]["CollectInvocation"] | components["schemas"]["CannyImageProcessorInvocation"] | components["schemas"]["HedImageProcessorInvocation"] | components["schemas"]["LineartImageProcessorInvocation"] | components["schemas"]["LineartAnimeImageProcessorInvocation"] | components["schemas"]["OpenposeImageProcessorInvocation"] | components["schemas"]["MidasDepthImageProcessorInvocation"] | components["schemas"]["NormalbaeImageProcessorInvocation"] | components["schemas"]["MlsdImageProcessorInvocation"] | components["schemas"]["PidiImageProcessorInvocation"] | components["schemas"]["ContentShuffleImageProcessorInvocation"] | components["schemas"]["ZoeDepthImageProcessorInvocation"] | components["schemas"]["MediapipeFaceProcessorInvocation"] | components["schemas"]["LeresImageProcessorInvocation"] | components["schemas"]["TileResamplerProcessorInvocation"] | components["schemas"]["SegmentAnythingProcessorInvocation"]; + [key: string]: components["schemas"]["BooleanInvocation"] | components["schemas"]["BooleanCollectionInvocation"] | components["schemas"]["IntegerInvocation"] | components["schemas"]["IntegerCollectionInvocation"] | components["schemas"]["FloatInvocation"] | components["schemas"]["FloatCollectionInvocation"] | components["schemas"]["StringInvocation"] | components["schemas"]["StringCollectionInvocation"] | components["schemas"]["ImageInvocation"] | components["schemas"]["ImageCollectionInvocation"] | components["schemas"]["LatentsInvocation"] | components["schemas"]["LatentsCollectionInvocation"] | components["schemas"]["ColorInvocation"] | components["schemas"]["ConditioningInvocation"] | components["schemas"]["ConditioningCollectionInvocation"] | components["schemas"]["ControlNetInvocation"] | components["schemas"]["ImageProcessorInvocation"] | components["schemas"]["MainModelLoaderInvocation"] | components["schemas"]["LoraLoaderInvocation"] | components["schemas"]["SDXLLoraLoaderInvocation"] | components["schemas"]["VaeLoaderInvocation"] | components["schemas"]["SeamlessModeInvocation"] | components["schemas"]["MetadataAccumulatorInvocation"] | components["schemas"]["SDXLModelLoaderInvocation"] | components["schemas"]["SDXLRefinerModelLoaderInvocation"] | components["schemas"]["CompelInvocation"] | components["schemas"]["SDXLCompelPromptInvocation"] | components["schemas"]["SDXLRefinerCompelPromptInvocation"] | components["schemas"]["ClipSkipInvocation"] | components["schemas"]["SchedulerInvocation"] | components["schemas"]["CreateDenoiseMaskInvocation"] | components["schemas"]["DenoiseLatentsInvocation"] | components["schemas"]["LatentsToImageInvocation"] | components["schemas"]["ResizeLatentsInvocation"] | components["schemas"]["ScaleLatentsInvocation"] | components["schemas"]["ImageToLatentsInvocation"] | components["schemas"]["BlendLatentsInvocation"] | components["schemas"]["ONNXPromptInvocation"] | components["schemas"]["ONNXTextToLatentsInvocation"] | components["schemas"]["ONNXLatentsToImageInvocation"] | components["schemas"]["OnnxModelLoaderInvocation"] | components["schemas"]["ShowImageInvocation"] | components["schemas"]["BlankImageInvocation"] | components["schemas"]["ImageCropInvocation"] | components["schemas"]["ImagePasteInvocation"] | components["schemas"]["MaskFromAlphaInvocation"] | components["schemas"]["ImageMultiplyInvocation"] | components["schemas"]["ImageChannelInvocation"] | components["schemas"]["ImageConvertInvocation"] | components["schemas"]["ImageBlurInvocation"] | components["schemas"]["ImageResizeInvocation"] | components["schemas"]["ImageScaleInvocation"] | components["schemas"]["ImageLerpInvocation"] | components["schemas"]["ImageInverseLerpInvocation"] | components["schemas"]["ImageNSFWBlurInvocation"] | components["schemas"]["ImageWatermarkInvocation"] | components["schemas"]["MaskEdgeInvocation"] | components["schemas"]["MaskCombineInvocation"] | components["schemas"]["ColorCorrectInvocation"] | components["schemas"]["ImageHueAdjustmentInvocation"] | components["schemas"]["ImageChannelOffsetInvocation"] | components["schemas"]["ImageChannelMultiplyInvocation"] | components["schemas"]["DynamicPromptInvocation"] | components["schemas"]["PromptsFromFileInvocation"] | components["schemas"]["CvInpaintInvocation"] | components["schemas"]["FloatLinearRangeInvocation"] | components["schemas"]["StepParamEasingInvocation"] | components["schemas"]["AddInvocation"] | components["schemas"]["SubtractInvocation"] | components["schemas"]["MultiplyInvocation"] | components["schemas"]["DivideInvocation"] | components["schemas"]["RandomIntInvocation"] | components["schemas"]["NoiseInvocation"] | components["schemas"]["RangeInvocation"] | components["schemas"]["RangeOfSizeInvocation"] | components["schemas"]["RandomRangeInvocation"] | components["schemas"]["ESRGANInvocation"] | components["schemas"]["InfillColorInvocation"] | components["schemas"]["InfillTileInvocation"] | components["schemas"]["InfillPatchMatchInvocation"] | components["schemas"]["LaMaInfillInvocation"] | components["schemas"]["GraphInvocation"] | components["schemas"]["IterateInvocation"] | components["schemas"]["CollectInvocation"] | components["schemas"]["CannyImageProcessorInvocation"] | components["schemas"]["HedImageProcessorInvocation"] | components["schemas"]["LineartImageProcessorInvocation"] | components["schemas"]["LineartAnimeImageProcessorInvocation"] | components["schemas"]["OpenposeImageProcessorInvocation"] | components["schemas"]["MidasDepthImageProcessorInvocation"] | components["schemas"]["NormalbaeImageProcessorInvocation"] | components["schemas"]["MlsdImageProcessorInvocation"] | components["schemas"]["PidiImageProcessorInvocation"] | components["schemas"]["ContentShuffleImageProcessorInvocation"] | components["schemas"]["ZoeDepthImageProcessorInvocation"] | components["schemas"]["MediapipeFaceProcessorInvocation"] | components["schemas"]["LeresImageProcessorInvocation"] | components["schemas"]["TileResamplerProcessorInvocation"] | components["schemas"]["SegmentAnythingProcessorInvocation"]; }; /** * Edges @@ -2480,6 +2480,102 @@ export type components = { */ type: "img_chan"; }; + /** + * Multiply Image Channel + * @description Scale a specific color channel of an image. + */ + ImageChannelMultiplyInvocation: { + /** + * 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; + /** + * Workflow + * @description The workflow to save with the image + */ + workflow?: string; + /** + * Image + * @description The image to adjust + */ + image?: components["schemas"]["ImageField"]; + /** + * Channel + * @description Which channel to adjust + * @enum {string} + */ + channel?: "Red (RGBA)" | "Green (RGBA)" | "Blue (RGBA)" | "Alpha (RGBA)" | "Cyan (CMYK)" | "Magenta (CMYK)" | "Yellow (CMYK)" | "Black (CMYK)" | "Hue (HSV)" | "Saturation (HSV)" | "Value (HSV)" | "Luminosity (LAB)" | "A (LAB)" | "B (LAB)" | "Y (YCbCr)" | "Cb (YCbCr)" | "Cr (YCbCr)"; + /** + * Scale + * @description The amount to scale the channel by. + * @default 1 + */ + scale?: number; + /** + * Invert Channel + * @description Invert the channel after scaling + * @default false + */ + invert_channel?: boolean; + /** + * Type + * @default img_channel_multiply + * @enum {string} + */ + type: "img_channel_multiply"; + }; + /** + * Offset Image Channel + * @description Add or subtract a value from a specific color channel of an image. + */ + ImageChannelOffsetInvocation: { + /** + * 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; + /** + * Workflow + * @description The workflow to save with the image + */ + workflow?: string; + /** + * Image + * @description The image to adjust + */ + image?: components["schemas"]["ImageField"]; + /** + * Channel + * @description Which channel to adjust + * @enum {string} + */ + channel?: "Red (RGBA)" | "Green (RGBA)" | "Blue (RGBA)" | "Alpha (RGBA)" | "Cyan (CMYK)" | "Magenta (CMYK)" | "Yellow (CMYK)" | "Black (CMYK)" | "Hue (HSV)" | "Saturation (HSV)" | "Value (HSV)" | "Luminosity (LAB)" | "A (LAB)" | "B (LAB)" | "Y (YCbCr)" | "Cb (YCbCr)" | "Cr (YCbCr)"; + /** + * Offset + * @description The amount to adjust the channel by + * @default 0 + */ + offset?: number; + /** + * Type + * @default img_channel_offset + * @enum {string} + */ + type: "img_channel_offset"; + }; /** * Image Collection Primitive * @description A collection of image primitive values @@ -2875,45 +2971,6 @@ export type components = { */ type: "img_lerp"; }; - /** - * Adjust Image Luminosity - * @description Adjusts the Luminosity (Value) of an image. - */ - ImageLuminosityAdjustmentInvocation: { - /** - * 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; - /** - * Workflow - * @description The workflow to save with the image - */ - workflow?: string; - /** - * Image - * @description The image to adjust - */ - image?: components["schemas"]["ImageField"]; - /** - * Luminosity - * @description The factor by which to adjust the luminosity (value) - * @default 1 - */ - luminosity?: number; - /** - * Type - * @default img_luminosity_adjust - * @enum {string} - */ - type: "img_luminosity_adjust"; - }; /** * ImageMetadata * @description An image's generation metadata @@ -3207,45 +3264,6 @@ export type components = { */ type: "img_resize"; }; - /** - * Adjust Image Saturation - * @description Adjusts the Saturation of an image. - */ - ImageSaturationAdjustmentInvocation: { - /** - * 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; - /** - * Workflow - * @description The workflow to save with the image - */ - workflow?: string; - /** - * Image - * @description The image to adjust - */ - image?: components["schemas"]["ImageField"]; - /** - * Saturation - * @description The factor by which to adjust the saturation - * @default 1 - */ - saturation?: number; - /** - * Type - * @default img_saturation_adjust - * @enum {string} - */ - type: "img_saturation_adjust"; - }; /** * Scale Image * @description Scales an image by a factor @@ -7041,6 +7059,12 @@ export type components = { /** Ui Order */ ui_order?: number; }; + /** + * StableDiffusionOnnxModelFormat + * @description An enumeration. + * @enum {string} + */ + StableDiffusionOnnxModelFormat: "olive" | "onnx"; /** * StableDiffusion1ModelFormat * @description An enumeration. @@ -7065,12 +7089,6 @@ export type components = { * @enum {string} */ ControlNetModelFormat: "checkpoint" | "diffusers"; - /** - * StableDiffusionOnnxModelFormat - * @description An enumeration. - * @enum {string} - */ - StableDiffusionOnnxModelFormat: "olive" | "onnx"; }; responses: never; parameters: never; @@ -7187,7 +7205,7 @@ export type operations = { }; requestBody: { content: { - "application/json": components["schemas"]["BooleanInvocation"] | components["schemas"]["BooleanCollectionInvocation"] | components["schemas"]["IntegerInvocation"] | components["schemas"]["IntegerCollectionInvocation"] | components["schemas"]["FloatInvocation"] | components["schemas"]["FloatCollectionInvocation"] | components["schemas"]["StringInvocation"] | components["schemas"]["StringCollectionInvocation"] | components["schemas"]["ImageInvocation"] | components["schemas"]["ImageCollectionInvocation"] | components["schemas"]["LatentsInvocation"] | components["schemas"]["LatentsCollectionInvocation"] | components["schemas"]["ColorInvocation"] | components["schemas"]["ConditioningInvocation"] | components["schemas"]["ConditioningCollectionInvocation"] | components["schemas"]["ControlNetInvocation"] | components["schemas"]["ImageProcessorInvocation"] | components["schemas"]["MainModelLoaderInvocation"] | components["schemas"]["LoraLoaderInvocation"] | components["schemas"]["SDXLLoraLoaderInvocation"] | components["schemas"]["VaeLoaderInvocation"] | components["schemas"]["SeamlessModeInvocation"] | components["schemas"]["MetadataAccumulatorInvocation"] | components["schemas"]["SDXLModelLoaderInvocation"] | components["schemas"]["SDXLRefinerModelLoaderInvocation"] | components["schemas"]["CompelInvocation"] | components["schemas"]["SDXLCompelPromptInvocation"] | components["schemas"]["SDXLRefinerCompelPromptInvocation"] | components["schemas"]["ClipSkipInvocation"] | components["schemas"]["SchedulerInvocation"] | components["schemas"]["CreateDenoiseMaskInvocation"] | components["schemas"]["DenoiseLatentsInvocation"] | components["schemas"]["LatentsToImageInvocation"] | components["schemas"]["ResizeLatentsInvocation"] | components["schemas"]["ScaleLatentsInvocation"] | components["schemas"]["ImageToLatentsInvocation"] | components["schemas"]["BlendLatentsInvocation"] | components["schemas"]["ONNXPromptInvocation"] | components["schemas"]["ONNXTextToLatentsInvocation"] | components["schemas"]["ONNXLatentsToImageInvocation"] | components["schemas"]["OnnxModelLoaderInvocation"] | components["schemas"]["ShowImageInvocation"] | components["schemas"]["BlankImageInvocation"] | components["schemas"]["ImageCropInvocation"] | components["schemas"]["ImagePasteInvocation"] | components["schemas"]["MaskFromAlphaInvocation"] | components["schemas"]["ImageMultiplyInvocation"] | components["schemas"]["ImageChannelInvocation"] | components["schemas"]["ImageConvertInvocation"] | components["schemas"]["ImageBlurInvocation"] | components["schemas"]["ImageResizeInvocation"] | components["schemas"]["ImageScaleInvocation"] | components["schemas"]["ImageLerpInvocation"] | components["schemas"]["ImageInverseLerpInvocation"] | components["schemas"]["ImageNSFWBlurInvocation"] | components["schemas"]["ImageWatermarkInvocation"] | components["schemas"]["MaskEdgeInvocation"] | components["schemas"]["MaskCombineInvocation"] | components["schemas"]["ColorCorrectInvocation"] | components["schemas"]["ImageHueAdjustmentInvocation"] | components["schemas"]["ImageLuminosityAdjustmentInvocation"] | components["schemas"]["ImageSaturationAdjustmentInvocation"] | components["schemas"]["DynamicPromptInvocation"] | components["schemas"]["PromptsFromFileInvocation"] | components["schemas"]["CvInpaintInvocation"] | components["schemas"]["FloatLinearRangeInvocation"] | components["schemas"]["StepParamEasingInvocation"] | components["schemas"]["AddInvocation"] | components["schemas"]["SubtractInvocation"] | components["schemas"]["MultiplyInvocation"] | components["schemas"]["DivideInvocation"] | components["schemas"]["RandomIntInvocation"] | components["schemas"]["NoiseInvocation"] | components["schemas"]["RangeInvocation"] | components["schemas"]["RangeOfSizeInvocation"] | components["schemas"]["RandomRangeInvocation"] | components["schemas"]["ESRGANInvocation"] | components["schemas"]["InfillColorInvocation"] | components["schemas"]["InfillTileInvocation"] | components["schemas"]["InfillPatchMatchInvocation"] | components["schemas"]["LaMaInfillInvocation"] | components["schemas"]["GraphInvocation"] | components["schemas"]["IterateInvocation"] | components["schemas"]["CollectInvocation"] | components["schemas"]["CannyImageProcessorInvocation"] | components["schemas"]["HedImageProcessorInvocation"] | components["schemas"]["LineartImageProcessorInvocation"] | components["schemas"]["LineartAnimeImageProcessorInvocation"] | components["schemas"]["OpenposeImageProcessorInvocation"] | components["schemas"]["MidasDepthImageProcessorInvocation"] | components["schemas"]["NormalbaeImageProcessorInvocation"] | components["schemas"]["MlsdImageProcessorInvocation"] | components["schemas"]["PidiImageProcessorInvocation"] | components["schemas"]["ContentShuffleImageProcessorInvocation"] | components["schemas"]["ZoeDepthImageProcessorInvocation"] | components["schemas"]["MediapipeFaceProcessorInvocation"] | components["schemas"]["LeresImageProcessorInvocation"] | components["schemas"]["TileResamplerProcessorInvocation"] | components["schemas"]["SegmentAnythingProcessorInvocation"]; + "application/json": components["schemas"]["BooleanInvocation"] | components["schemas"]["BooleanCollectionInvocation"] | components["schemas"]["IntegerInvocation"] | components["schemas"]["IntegerCollectionInvocation"] | components["schemas"]["FloatInvocation"] | components["schemas"]["FloatCollectionInvocation"] | components["schemas"]["StringInvocation"] | components["schemas"]["StringCollectionInvocation"] | components["schemas"]["ImageInvocation"] | components["schemas"]["ImageCollectionInvocation"] | components["schemas"]["LatentsInvocation"] | components["schemas"]["LatentsCollectionInvocation"] | components["schemas"]["ColorInvocation"] | components["schemas"]["ConditioningInvocation"] | components["schemas"]["ConditioningCollectionInvocation"] | components["schemas"]["ControlNetInvocation"] | components["schemas"]["ImageProcessorInvocation"] | components["schemas"]["MainModelLoaderInvocation"] | components["schemas"]["LoraLoaderInvocation"] | components["schemas"]["SDXLLoraLoaderInvocation"] | components["schemas"]["VaeLoaderInvocation"] | components["schemas"]["SeamlessModeInvocation"] | components["schemas"]["MetadataAccumulatorInvocation"] | components["schemas"]["SDXLModelLoaderInvocation"] | components["schemas"]["SDXLRefinerModelLoaderInvocation"] | components["schemas"]["CompelInvocation"] | components["schemas"]["SDXLCompelPromptInvocation"] | components["schemas"]["SDXLRefinerCompelPromptInvocation"] | components["schemas"]["ClipSkipInvocation"] | components["schemas"]["SchedulerInvocation"] | components["schemas"]["CreateDenoiseMaskInvocation"] | components["schemas"]["DenoiseLatentsInvocation"] | components["schemas"]["LatentsToImageInvocation"] | components["schemas"]["ResizeLatentsInvocation"] | components["schemas"]["ScaleLatentsInvocation"] | components["schemas"]["ImageToLatentsInvocation"] | components["schemas"]["BlendLatentsInvocation"] | components["schemas"]["ONNXPromptInvocation"] | components["schemas"]["ONNXTextToLatentsInvocation"] | components["schemas"]["ONNXLatentsToImageInvocation"] | components["schemas"]["OnnxModelLoaderInvocation"] | components["schemas"]["ShowImageInvocation"] | components["schemas"]["BlankImageInvocation"] | components["schemas"]["ImageCropInvocation"] | components["schemas"]["ImagePasteInvocation"] | components["schemas"]["MaskFromAlphaInvocation"] | components["schemas"]["ImageMultiplyInvocation"] | components["schemas"]["ImageChannelInvocation"] | components["schemas"]["ImageConvertInvocation"] | components["schemas"]["ImageBlurInvocation"] | components["schemas"]["ImageResizeInvocation"] | components["schemas"]["ImageScaleInvocation"] | components["schemas"]["ImageLerpInvocation"] | components["schemas"]["ImageInverseLerpInvocation"] | components["schemas"]["ImageNSFWBlurInvocation"] | components["schemas"]["ImageWatermarkInvocation"] | components["schemas"]["MaskEdgeInvocation"] | components["schemas"]["MaskCombineInvocation"] | components["schemas"]["ColorCorrectInvocation"] | components["schemas"]["ImageHueAdjustmentInvocation"] | components["schemas"]["ImageChannelOffsetInvocation"] | components["schemas"]["ImageChannelMultiplyInvocation"] | components["schemas"]["DynamicPromptInvocation"] | components["schemas"]["PromptsFromFileInvocation"] | components["schemas"]["CvInpaintInvocation"] | components["schemas"]["FloatLinearRangeInvocation"] | components["schemas"]["StepParamEasingInvocation"] | components["schemas"]["AddInvocation"] | components["schemas"]["SubtractInvocation"] | components["schemas"]["MultiplyInvocation"] | components["schemas"]["DivideInvocation"] | components["schemas"]["RandomIntInvocation"] | components["schemas"]["NoiseInvocation"] | components["schemas"]["RangeInvocation"] | components["schemas"]["RangeOfSizeInvocation"] | components["schemas"]["RandomRangeInvocation"] | components["schemas"]["ESRGANInvocation"] | components["schemas"]["InfillColorInvocation"] | components["schemas"]["InfillTileInvocation"] | components["schemas"]["InfillPatchMatchInvocation"] | components["schemas"]["LaMaInfillInvocation"] | components["schemas"]["GraphInvocation"] | components["schemas"]["IterateInvocation"] | components["schemas"]["CollectInvocation"] | components["schemas"]["CannyImageProcessorInvocation"] | components["schemas"]["HedImageProcessorInvocation"] | components["schemas"]["LineartImageProcessorInvocation"] | components["schemas"]["LineartAnimeImageProcessorInvocation"] | components["schemas"]["OpenposeImageProcessorInvocation"] | components["schemas"]["MidasDepthImageProcessorInvocation"] | components["schemas"]["NormalbaeImageProcessorInvocation"] | components["schemas"]["MlsdImageProcessorInvocation"] | components["schemas"]["PidiImageProcessorInvocation"] | components["schemas"]["ContentShuffleImageProcessorInvocation"] | components["schemas"]["ZoeDepthImageProcessorInvocation"] | components["schemas"]["MediapipeFaceProcessorInvocation"] | components["schemas"]["LeresImageProcessorInvocation"] | components["schemas"]["TileResamplerProcessorInvocation"] | components["schemas"]["SegmentAnythingProcessorInvocation"]; }; }; responses: { @@ -7228,7 +7246,7 @@ export type operations = { }; requestBody: { content: { - "application/json": components["schemas"]["BooleanInvocation"] | components["schemas"]["BooleanCollectionInvocation"] | components["schemas"]["IntegerInvocation"] | components["schemas"]["IntegerCollectionInvocation"] | components["schemas"]["FloatInvocation"] | components["schemas"]["FloatCollectionInvocation"] | components["schemas"]["StringInvocation"] | components["schemas"]["StringCollectionInvocation"] | components["schemas"]["ImageInvocation"] | components["schemas"]["ImageCollectionInvocation"] | components["schemas"]["LatentsInvocation"] | components["schemas"]["LatentsCollectionInvocation"] | components["schemas"]["ColorInvocation"] | components["schemas"]["ConditioningInvocation"] | components["schemas"]["ConditioningCollectionInvocation"] | components["schemas"]["ControlNetInvocation"] | components["schemas"]["ImageProcessorInvocation"] | components["schemas"]["MainModelLoaderInvocation"] | components["schemas"]["LoraLoaderInvocation"] | components["schemas"]["SDXLLoraLoaderInvocation"] | components["schemas"]["VaeLoaderInvocation"] | components["schemas"]["SeamlessModeInvocation"] | components["schemas"]["MetadataAccumulatorInvocation"] | components["schemas"]["SDXLModelLoaderInvocation"] | components["schemas"]["SDXLRefinerModelLoaderInvocation"] | components["schemas"]["CompelInvocation"] | components["schemas"]["SDXLCompelPromptInvocation"] | components["schemas"]["SDXLRefinerCompelPromptInvocation"] | components["schemas"]["ClipSkipInvocation"] | components["schemas"]["SchedulerInvocation"] | components["schemas"]["CreateDenoiseMaskInvocation"] | components["schemas"]["DenoiseLatentsInvocation"] | components["schemas"]["LatentsToImageInvocation"] | components["schemas"]["ResizeLatentsInvocation"] | components["schemas"]["ScaleLatentsInvocation"] | components["schemas"]["ImageToLatentsInvocation"] | components["schemas"]["BlendLatentsInvocation"] | components["schemas"]["ONNXPromptInvocation"] | components["schemas"]["ONNXTextToLatentsInvocation"] | components["schemas"]["ONNXLatentsToImageInvocation"] | components["schemas"]["OnnxModelLoaderInvocation"] | components["schemas"]["ShowImageInvocation"] | components["schemas"]["BlankImageInvocation"] | components["schemas"]["ImageCropInvocation"] | components["schemas"]["ImagePasteInvocation"] | components["schemas"]["MaskFromAlphaInvocation"] | components["schemas"]["ImageMultiplyInvocation"] | components["schemas"]["ImageChannelInvocation"] | components["schemas"]["ImageConvertInvocation"] | components["schemas"]["ImageBlurInvocation"] | components["schemas"]["ImageResizeInvocation"] | components["schemas"]["ImageScaleInvocation"] | components["schemas"]["ImageLerpInvocation"] | components["schemas"]["ImageInverseLerpInvocation"] | components["schemas"]["ImageNSFWBlurInvocation"] | components["schemas"]["ImageWatermarkInvocation"] | components["schemas"]["MaskEdgeInvocation"] | components["schemas"]["MaskCombineInvocation"] | components["schemas"]["ColorCorrectInvocation"] | components["schemas"]["ImageHueAdjustmentInvocation"] | components["schemas"]["ImageLuminosityAdjustmentInvocation"] | components["schemas"]["ImageSaturationAdjustmentInvocation"] | components["schemas"]["DynamicPromptInvocation"] | components["schemas"]["PromptsFromFileInvocation"] | components["schemas"]["CvInpaintInvocation"] | components["schemas"]["FloatLinearRangeInvocation"] | components["schemas"]["StepParamEasingInvocation"] | components["schemas"]["AddInvocation"] | components["schemas"]["SubtractInvocation"] | components["schemas"]["MultiplyInvocation"] | components["schemas"]["DivideInvocation"] | components["schemas"]["RandomIntInvocation"] | components["schemas"]["NoiseInvocation"] | components["schemas"]["RangeInvocation"] | components["schemas"]["RangeOfSizeInvocation"] | components["schemas"]["RandomRangeInvocation"] | components["schemas"]["ESRGANInvocation"] | components["schemas"]["InfillColorInvocation"] | components["schemas"]["InfillTileInvocation"] | components["schemas"]["InfillPatchMatchInvocation"] | components["schemas"]["LaMaInfillInvocation"] | components["schemas"]["GraphInvocation"] | components["schemas"]["IterateInvocation"] | components["schemas"]["CollectInvocation"] | components["schemas"]["CannyImageProcessorInvocation"] | components["schemas"]["HedImageProcessorInvocation"] | components["schemas"]["LineartImageProcessorInvocation"] | components["schemas"]["LineartAnimeImageProcessorInvocation"] | components["schemas"]["OpenposeImageProcessorInvocation"] | components["schemas"]["MidasDepthImageProcessorInvocation"] | components["schemas"]["NormalbaeImageProcessorInvocation"] | components["schemas"]["MlsdImageProcessorInvocation"] | components["schemas"]["PidiImageProcessorInvocation"] | components["schemas"]["ContentShuffleImageProcessorInvocation"] | components["schemas"]["ZoeDepthImageProcessorInvocation"] | components["schemas"]["MediapipeFaceProcessorInvocation"] | components["schemas"]["LeresImageProcessorInvocation"] | components["schemas"]["TileResamplerProcessorInvocation"] | components["schemas"]["SegmentAnythingProcessorInvocation"]; + "application/json": components["schemas"]["BooleanInvocation"] | components["schemas"]["BooleanCollectionInvocation"] | components["schemas"]["IntegerInvocation"] | components["schemas"]["IntegerCollectionInvocation"] | components["schemas"]["FloatInvocation"] | components["schemas"]["FloatCollectionInvocation"] | components["schemas"]["StringInvocation"] | components["schemas"]["StringCollectionInvocation"] | components["schemas"]["ImageInvocation"] | components["schemas"]["ImageCollectionInvocation"] | components["schemas"]["LatentsInvocation"] | components["schemas"]["LatentsCollectionInvocation"] | components["schemas"]["ColorInvocation"] | components["schemas"]["ConditioningInvocation"] | components["schemas"]["ConditioningCollectionInvocation"] | components["schemas"]["ControlNetInvocation"] | components["schemas"]["ImageProcessorInvocation"] | components["schemas"]["MainModelLoaderInvocation"] | components["schemas"]["LoraLoaderInvocation"] | components["schemas"]["SDXLLoraLoaderInvocation"] | components["schemas"]["VaeLoaderInvocation"] | components["schemas"]["SeamlessModeInvocation"] | components["schemas"]["MetadataAccumulatorInvocation"] | components["schemas"]["SDXLModelLoaderInvocation"] | components["schemas"]["SDXLRefinerModelLoaderInvocation"] | components["schemas"]["CompelInvocation"] | components["schemas"]["SDXLCompelPromptInvocation"] | components["schemas"]["SDXLRefinerCompelPromptInvocation"] | components["schemas"]["ClipSkipInvocation"] | components["schemas"]["SchedulerInvocation"] | components["schemas"]["CreateDenoiseMaskInvocation"] | components["schemas"]["DenoiseLatentsInvocation"] | components["schemas"]["LatentsToImageInvocation"] | components["schemas"]["ResizeLatentsInvocation"] | components["schemas"]["ScaleLatentsInvocation"] | components["schemas"]["ImageToLatentsInvocation"] | components["schemas"]["BlendLatentsInvocation"] | components["schemas"]["ONNXPromptInvocation"] | components["schemas"]["ONNXTextToLatentsInvocation"] | components["schemas"]["ONNXLatentsToImageInvocation"] | components["schemas"]["OnnxModelLoaderInvocation"] | components["schemas"]["ShowImageInvocation"] | components["schemas"]["BlankImageInvocation"] | components["schemas"]["ImageCropInvocation"] | components["schemas"]["ImagePasteInvocation"] | components["schemas"]["MaskFromAlphaInvocation"] | components["schemas"]["ImageMultiplyInvocation"] | components["schemas"]["ImageChannelInvocation"] | components["schemas"]["ImageConvertInvocation"] | components["schemas"]["ImageBlurInvocation"] | components["schemas"]["ImageResizeInvocation"] | components["schemas"]["ImageScaleInvocation"] | components["schemas"]["ImageLerpInvocation"] | components["schemas"]["ImageInverseLerpInvocation"] | components["schemas"]["ImageNSFWBlurInvocation"] | components["schemas"]["ImageWatermarkInvocation"] | components["schemas"]["MaskEdgeInvocation"] | components["schemas"]["MaskCombineInvocation"] | components["schemas"]["ColorCorrectInvocation"] | components["schemas"]["ImageHueAdjustmentInvocation"] | components["schemas"]["ImageChannelOffsetInvocation"] | components["schemas"]["ImageChannelMultiplyInvocation"] | components["schemas"]["DynamicPromptInvocation"] | components["schemas"]["PromptsFromFileInvocation"] | components["schemas"]["CvInpaintInvocation"] | components["schemas"]["FloatLinearRangeInvocation"] | components["schemas"]["StepParamEasingInvocation"] | components["schemas"]["AddInvocation"] | components["schemas"]["SubtractInvocation"] | components["schemas"]["MultiplyInvocation"] | components["schemas"]["DivideInvocation"] | components["schemas"]["RandomIntInvocation"] | components["schemas"]["NoiseInvocation"] | components["schemas"]["RangeInvocation"] | components["schemas"]["RangeOfSizeInvocation"] | components["schemas"]["RandomRangeInvocation"] | components["schemas"]["ESRGANInvocation"] | components["schemas"]["InfillColorInvocation"] | components["schemas"]["InfillTileInvocation"] | components["schemas"]["InfillPatchMatchInvocation"] | components["schemas"]["LaMaInfillInvocation"] | components["schemas"]["GraphInvocation"] | components["schemas"]["IterateInvocation"] | components["schemas"]["CollectInvocation"] | components["schemas"]["CannyImageProcessorInvocation"] | components["schemas"]["HedImageProcessorInvocation"] | components["schemas"]["LineartImageProcessorInvocation"] | components["schemas"]["LineartAnimeImageProcessorInvocation"] | components["schemas"]["OpenposeImageProcessorInvocation"] | components["schemas"]["MidasDepthImageProcessorInvocation"] | components["schemas"]["NormalbaeImageProcessorInvocation"] | components["schemas"]["MlsdImageProcessorInvocation"] | components["schemas"]["PidiImageProcessorInvocation"] | components["schemas"]["ContentShuffleImageProcessorInvocation"] | components["schemas"]["ZoeDepthImageProcessorInvocation"] | components["schemas"]["MediapipeFaceProcessorInvocation"] | components["schemas"]["LeresImageProcessorInvocation"] | components["schemas"]["TileResamplerProcessorInvocation"] | components["schemas"]["SegmentAnythingProcessorInvocation"]; }; }; responses: { From 94115b52175a17b8f5f7469cb43909288e6fcda8 Mon Sep 17 00:00:00 2001 From: psychedelicious <4822129+psychedelicious@users.noreply.github.com> Date: Tue, 5 Sep 2023 11:23:13 +1000 Subject: [PATCH 21/26] fix(nodes): downscale and resample_mode are not optional --- invokeai/app/invocations/infill.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/invokeai/app/invocations/infill.py b/invokeai/app/invocations/infill.py index 0971f6cce9..98e8a7590c 100644 --- a/invokeai/app/invocations/infill.py +++ b/invokeai/app/invocations/infill.py @@ -196,10 +196,8 @@ class InfillPatchMatchInvocation(BaseInvocation): """Infills transparent areas of an image using the PatchMatch algorithm""" image: ImageField = InputField(description="The image to infill") - downscale: Optional[float] = InputField( - default=2.0, gt=0, description="Run patchmatch on downscaled image to speedup infill" - ) - resample_mode: Optional[PIL_RESAMPLING_MODES] = InputField(default="bicubic", description="The resampling mode") + downscale: float = InputField(default=2.0, gt=0, description="Run patchmatch on downscaled image to speedup infill") + resample_mode: PIL_RESAMPLING_MODES = InputField(default="bicubic", description="The resampling mode") def invoke(self, context: InvocationContext) -> ImageOutput: image = context.services.images.get_pil_image(self.image.image_name).convert("RGBA") From 2ab75bc52e4b405485164104b7b2edc7e3231fc0 Mon Sep 17 00:00:00 2001 From: psychedelicious <4822129+psychedelicious@users.noreply.github.com> Date: Tue, 5 Sep 2023 11:51:46 +1000 Subject: [PATCH 22/26] feat(ui): move fp32 check to its own variable remove a ton of extraneous checks that are easy to miss during maintenance --- .../nodes/util/graphBuilders/addSDXLRefinerToGraph.ts | 4 +++- .../util/graphBuilders/buildCanvasImageToImageGraph.ts | 6 ++++-- .../util/graphBuilders/buildCanvasInpaintGraph.ts | 10 ++++++---- .../util/graphBuilders/buildCanvasOutpaintGraph.ts | 10 ++++++---- .../graphBuilders/buildCanvasSDXLImageToImageGraph.ts | 8 +++++--- .../util/graphBuilders/buildCanvasSDXLInpaintGraph.ts | 10 ++++++---- .../util/graphBuilders/buildCanvasSDXLOutpaintGraph.ts | 10 ++++++---- .../graphBuilders/buildCanvasSDXLTextToImageGraph.ts | 6 ++++-- .../util/graphBuilders/buildCanvasTextToImageGraph.ts | 6 ++++-- .../util/graphBuilders/buildLinearImageToImageGraph.ts | 6 ++++-- .../graphBuilders/buildLinearSDXLImageToImageGraph.ts | 6 ++++-- .../graphBuilders/buildLinearSDXLTextToImageGraph.ts | 4 +++- .../util/graphBuilders/buildLinearTextToImageGraph.ts | 4 +++- 13 files changed, 58 insertions(+), 32 deletions(-) diff --git a/invokeai/frontend/web/src/features/nodes/util/graphBuilders/addSDXLRefinerToGraph.ts b/invokeai/frontend/web/src/features/nodes/util/graphBuilders/addSDXLRefinerToGraph.ts index acee1d5e35..0daca1f310 100644 --- a/invokeai/frontend/web/src/features/nodes/util/graphBuilders/addSDXLRefinerToGraph.ts +++ b/invokeai/frontend/web/src/features/nodes/util/graphBuilders/addSDXLRefinerToGraph.ts @@ -47,6 +47,8 @@ export const addSDXLRefinerToGraph = ( const { seamlessXAxis, seamlessYAxis, vaePrecision } = state.generation; const { boundingBoxScaleMethod } = state.canvas; + const fp32 = vaePrecision === 'fp32'; + const isUsingScaledDimensions = ['auto', 'manual'].includes( boundingBoxScaleMethod ); @@ -232,7 +234,7 @@ export const addSDXLRefinerToGraph = ( type: 'create_denoise_mask', id: SDXL_REFINER_INPAINT_CREATE_MASK, is_intermediate: true, - fp32: vaePrecision === 'fp32' ? true : false, + fp32, }; if (isUsingScaledDimensions) { diff --git a/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasImageToImageGraph.ts b/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasImageToImageGraph.ts index 63a7eac56b..e750b40220 100644 --- a/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasImageToImageGraph.ts +++ b/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasImageToImageGraph.ts @@ -59,6 +59,8 @@ export const buildCanvasImageToImageGraph = ( shouldAutoSave, } = state.canvas; + const fp32 = vaePrecision === 'fp32'; + const isUsingScaledDimensions = ['auto', 'manual'].includes( boundingBoxScaleMethod ); @@ -245,7 +247,7 @@ export const buildCanvasImageToImageGraph = ( id: LATENTS_TO_IMAGE, type: 'l2i', is_intermediate: true, - fp32: vaePrecision === 'fp32' ? true : false, + fp32, }; graph.nodes[CANVAS_OUTPUT] = { id: CANVAS_OUTPUT, @@ -292,7 +294,7 @@ export const buildCanvasImageToImageGraph = ( type: 'l2i', id: CANVAS_OUTPUT, is_intermediate: !shouldAutoSave, - fp32: vaePrecision === 'fp32' ? true : false, + fp32, }; (graph.nodes[IMAGE_TO_LATENTS] as ImageToLatentsInvocation).image = diff --git a/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasInpaintGraph.ts b/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasInpaintGraph.ts index ea6ec17999..58a7726410 100644 --- a/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasInpaintGraph.ts +++ b/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasInpaintGraph.ts @@ -93,6 +93,8 @@ export const buildCanvasInpaintGraph = ( shouldAutoSave, } = state.canvas; + const fp32 = vaePrecision === 'fp32'; + const isUsingScaledDimensions = ['auto', 'manual'].includes( boundingBoxScaleMethod ); @@ -141,7 +143,7 @@ export const buildCanvasInpaintGraph = ( type: 'i2l', id: INPAINT_IMAGE, is_intermediate: true, - fp32: vaePrecision === 'fp32' ? true : false, + fp32, }, [NOISE]: { type: 'noise', @@ -153,7 +155,7 @@ export const buildCanvasInpaintGraph = ( type: 'create_denoise_mask', id: INPAINT_CREATE_MASK, is_intermediate: true, - fp32: vaePrecision === 'fp32' ? true : false, + fp32, }, [DENOISE_LATENTS]: { type: 'denoise_latents', @@ -191,7 +193,7 @@ export const buildCanvasInpaintGraph = ( type: 'l2i', id: LATENTS_TO_IMAGE, is_intermediate: true, - fp32: vaePrecision === 'fp32' ? true : false, + fp32, }, [CANVAS_OUTPUT]: { type: 'color_correct', @@ -596,7 +598,7 @@ export const buildCanvasInpaintGraph = ( type: 'create_denoise_mask', id: CANVAS_COHERENCE_INPAINT_CREATE_MASK, is_intermediate: true, - fp32: vaePrecision === 'fp32' ? true : false, + fp32, }; // Handle Image Input For Mask Creation diff --git a/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasOutpaintGraph.ts b/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasOutpaintGraph.ts index 60e606e6da..71d3492bdc 100644 --- a/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasOutpaintGraph.ts +++ b/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasOutpaintGraph.ts @@ -97,6 +97,8 @@ export const buildCanvasOutpaintGraph = ( shouldAutoSave, } = state.canvas; + const fp32 = vaePrecision === 'fp32'; + const isUsingScaledDimensions = ['auto', 'manual'].includes( boundingBoxScaleMethod ); @@ -150,7 +152,7 @@ export const buildCanvasOutpaintGraph = ( type: 'i2l', id: INPAINT_IMAGE, is_intermediate: true, - fp32: vaePrecision === 'fp32' ? true : false, + fp32, }, [NOISE]: { type: 'noise', @@ -162,7 +164,7 @@ export const buildCanvasOutpaintGraph = ( type: 'create_denoise_mask', id: INPAINT_CREATE_MASK, is_intermediate: true, - fp32: vaePrecision === 'fp32' ? true : false, + fp32, }, [DENOISE_LATENTS]: { type: 'denoise_latents', @@ -200,7 +202,7 @@ export const buildCanvasOutpaintGraph = ( type: 'l2i', id: LATENTS_TO_IMAGE, is_intermediate: true, - fp32: vaePrecision === 'fp32' ? true : false, + fp32, }, [CANVAS_OUTPUT]: { type: 'color_correct', @@ -698,7 +700,7 @@ export const buildCanvasOutpaintGraph = ( type: 'create_denoise_mask', id: CANVAS_COHERENCE_INPAINT_CREATE_MASK, is_intermediate: true, - fp32: vaePrecision === 'fp32' ? true : false, + fp32, }; // Handle Image Input For Mask Creation diff --git a/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasSDXLImageToImageGraph.ts b/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasSDXLImageToImageGraph.ts index 872a1d53bd..2a677a8775 100644 --- a/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasSDXLImageToImageGraph.ts +++ b/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasSDXLImageToImageGraph.ts @@ -67,6 +67,8 @@ export const buildCanvasSDXLImageToImageGraph = ( shouldAutoSave, } = state.canvas; + const fp32 = vaePrecision === 'fp32'; + const isUsingScaledDimensions = ['auto', 'manual'].includes( boundingBoxScaleMethod ); @@ -133,7 +135,7 @@ export const buildCanvasSDXLImageToImageGraph = ( type: 'i2l', id: IMAGE_TO_LATENTS, is_intermediate: true, - fp32: vaePrecision === 'fp32' ? true : false, + fp32, }, [SDXL_DENOISE_LATENTS]: { type: 'denoise_latents', @@ -258,7 +260,7 @@ export const buildCanvasSDXLImageToImageGraph = ( id: LATENTS_TO_IMAGE, type: 'l2i', is_intermediate: true, - fp32: vaePrecision === 'fp32' ? true : false, + fp32, }; graph.nodes[CANVAS_OUTPUT] = { id: CANVAS_OUTPUT, @@ -305,7 +307,7 @@ export const buildCanvasSDXLImageToImageGraph = ( type: 'l2i', id: CANVAS_OUTPUT, is_intermediate: !shouldAutoSave, - fp32: vaePrecision === 'fp32' ? true : false, + fp32, }; (graph.nodes[IMAGE_TO_LATENTS] as ImageToLatentsInvocation).image = diff --git a/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasSDXLInpaintGraph.ts b/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasSDXLInpaintGraph.ts index f26a34a2b7..baa1c0155f 100644 --- a/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasSDXLInpaintGraph.ts +++ b/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasSDXLInpaintGraph.ts @@ -100,6 +100,8 @@ export const buildCanvasSDXLInpaintGraph = ( shouldAutoSave, } = state.canvas; + const fp32 = vaePrecision === 'fp32'; + const isUsingScaledDimensions = ['auto', 'manual'].includes( boundingBoxScaleMethod ); @@ -145,7 +147,7 @@ export const buildCanvasSDXLInpaintGraph = ( type: 'i2l', id: INPAINT_IMAGE, is_intermediate: true, - fp32: vaePrecision === 'fp32' ? true : false, + fp32, }, [NOISE]: { type: 'noise', @@ -157,7 +159,7 @@ export const buildCanvasSDXLInpaintGraph = ( type: 'create_denoise_mask', id: INPAINT_CREATE_MASK, is_intermediate: true, - fp32: vaePrecision === 'fp32' ? true : false, + fp32, }, [SDXL_DENOISE_LATENTS]: { type: 'denoise_latents', @@ -197,7 +199,7 @@ export const buildCanvasSDXLInpaintGraph = ( type: 'l2i', id: LATENTS_TO_IMAGE, is_intermediate: true, - fp32: vaePrecision === 'fp32' ? true : false, + fp32, }, [CANVAS_OUTPUT]: { type: 'color_correct', @@ -611,7 +613,7 @@ export const buildCanvasSDXLInpaintGraph = ( type: 'create_denoise_mask', id: CANVAS_COHERENCE_INPAINT_CREATE_MASK, is_intermediate: true, - fp32: vaePrecision === 'fp32' ? true : false, + fp32, }; // Handle Image Input For Mask Creation diff --git a/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasSDXLOutpaintGraph.ts b/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasSDXLOutpaintGraph.ts index da796f8a87..3f8fffb70a 100644 --- a/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasSDXLOutpaintGraph.ts +++ b/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasSDXLOutpaintGraph.ts @@ -104,6 +104,8 @@ export const buildCanvasSDXLOutpaintGraph = ( shouldAutoSave, } = state.canvas; + const fp32 = vaePrecision === 'fp32'; + const isUsingScaledDimensions = ['auto', 'manual'].includes( boundingBoxScaleMethod ); @@ -154,7 +156,7 @@ export const buildCanvasSDXLOutpaintGraph = ( type: 'i2l', id: INPAINT_IMAGE, is_intermediate: true, - fp32: vaePrecision === 'fp32' ? true : false, + fp32, }, [NOISE]: { type: 'noise', @@ -166,7 +168,7 @@ export const buildCanvasSDXLOutpaintGraph = ( type: 'create_denoise_mask', id: INPAINT_CREATE_MASK, is_intermediate: true, - fp32: vaePrecision === 'fp32' ? true : false, + fp32, }, [SDXL_DENOISE_LATENTS]: { type: 'denoise_latents', @@ -206,7 +208,7 @@ export const buildCanvasSDXLOutpaintGraph = ( type: 'l2i', id: LATENTS_TO_IMAGE, is_intermediate: true, - fp32: vaePrecision === 'fp32' ? true : false, + fp32, }, [CANVAS_OUTPUT]: { type: 'color_correct', @@ -714,7 +716,7 @@ export const buildCanvasSDXLOutpaintGraph = ( type: 'create_denoise_mask', id: CANVAS_COHERENCE_INPAINT_CREATE_MASK, is_intermediate: true, - fp32: vaePrecision === 'fp32' ? true : false, + fp32, }; // Handle Image Input For Mask Creation diff --git a/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasSDXLTextToImageGraph.ts b/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasSDXLTextToImageGraph.ts index 10bde11de9..6d787987ef 100644 --- a/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasSDXLTextToImageGraph.ts +++ b/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasSDXLTextToImageGraph.ts @@ -61,6 +61,8 @@ export const buildCanvasSDXLTextToImageGraph = ( shouldAutoSave, } = state.canvas; + const fp32 = vaePrecision === 'fp32'; + const isUsingScaledDimensions = ['auto', 'manual'].includes( boundingBoxScaleMethod ); @@ -252,7 +254,7 @@ export const buildCanvasSDXLTextToImageGraph = ( id: LATENTS_TO_IMAGE, type: isUsingOnnxModel ? 'l2i_onnx' : 'l2i', is_intermediate: true, - fp32: vaePrecision === 'fp32' ? true : false, + fp32, }; graph.nodes[CANVAS_OUTPUT] = { @@ -290,7 +292,7 @@ export const buildCanvasSDXLTextToImageGraph = ( type: isUsingOnnxModel ? 'l2i_onnx' : 'l2i', id: CANVAS_OUTPUT, is_intermediate: !shouldAutoSave, - fp32: vaePrecision === 'fp32' ? true : false, + fp32, }; graph.edges.push({ diff --git a/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasTextToImageGraph.ts b/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasTextToImageGraph.ts index b25c266d66..094a7b02cc 100644 --- a/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasTextToImageGraph.ts +++ b/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildCanvasTextToImageGraph.ts @@ -59,6 +59,8 @@ export const buildCanvasTextToImageGraph = ( shouldAutoSave, } = state.canvas; + const fp32 = vaePrecision === 'fp32'; + const isUsingScaledDimensions = ['auto', 'manual'].includes( boundingBoxScaleMethod ); @@ -238,7 +240,7 @@ export const buildCanvasTextToImageGraph = ( id: LATENTS_TO_IMAGE, type: isUsingOnnxModel ? 'l2i_onnx' : 'l2i', is_intermediate: true, - fp32: vaePrecision === 'fp32' ? true : false, + fp32, }; graph.nodes[CANVAS_OUTPUT] = { @@ -276,7 +278,7 @@ export const buildCanvasTextToImageGraph = ( type: isUsingOnnxModel ? 'l2i_onnx' : 'l2i', id: CANVAS_OUTPUT, is_intermediate: !shouldAutoSave, - fp32: vaePrecision === 'fp32' ? true : false, + fp32, }; graph.edges.push({ diff --git a/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildLinearImageToImageGraph.ts b/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildLinearImageToImageGraph.ts index 7c1764ae65..dc9a34c67e 100644 --- a/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildLinearImageToImageGraph.ts +++ b/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildLinearImageToImageGraph.ts @@ -84,6 +84,8 @@ export const buildLinearImageToImageGraph = ( throw new Error('No model found in state'); } + const fp32 = vaePrecision === 'fp32'; + let modelLoaderNodeId = MAIN_MODEL_LOADER; const use_cpu = shouldUseNoiseSettings @@ -122,7 +124,7 @@ export const buildLinearImageToImageGraph = ( [LATENTS_TO_IMAGE]: { type: 'l2i', id: LATENTS_TO_IMAGE, - fp32: vaePrecision === 'fp32' ? true : false, + fp32, }, [DENOISE_LATENTS]: { type: 'denoise_latents', @@ -140,7 +142,7 @@ export const buildLinearImageToImageGraph = ( // image: { // image_name: initialImage.image_name, // }, - fp32: vaePrecision === 'fp32' ? true : false, + fp32, }, }, edges: [ diff --git a/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildLinearSDXLImageToImageGraph.ts b/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildLinearSDXLImageToImageGraph.ts index b1098be6a5..757a3976bb 100644 --- a/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildLinearSDXLImageToImageGraph.ts +++ b/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildLinearSDXLImageToImageGraph.ts @@ -84,6 +84,8 @@ export const buildLinearSDXLImageToImageGraph = ( throw new Error('No model found in state'); } + const fp32 = vaePrecision === 'fp32'; + // Model Loader ID let modelLoaderNodeId = SDXL_MODEL_LOADER; @@ -124,7 +126,7 @@ export const buildLinearSDXLImageToImageGraph = ( [LATENTS_TO_IMAGE]: { type: 'l2i', id: LATENTS_TO_IMAGE, - fp32: vaePrecision === 'fp32' ? true : false, + fp32, }, [SDXL_DENOISE_LATENTS]: { type: 'denoise_latents', @@ -144,7 +146,7 @@ export const buildLinearSDXLImageToImageGraph = ( // image: { // image_name: initialImage.image_name, // }, - fp32: vaePrecision === 'fp32' ? true : false, + fp32, }, }, edges: [ diff --git a/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildLinearSDXLTextToImageGraph.ts b/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildLinearSDXLTextToImageGraph.ts index bf25461e34..9590e77f89 100644 --- a/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildLinearSDXLTextToImageGraph.ts +++ b/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildLinearSDXLTextToImageGraph.ts @@ -62,6 +62,8 @@ export const buildLinearSDXLTextToImageGraph = ( throw new Error('No model found in state'); } + const fp32 = vaePrecision === 'fp32'; + // Construct Style Prompt const { craftedPositiveStylePrompt, craftedNegativeStylePrompt } = craftSDXLStylePrompt(state, shouldConcatSDXLStylePrompt); @@ -118,7 +120,7 @@ export const buildLinearSDXLTextToImageGraph = ( [LATENTS_TO_IMAGE]: { type: 'l2i', id: LATENTS_TO_IMAGE, - fp32: vaePrecision === 'fp32' ? true : false, + fp32, }, }, edges: [ diff --git a/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildLinearTextToImageGraph.ts b/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildLinearTextToImageGraph.ts index d07534bdd9..5c534fff21 100644 --- a/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildLinearTextToImageGraph.ts +++ b/invokeai/frontend/web/src/features/nodes/util/graphBuilders/buildLinearTextToImageGraph.ts @@ -57,6 +57,8 @@ export const buildLinearTextToImageGraph = ( throw new Error('No model found in state'); } + const fp32 = vaePrecision === 'fp32'; + const isUsingOnnxModel = model.model_type === 'onnx'; let modelLoaderNodeId = isUsingOnnxModel @@ -139,7 +141,7 @@ export const buildLinearTextToImageGraph = ( [LATENTS_TO_IMAGE]: { type: isUsingOnnxModel ? 'l2i_onnx' : 'l2i', id: LATENTS_TO_IMAGE, - fp32: vaePrecision === 'fp32' ? true : false, + fp32, }, }, edges: [ From d2e327add96416d12628df10abcf60af240150e7 Mon Sep 17 00:00:00 2001 From: Lincoln Stein Date: Mon, 4 Sep 2023 21:54:40 -0400 Subject: [PATCH 23/26] install models/core/misc/lama/lama.pt --- invokeai/backend/install/invokeai_configure.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/invokeai/backend/install/invokeai_configure.py b/invokeai/backend/install/invokeai_configure.py index 90298ce076..8d9500cf4a 100755 --- a/invokeai/backend/install/invokeai_configure.py +++ b/invokeai/backend/install/invokeai_configure.py @@ -290,9 +290,19 @@ def download_realesrgan(): download_with_progress_bar(model["url"], config.models_path / model["dest"], model["description"]) +# --------------------------------------------- +def download_lama(): + logger.info("Installing lama infill model") + download_with_progress_bar( + 'https://github.com/Sanster/models/releases/download/add_big_lama/big-lama.pt', + config.models_path / 'core/misc/lama/lama.pt', + 'lama infill model' + ) + # --------------------------------------------- def download_support_models(): download_realesrgan() + download_lama() download_conversion_models() From 871b9286d128b1001910e7ca9a7f9298baae634b Mon Sep 17 00:00:00 2001 From: blessedcoolant <54517381+blessedcoolant@users.noreply.github.com> Date: Tue, 5 Sep 2023 14:10:41 +1200 Subject: [PATCH 24/26] fix: Review changes --- .../InfillAndScaling/ParamInfillPatchmatchDownscaleSize.tsx | 1 - .../web/src/features/parameters/store/generationSlice.ts | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/invokeai/frontend/web/src/features/parameters/components/Parameters/Canvas/InfillAndScaling/ParamInfillPatchmatchDownscaleSize.tsx b/invokeai/frontend/web/src/features/parameters/components/Parameters/Canvas/InfillAndScaling/ParamInfillPatchmatchDownscaleSize.tsx index d8e9749422..4e1aa0f721 100644 --- a/invokeai/frontend/web/src/features/parameters/components/Parameters/Canvas/InfillAndScaling/ParamInfillPatchmatchDownscaleSize.tsx +++ b/invokeai/frontend/web/src/features/parameters/components/Parameters/Canvas/InfillAndScaling/ParamInfillPatchmatchDownscaleSize.tsx @@ -45,7 +45,6 @@ const ParamInfillPatchmatchDownscaleSize = () => { label={t('parameters.patchmatchDownScaleSize')} min={1} max={10} - sliderNumberInputProps={{ max: 10 }} value={infillPatchmatchDownscaleSize} onChange={handleChange} withInput diff --git a/invokeai/frontend/web/src/features/parameters/store/generationSlice.ts b/invokeai/frontend/web/src/features/parameters/store/generationSlice.ts index 7703376e43..50d9894b27 100644 --- a/invokeai/frontend/web/src/features/parameters/store/generationSlice.ts +++ b/invokeai/frontend/web/src/features/parameters/store/generationSlice.ts @@ -92,7 +92,7 @@ export const initialGenerationState: GenerationState = { steps: 50, threshold: 0, infillTileSize: 32, - infillPatchmatchDownscaleSize: 2, + infillPatchmatchDownscaleSize: 1, variationAmount: 0.1, width: 512, shouldUseSymmetry: false, From a9fafad5b5d4967fcb19cb1cce3bb2c6550d8b2a Mon Sep 17 00:00:00 2001 From: blessedcoolant <54517381+blessedcoolant@users.noreply.github.com> Date: Tue, 5 Sep 2023 14:17:23 +1200 Subject: [PATCH 25/26] chore: sync, lint & update --- .../backend/install/invokeai_configure.py | 9 ++- .../frontend/web/src/services/api/schema.d.ts | 74 +++++++++++++++---- 2 files changed, 65 insertions(+), 18 deletions(-) diff --git a/invokeai/backend/install/invokeai_configure.py b/invokeai/backend/install/invokeai_configure.py index 8d9500cf4a..4a512bfa5f 100755 --- a/invokeai/backend/install/invokeai_configure.py +++ b/invokeai/backend/install/invokeai_configure.py @@ -294,11 +294,12 @@ def download_realesrgan(): def download_lama(): logger.info("Installing lama infill model") download_with_progress_bar( - 'https://github.com/Sanster/models/releases/download/add_big_lama/big-lama.pt', - config.models_path / 'core/misc/lama/lama.pt', - 'lama infill model' + "https://github.com/Sanster/models/releases/download/add_big_lama/big-lama.pt", + config.models_path / "core/misc/lama/lama.pt", + "lama infill model", ) - + + # --------------------------------------------- def download_support_models(): download_realesrgan() diff --git a/invokeai/frontend/web/src/services/api/schema.d.ts b/invokeai/frontend/web/src/services/api/schema.d.ts index 986cade3b6..f4b87e15da 100644 --- a/invokeai/frontend/web/src/services/api/schema.d.ts +++ b/invokeai/frontend/web/src/services/api/schema.d.ts @@ -780,6 +780,39 @@ export type components = { */ type: "boolean_output"; }; + /** + * CV2 Infill + * @description Infills transparent areas of an image using OpenCV Inpainting + */ + CV2InfillInvocation: { + /** + * 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; + /** + * Workflow + * @description The workflow to save with the image + */ + workflow?: string; + /** + * Image + * @description The image to infill + */ + image?: components["schemas"]["ImageField"]; + /** + * Type + * @default infill_cv2 + * @enum {string} + */ + type: "infill_cv2"; + }; /** * Canny Processor * @description Canny edge detection for ControlNet @@ -2212,7 +2245,7 @@ export type components = { * @description The nodes in this graph */ nodes?: { - [key: string]: components["schemas"]["BooleanInvocation"] | components["schemas"]["BooleanCollectionInvocation"] | components["schemas"]["IntegerInvocation"] | components["schemas"]["IntegerCollectionInvocation"] | components["schemas"]["FloatInvocation"] | components["schemas"]["FloatCollectionInvocation"] | components["schemas"]["StringInvocation"] | components["schemas"]["StringCollectionInvocation"] | components["schemas"]["ImageInvocation"] | components["schemas"]["ImageCollectionInvocation"] | components["schemas"]["LatentsInvocation"] | components["schemas"]["LatentsCollectionInvocation"] | components["schemas"]["ColorInvocation"] | components["schemas"]["ConditioningInvocation"] | components["schemas"]["ConditioningCollectionInvocation"] | components["schemas"]["ControlNetInvocation"] | components["schemas"]["ImageProcessorInvocation"] | components["schemas"]["MainModelLoaderInvocation"] | components["schemas"]["LoraLoaderInvocation"] | components["schemas"]["SDXLLoraLoaderInvocation"] | components["schemas"]["VaeLoaderInvocation"] | components["schemas"]["SeamlessModeInvocation"] | components["schemas"]["MetadataAccumulatorInvocation"] | components["schemas"]["SDXLModelLoaderInvocation"] | components["schemas"]["SDXLRefinerModelLoaderInvocation"] | components["schemas"]["CompelInvocation"] | components["schemas"]["SDXLCompelPromptInvocation"] | components["schemas"]["SDXLRefinerCompelPromptInvocation"] | components["schemas"]["ClipSkipInvocation"] | components["schemas"]["SchedulerInvocation"] | components["schemas"]["CreateDenoiseMaskInvocation"] | components["schemas"]["DenoiseLatentsInvocation"] | components["schemas"]["LatentsToImageInvocation"] | components["schemas"]["ResizeLatentsInvocation"] | components["schemas"]["ScaleLatentsInvocation"] | components["schemas"]["ImageToLatentsInvocation"] | components["schemas"]["BlendLatentsInvocation"] | components["schemas"]["ONNXPromptInvocation"] | components["schemas"]["ONNXTextToLatentsInvocation"] | components["schemas"]["ONNXLatentsToImageInvocation"] | components["schemas"]["OnnxModelLoaderInvocation"] | components["schemas"]["ShowImageInvocation"] | components["schemas"]["BlankImageInvocation"] | components["schemas"]["ImageCropInvocation"] | components["schemas"]["ImagePasteInvocation"] | components["schemas"]["MaskFromAlphaInvocation"] | components["schemas"]["ImageMultiplyInvocation"] | components["schemas"]["ImageChannelInvocation"] | components["schemas"]["ImageConvertInvocation"] | components["schemas"]["ImageBlurInvocation"] | components["schemas"]["ImageResizeInvocation"] | components["schemas"]["ImageScaleInvocation"] | components["schemas"]["ImageLerpInvocation"] | components["schemas"]["ImageInverseLerpInvocation"] | components["schemas"]["ImageNSFWBlurInvocation"] | components["schemas"]["ImageWatermarkInvocation"] | components["schemas"]["MaskEdgeInvocation"] | components["schemas"]["MaskCombineInvocation"] | components["schemas"]["ColorCorrectInvocation"] | components["schemas"]["ImageHueAdjustmentInvocation"] | components["schemas"]["ImageChannelOffsetInvocation"] | components["schemas"]["ImageChannelMultiplyInvocation"] | components["schemas"]["DynamicPromptInvocation"] | components["schemas"]["PromptsFromFileInvocation"] | components["schemas"]["CvInpaintInvocation"] | components["schemas"]["FloatLinearRangeInvocation"] | components["schemas"]["StepParamEasingInvocation"] | components["schemas"]["AddInvocation"] | components["schemas"]["SubtractInvocation"] | components["schemas"]["MultiplyInvocation"] | components["schemas"]["DivideInvocation"] | components["schemas"]["RandomIntInvocation"] | components["schemas"]["NoiseInvocation"] | components["schemas"]["RangeInvocation"] | components["schemas"]["RangeOfSizeInvocation"] | components["schemas"]["RandomRangeInvocation"] | components["schemas"]["ESRGANInvocation"] | components["schemas"]["InfillColorInvocation"] | components["schemas"]["InfillTileInvocation"] | components["schemas"]["InfillPatchMatchInvocation"] | components["schemas"]["LaMaInfillInvocation"] | components["schemas"]["GraphInvocation"] | components["schemas"]["IterateInvocation"] | components["schemas"]["CollectInvocation"] | components["schemas"]["CannyImageProcessorInvocation"] | components["schemas"]["HedImageProcessorInvocation"] | components["schemas"]["LineartImageProcessorInvocation"] | components["schemas"]["LineartAnimeImageProcessorInvocation"] | components["schemas"]["OpenposeImageProcessorInvocation"] | components["schemas"]["MidasDepthImageProcessorInvocation"] | components["schemas"]["NormalbaeImageProcessorInvocation"] | components["schemas"]["MlsdImageProcessorInvocation"] | components["schemas"]["PidiImageProcessorInvocation"] | components["schemas"]["ContentShuffleImageProcessorInvocation"] | components["schemas"]["ZoeDepthImageProcessorInvocation"] | components["schemas"]["MediapipeFaceProcessorInvocation"] | components["schemas"]["LeresImageProcessorInvocation"] | components["schemas"]["TileResamplerProcessorInvocation"] | components["schemas"]["SegmentAnythingProcessorInvocation"]; + [key: string]: components["schemas"]["BooleanInvocation"] | components["schemas"]["BooleanCollectionInvocation"] | components["schemas"]["IntegerInvocation"] | components["schemas"]["IntegerCollectionInvocation"] | components["schemas"]["FloatInvocation"] | components["schemas"]["FloatCollectionInvocation"] | components["schemas"]["StringInvocation"] | components["schemas"]["StringCollectionInvocation"] | components["schemas"]["ImageInvocation"] | components["schemas"]["ImageCollectionInvocation"] | components["schemas"]["LatentsInvocation"] | components["schemas"]["LatentsCollectionInvocation"] | components["schemas"]["ColorInvocation"] | components["schemas"]["ConditioningInvocation"] | components["schemas"]["ConditioningCollectionInvocation"] | components["schemas"]["ControlNetInvocation"] | components["schemas"]["ImageProcessorInvocation"] | components["schemas"]["MainModelLoaderInvocation"] | components["schemas"]["LoraLoaderInvocation"] | components["schemas"]["SDXLLoraLoaderInvocation"] | components["schemas"]["VaeLoaderInvocation"] | components["schemas"]["SeamlessModeInvocation"] | components["schemas"]["MetadataAccumulatorInvocation"] | components["schemas"]["RangeInvocation"] | components["schemas"]["RangeOfSizeInvocation"] | components["schemas"]["RandomRangeInvocation"] | components["schemas"]["CompelInvocation"] | components["schemas"]["SDXLCompelPromptInvocation"] | components["schemas"]["SDXLRefinerCompelPromptInvocation"] | components["schemas"]["ClipSkipInvocation"] | components["schemas"]["CvInpaintInvocation"] | components["schemas"]["ShowImageInvocation"] | components["schemas"]["BlankImageInvocation"] | components["schemas"]["ImageCropInvocation"] | components["schemas"]["ImagePasteInvocation"] | components["schemas"]["MaskFromAlphaInvocation"] | components["schemas"]["ImageMultiplyInvocation"] | components["schemas"]["ImageChannelInvocation"] | components["schemas"]["ImageConvertInvocation"] | components["schemas"]["ImageBlurInvocation"] | components["schemas"]["ImageResizeInvocation"] | components["schemas"]["ImageScaleInvocation"] | components["schemas"]["ImageLerpInvocation"] | components["schemas"]["ImageInverseLerpInvocation"] | components["schemas"]["ImageNSFWBlurInvocation"] | components["schemas"]["ImageWatermarkInvocation"] | components["schemas"]["MaskEdgeInvocation"] | components["schemas"]["MaskCombineInvocation"] | components["schemas"]["ColorCorrectInvocation"] | components["schemas"]["ImageHueAdjustmentInvocation"] | components["schemas"]["ImageChannelOffsetInvocation"] | components["schemas"]["ImageChannelMultiplyInvocation"] | components["schemas"]["InfillColorInvocation"] | components["schemas"]["InfillTileInvocation"] | components["schemas"]["InfillPatchMatchInvocation"] | components["schemas"]["LaMaInfillInvocation"] | components["schemas"]["CV2InfillInvocation"] | components["schemas"]["SchedulerInvocation"] | components["schemas"]["CreateDenoiseMaskInvocation"] | components["schemas"]["DenoiseLatentsInvocation"] | components["schemas"]["LatentsToImageInvocation"] | components["schemas"]["ResizeLatentsInvocation"] | components["schemas"]["ScaleLatentsInvocation"] | components["schemas"]["ImageToLatentsInvocation"] | components["schemas"]["BlendLatentsInvocation"] | components["schemas"]["AddInvocation"] | components["schemas"]["SubtractInvocation"] | components["schemas"]["MultiplyInvocation"] | components["schemas"]["DivideInvocation"] | components["schemas"]["RandomIntInvocation"] | components["schemas"]["NoiseInvocation"] | components["schemas"]["ONNXPromptInvocation"] | components["schemas"]["ONNXTextToLatentsInvocation"] | components["schemas"]["ONNXLatentsToImageInvocation"] | components["schemas"]["OnnxModelLoaderInvocation"] | components["schemas"]["FloatLinearRangeInvocation"] | components["schemas"]["StepParamEasingInvocation"] | components["schemas"]["DynamicPromptInvocation"] | components["schemas"]["PromptsFromFileInvocation"] | components["schemas"]["SDXLModelLoaderInvocation"] | components["schemas"]["SDXLRefinerModelLoaderInvocation"] | components["schemas"]["ESRGANInvocation"] | components["schemas"]["GraphInvocation"] | components["schemas"]["IterateInvocation"] | components["schemas"]["CollectInvocation"] | components["schemas"]["CannyImageProcessorInvocation"] | components["schemas"]["HedImageProcessorInvocation"] | components["schemas"]["LineartImageProcessorInvocation"] | components["schemas"]["LineartAnimeImageProcessorInvocation"] | components["schemas"]["OpenposeImageProcessorInvocation"] | components["schemas"]["MidasDepthImageProcessorInvocation"] | components["schemas"]["NormalbaeImageProcessorInvocation"] | components["schemas"]["MlsdImageProcessorInvocation"] | components["schemas"]["PidiImageProcessorInvocation"] | components["schemas"]["ContentShuffleImageProcessorInvocation"] | components["schemas"]["ZoeDepthImageProcessorInvocation"] | components["schemas"]["MediapipeFaceProcessorInvocation"] | components["schemas"]["LeresImageProcessorInvocation"] | components["schemas"]["TileResamplerProcessorInvocation"] | components["schemas"]["SegmentAnythingProcessorInvocation"]; }; /** * Edges @@ -2255,7 +2288,7 @@ export type components = { * @description The results of node executions */ results: { - [key: string]: components["schemas"]["BooleanOutput"] | components["schemas"]["BooleanCollectionOutput"] | components["schemas"]["IntegerOutput"] | components["schemas"]["IntegerCollectionOutput"] | components["schemas"]["FloatOutput"] | components["schemas"]["FloatCollectionOutput"] | components["schemas"]["StringOutput"] | components["schemas"]["StringCollectionOutput"] | components["schemas"]["ImageOutput"] | components["schemas"]["ImageCollectionOutput"] | components["schemas"]["DenoiseMaskOutput"] | components["schemas"]["LatentsOutput"] | components["schemas"]["LatentsCollectionOutput"] | components["schemas"]["ColorOutput"] | components["schemas"]["ColorCollectionOutput"] | components["schemas"]["ConditioningOutput"] | components["schemas"]["ConditioningCollectionOutput"] | components["schemas"]["ControlOutput"] | components["schemas"]["ModelLoaderOutput"] | components["schemas"]["LoraLoaderOutput"] | components["schemas"]["SDXLLoraLoaderOutput"] | components["schemas"]["VaeLoaderOutput"] | components["schemas"]["SeamlessModeOutput"] | components["schemas"]["MetadataAccumulatorOutput"] | components["schemas"]["SDXLModelLoaderOutput"] | components["schemas"]["SDXLRefinerModelLoaderOutput"] | components["schemas"]["ClipSkipInvocationOutput"] | components["schemas"]["SchedulerOutput"] | components["schemas"]["ONNXModelLoaderOutput"] | components["schemas"]["NoiseOutput"] | components["schemas"]["GraphInvocationOutput"] | components["schemas"]["IterateInvocationOutput"] | components["schemas"]["CollectInvocationOutput"]; + [key: string]: components["schemas"]["BooleanOutput"] | components["schemas"]["BooleanCollectionOutput"] | components["schemas"]["IntegerOutput"] | components["schemas"]["IntegerCollectionOutput"] | components["schemas"]["FloatOutput"] | components["schemas"]["FloatCollectionOutput"] | components["schemas"]["StringOutput"] | components["schemas"]["StringCollectionOutput"] | components["schemas"]["ImageOutput"] | components["schemas"]["ImageCollectionOutput"] | components["schemas"]["DenoiseMaskOutput"] | components["schemas"]["LatentsOutput"] | components["schemas"]["LatentsCollectionOutput"] | components["schemas"]["ColorOutput"] | components["schemas"]["ColorCollectionOutput"] | components["schemas"]["ConditioningOutput"] | components["schemas"]["ConditioningCollectionOutput"] | components["schemas"]["ControlOutput"] | components["schemas"]["ModelLoaderOutput"] | components["schemas"]["LoraLoaderOutput"] | components["schemas"]["SDXLLoraLoaderOutput"] | components["schemas"]["VaeLoaderOutput"] | components["schemas"]["SeamlessModeOutput"] | components["schemas"]["MetadataAccumulatorOutput"] | components["schemas"]["ClipSkipInvocationOutput"] | components["schemas"]["SchedulerOutput"] | components["schemas"]["NoiseOutput"] | components["schemas"]["ONNXModelLoaderOutput"] | components["schemas"]["SDXLModelLoaderOutput"] | components["schemas"]["SDXLRefinerModelLoaderOutput"] | components["schemas"]["GraphInvocationOutput"] | components["schemas"]["IterateInvocationOutput"] | components["schemas"]["CollectInvocationOutput"]; }; /** * Errors @@ -3503,6 +3536,19 @@ export type components = { * @description The image to infill */ image?: components["schemas"]["ImageField"]; + /** + * Downscale + * @description Run patchmatch on downscaled image to speedup infill + * @default 2 + */ + downscale?: number; + /** + * Resample Mode + * @description The resampling mode + * @default bicubic + * @enum {string} + */ + resample_mode?: "nearest" | "box" | "bilinear" | "hamming" | "bicubic" | "lanczos"; /** * Type * @default infill_patchmatch @@ -7059,6 +7105,12 @@ export type components = { /** Ui Order */ ui_order?: number; }; + /** + * StableDiffusionXLModelFormat + * @description An enumeration. + * @enum {string} + */ + StableDiffusionXLModelFormat: "checkpoint" | "diffusers"; /** * StableDiffusionOnnxModelFormat * @description An enumeration. @@ -7066,17 +7118,11 @@ export type components = { */ StableDiffusionOnnxModelFormat: "olive" | "onnx"; /** - * StableDiffusion1ModelFormat + * ControlNetModelFormat * @description An enumeration. * @enum {string} */ - StableDiffusion1ModelFormat: "checkpoint" | "diffusers"; - /** - * StableDiffusionXLModelFormat - * @description An enumeration. - * @enum {string} - */ - StableDiffusionXLModelFormat: "checkpoint" | "diffusers"; + ControlNetModelFormat: "checkpoint" | "diffusers"; /** * StableDiffusion2ModelFormat * @description An enumeration. @@ -7084,11 +7130,11 @@ export type components = { */ StableDiffusion2ModelFormat: "checkpoint" | "diffusers"; /** - * ControlNetModelFormat + * StableDiffusion1ModelFormat * @description An enumeration. * @enum {string} */ - ControlNetModelFormat: "checkpoint" | "diffusers"; + StableDiffusion1ModelFormat: "checkpoint" | "diffusers"; }; responses: never; parameters: never; @@ -7205,7 +7251,7 @@ export type operations = { }; requestBody: { content: { - "application/json": components["schemas"]["BooleanInvocation"] | components["schemas"]["BooleanCollectionInvocation"] | components["schemas"]["IntegerInvocation"] | components["schemas"]["IntegerCollectionInvocation"] | components["schemas"]["FloatInvocation"] | components["schemas"]["FloatCollectionInvocation"] | components["schemas"]["StringInvocation"] | components["schemas"]["StringCollectionInvocation"] | components["schemas"]["ImageInvocation"] | components["schemas"]["ImageCollectionInvocation"] | components["schemas"]["LatentsInvocation"] | components["schemas"]["LatentsCollectionInvocation"] | components["schemas"]["ColorInvocation"] | components["schemas"]["ConditioningInvocation"] | components["schemas"]["ConditioningCollectionInvocation"] | components["schemas"]["ControlNetInvocation"] | components["schemas"]["ImageProcessorInvocation"] | components["schemas"]["MainModelLoaderInvocation"] | components["schemas"]["LoraLoaderInvocation"] | components["schemas"]["SDXLLoraLoaderInvocation"] | components["schemas"]["VaeLoaderInvocation"] | components["schemas"]["SeamlessModeInvocation"] | components["schemas"]["MetadataAccumulatorInvocation"] | components["schemas"]["SDXLModelLoaderInvocation"] | components["schemas"]["SDXLRefinerModelLoaderInvocation"] | components["schemas"]["CompelInvocation"] | components["schemas"]["SDXLCompelPromptInvocation"] | components["schemas"]["SDXLRefinerCompelPromptInvocation"] | components["schemas"]["ClipSkipInvocation"] | components["schemas"]["SchedulerInvocation"] | components["schemas"]["CreateDenoiseMaskInvocation"] | components["schemas"]["DenoiseLatentsInvocation"] | components["schemas"]["LatentsToImageInvocation"] | components["schemas"]["ResizeLatentsInvocation"] | components["schemas"]["ScaleLatentsInvocation"] | components["schemas"]["ImageToLatentsInvocation"] | components["schemas"]["BlendLatentsInvocation"] | components["schemas"]["ONNXPromptInvocation"] | components["schemas"]["ONNXTextToLatentsInvocation"] | components["schemas"]["ONNXLatentsToImageInvocation"] | components["schemas"]["OnnxModelLoaderInvocation"] | components["schemas"]["ShowImageInvocation"] | components["schemas"]["BlankImageInvocation"] | components["schemas"]["ImageCropInvocation"] | components["schemas"]["ImagePasteInvocation"] | components["schemas"]["MaskFromAlphaInvocation"] | components["schemas"]["ImageMultiplyInvocation"] | components["schemas"]["ImageChannelInvocation"] | components["schemas"]["ImageConvertInvocation"] | components["schemas"]["ImageBlurInvocation"] | components["schemas"]["ImageResizeInvocation"] | components["schemas"]["ImageScaleInvocation"] | components["schemas"]["ImageLerpInvocation"] | components["schemas"]["ImageInverseLerpInvocation"] | components["schemas"]["ImageNSFWBlurInvocation"] | components["schemas"]["ImageWatermarkInvocation"] | components["schemas"]["MaskEdgeInvocation"] | components["schemas"]["MaskCombineInvocation"] | components["schemas"]["ColorCorrectInvocation"] | components["schemas"]["ImageHueAdjustmentInvocation"] | components["schemas"]["ImageChannelOffsetInvocation"] | components["schemas"]["ImageChannelMultiplyInvocation"] | components["schemas"]["DynamicPromptInvocation"] | components["schemas"]["PromptsFromFileInvocation"] | components["schemas"]["CvInpaintInvocation"] | components["schemas"]["FloatLinearRangeInvocation"] | components["schemas"]["StepParamEasingInvocation"] | components["schemas"]["AddInvocation"] | components["schemas"]["SubtractInvocation"] | components["schemas"]["MultiplyInvocation"] | components["schemas"]["DivideInvocation"] | components["schemas"]["RandomIntInvocation"] | components["schemas"]["NoiseInvocation"] | components["schemas"]["RangeInvocation"] | components["schemas"]["RangeOfSizeInvocation"] | components["schemas"]["RandomRangeInvocation"] | components["schemas"]["ESRGANInvocation"] | components["schemas"]["InfillColorInvocation"] | components["schemas"]["InfillTileInvocation"] | components["schemas"]["InfillPatchMatchInvocation"] | components["schemas"]["LaMaInfillInvocation"] | components["schemas"]["GraphInvocation"] | components["schemas"]["IterateInvocation"] | components["schemas"]["CollectInvocation"] | components["schemas"]["CannyImageProcessorInvocation"] | components["schemas"]["HedImageProcessorInvocation"] | components["schemas"]["LineartImageProcessorInvocation"] | components["schemas"]["LineartAnimeImageProcessorInvocation"] | components["schemas"]["OpenposeImageProcessorInvocation"] | components["schemas"]["MidasDepthImageProcessorInvocation"] | components["schemas"]["NormalbaeImageProcessorInvocation"] | components["schemas"]["MlsdImageProcessorInvocation"] | components["schemas"]["PidiImageProcessorInvocation"] | components["schemas"]["ContentShuffleImageProcessorInvocation"] | components["schemas"]["ZoeDepthImageProcessorInvocation"] | components["schemas"]["MediapipeFaceProcessorInvocation"] | components["schemas"]["LeresImageProcessorInvocation"] | components["schemas"]["TileResamplerProcessorInvocation"] | components["schemas"]["SegmentAnythingProcessorInvocation"]; + "application/json": components["schemas"]["BooleanInvocation"] | components["schemas"]["BooleanCollectionInvocation"] | components["schemas"]["IntegerInvocation"] | components["schemas"]["IntegerCollectionInvocation"] | components["schemas"]["FloatInvocation"] | components["schemas"]["FloatCollectionInvocation"] | components["schemas"]["StringInvocation"] | components["schemas"]["StringCollectionInvocation"] | components["schemas"]["ImageInvocation"] | components["schemas"]["ImageCollectionInvocation"] | components["schemas"]["LatentsInvocation"] | components["schemas"]["LatentsCollectionInvocation"] | components["schemas"]["ColorInvocation"] | components["schemas"]["ConditioningInvocation"] | components["schemas"]["ConditioningCollectionInvocation"] | components["schemas"]["ControlNetInvocation"] | components["schemas"]["ImageProcessorInvocation"] | components["schemas"]["MainModelLoaderInvocation"] | components["schemas"]["LoraLoaderInvocation"] | components["schemas"]["SDXLLoraLoaderInvocation"] | components["schemas"]["VaeLoaderInvocation"] | components["schemas"]["SeamlessModeInvocation"] | components["schemas"]["MetadataAccumulatorInvocation"] | components["schemas"]["RangeInvocation"] | components["schemas"]["RangeOfSizeInvocation"] | components["schemas"]["RandomRangeInvocation"] | components["schemas"]["CompelInvocation"] | components["schemas"]["SDXLCompelPromptInvocation"] | components["schemas"]["SDXLRefinerCompelPromptInvocation"] | components["schemas"]["ClipSkipInvocation"] | components["schemas"]["CvInpaintInvocation"] | components["schemas"]["ShowImageInvocation"] | components["schemas"]["BlankImageInvocation"] | components["schemas"]["ImageCropInvocation"] | components["schemas"]["ImagePasteInvocation"] | components["schemas"]["MaskFromAlphaInvocation"] | components["schemas"]["ImageMultiplyInvocation"] | components["schemas"]["ImageChannelInvocation"] | components["schemas"]["ImageConvertInvocation"] | components["schemas"]["ImageBlurInvocation"] | components["schemas"]["ImageResizeInvocation"] | components["schemas"]["ImageScaleInvocation"] | components["schemas"]["ImageLerpInvocation"] | components["schemas"]["ImageInverseLerpInvocation"] | components["schemas"]["ImageNSFWBlurInvocation"] | components["schemas"]["ImageWatermarkInvocation"] | components["schemas"]["MaskEdgeInvocation"] | components["schemas"]["MaskCombineInvocation"] | components["schemas"]["ColorCorrectInvocation"] | components["schemas"]["ImageHueAdjustmentInvocation"] | components["schemas"]["ImageChannelOffsetInvocation"] | components["schemas"]["ImageChannelMultiplyInvocation"] | components["schemas"]["InfillColorInvocation"] | components["schemas"]["InfillTileInvocation"] | components["schemas"]["InfillPatchMatchInvocation"] | components["schemas"]["LaMaInfillInvocation"] | components["schemas"]["CV2InfillInvocation"] | components["schemas"]["SchedulerInvocation"] | components["schemas"]["CreateDenoiseMaskInvocation"] | components["schemas"]["DenoiseLatentsInvocation"] | components["schemas"]["LatentsToImageInvocation"] | components["schemas"]["ResizeLatentsInvocation"] | components["schemas"]["ScaleLatentsInvocation"] | components["schemas"]["ImageToLatentsInvocation"] | components["schemas"]["BlendLatentsInvocation"] | components["schemas"]["AddInvocation"] | components["schemas"]["SubtractInvocation"] | components["schemas"]["MultiplyInvocation"] | components["schemas"]["DivideInvocation"] | components["schemas"]["RandomIntInvocation"] | components["schemas"]["NoiseInvocation"] | components["schemas"]["ONNXPromptInvocation"] | components["schemas"]["ONNXTextToLatentsInvocation"] | components["schemas"]["ONNXLatentsToImageInvocation"] | components["schemas"]["OnnxModelLoaderInvocation"] | components["schemas"]["FloatLinearRangeInvocation"] | components["schemas"]["StepParamEasingInvocation"] | components["schemas"]["DynamicPromptInvocation"] | components["schemas"]["PromptsFromFileInvocation"] | components["schemas"]["SDXLModelLoaderInvocation"] | components["schemas"]["SDXLRefinerModelLoaderInvocation"] | components["schemas"]["ESRGANInvocation"] | components["schemas"]["GraphInvocation"] | components["schemas"]["IterateInvocation"] | components["schemas"]["CollectInvocation"] | components["schemas"]["CannyImageProcessorInvocation"] | components["schemas"]["HedImageProcessorInvocation"] | components["schemas"]["LineartImageProcessorInvocation"] | components["schemas"]["LineartAnimeImageProcessorInvocation"] | components["schemas"]["OpenposeImageProcessorInvocation"] | components["schemas"]["MidasDepthImageProcessorInvocation"] | components["schemas"]["NormalbaeImageProcessorInvocation"] | components["schemas"]["MlsdImageProcessorInvocation"] | components["schemas"]["PidiImageProcessorInvocation"] | components["schemas"]["ContentShuffleImageProcessorInvocation"] | components["schemas"]["ZoeDepthImageProcessorInvocation"] | components["schemas"]["MediapipeFaceProcessorInvocation"] | components["schemas"]["LeresImageProcessorInvocation"] | components["schemas"]["TileResamplerProcessorInvocation"] | components["schemas"]["SegmentAnythingProcessorInvocation"]; }; }; responses: { @@ -7246,7 +7292,7 @@ export type operations = { }; requestBody: { content: { - "application/json": components["schemas"]["BooleanInvocation"] | components["schemas"]["BooleanCollectionInvocation"] | components["schemas"]["IntegerInvocation"] | components["schemas"]["IntegerCollectionInvocation"] | components["schemas"]["FloatInvocation"] | components["schemas"]["FloatCollectionInvocation"] | components["schemas"]["StringInvocation"] | components["schemas"]["StringCollectionInvocation"] | components["schemas"]["ImageInvocation"] | components["schemas"]["ImageCollectionInvocation"] | components["schemas"]["LatentsInvocation"] | components["schemas"]["LatentsCollectionInvocation"] | components["schemas"]["ColorInvocation"] | components["schemas"]["ConditioningInvocation"] | components["schemas"]["ConditioningCollectionInvocation"] | components["schemas"]["ControlNetInvocation"] | components["schemas"]["ImageProcessorInvocation"] | components["schemas"]["MainModelLoaderInvocation"] | components["schemas"]["LoraLoaderInvocation"] | components["schemas"]["SDXLLoraLoaderInvocation"] | components["schemas"]["VaeLoaderInvocation"] | components["schemas"]["SeamlessModeInvocation"] | components["schemas"]["MetadataAccumulatorInvocation"] | components["schemas"]["SDXLModelLoaderInvocation"] | components["schemas"]["SDXLRefinerModelLoaderInvocation"] | components["schemas"]["CompelInvocation"] | components["schemas"]["SDXLCompelPromptInvocation"] | components["schemas"]["SDXLRefinerCompelPromptInvocation"] | components["schemas"]["ClipSkipInvocation"] | components["schemas"]["SchedulerInvocation"] | components["schemas"]["CreateDenoiseMaskInvocation"] | components["schemas"]["DenoiseLatentsInvocation"] | components["schemas"]["LatentsToImageInvocation"] | components["schemas"]["ResizeLatentsInvocation"] | components["schemas"]["ScaleLatentsInvocation"] | components["schemas"]["ImageToLatentsInvocation"] | components["schemas"]["BlendLatentsInvocation"] | components["schemas"]["ONNXPromptInvocation"] | components["schemas"]["ONNXTextToLatentsInvocation"] | components["schemas"]["ONNXLatentsToImageInvocation"] | components["schemas"]["OnnxModelLoaderInvocation"] | components["schemas"]["ShowImageInvocation"] | components["schemas"]["BlankImageInvocation"] | components["schemas"]["ImageCropInvocation"] | components["schemas"]["ImagePasteInvocation"] | components["schemas"]["MaskFromAlphaInvocation"] | components["schemas"]["ImageMultiplyInvocation"] | components["schemas"]["ImageChannelInvocation"] | components["schemas"]["ImageConvertInvocation"] | components["schemas"]["ImageBlurInvocation"] | components["schemas"]["ImageResizeInvocation"] | components["schemas"]["ImageScaleInvocation"] | components["schemas"]["ImageLerpInvocation"] | components["schemas"]["ImageInverseLerpInvocation"] | components["schemas"]["ImageNSFWBlurInvocation"] | components["schemas"]["ImageWatermarkInvocation"] | components["schemas"]["MaskEdgeInvocation"] | components["schemas"]["MaskCombineInvocation"] | components["schemas"]["ColorCorrectInvocation"] | components["schemas"]["ImageHueAdjustmentInvocation"] | components["schemas"]["ImageChannelOffsetInvocation"] | components["schemas"]["ImageChannelMultiplyInvocation"] | components["schemas"]["DynamicPromptInvocation"] | components["schemas"]["PromptsFromFileInvocation"] | components["schemas"]["CvInpaintInvocation"] | components["schemas"]["FloatLinearRangeInvocation"] | components["schemas"]["StepParamEasingInvocation"] | components["schemas"]["AddInvocation"] | components["schemas"]["SubtractInvocation"] | components["schemas"]["MultiplyInvocation"] | components["schemas"]["DivideInvocation"] | components["schemas"]["RandomIntInvocation"] | components["schemas"]["NoiseInvocation"] | components["schemas"]["RangeInvocation"] | components["schemas"]["RangeOfSizeInvocation"] | components["schemas"]["RandomRangeInvocation"] | components["schemas"]["ESRGANInvocation"] | components["schemas"]["InfillColorInvocation"] | components["schemas"]["InfillTileInvocation"] | components["schemas"]["InfillPatchMatchInvocation"] | components["schemas"]["LaMaInfillInvocation"] | components["schemas"]["GraphInvocation"] | components["schemas"]["IterateInvocation"] | components["schemas"]["CollectInvocation"] | components["schemas"]["CannyImageProcessorInvocation"] | components["schemas"]["HedImageProcessorInvocation"] | components["schemas"]["LineartImageProcessorInvocation"] | components["schemas"]["LineartAnimeImageProcessorInvocation"] | components["schemas"]["OpenposeImageProcessorInvocation"] | components["schemas"]["MidasDepthImageProcessorInvocation"] | components["schemas"]["NormalbaeImageProcessorInvocation"] | components["schemas"]["MlsdImageProcessorInvocation"] | components["schemas"]["PidiImageProcessorInvocation"] | components["schemas"]["ContentShuffleImageProcessorInvocation"] | components["schemas"]["ZoeDepthImageProcessorInvocation"] | components["schemas"]["MediapipeFaceProcessorInvocation"] | components["schemas"]["LeresImageProcessorInvocation"] | components["schemas"]["TileResamplerProcessorInvocation"] | components["schemas"]["SegmentAnythingProcessorInvocation"]; + "application/json": components["schemas"]["BooleanInvocation"] | components["schemas"]["BooleanCollectionInvocation"] | components["schemas"]["IntegerInvocation"] | components["schemas"]["IntegerCollectionInvocation"] | components["schemas"]["FloatInvocation"] | components["schemas"]["FloatCollectionInvocation"] | components["schemas"]["StringInvocation"] | components["schemas"]["StringCollectionInvocation"] | components["schemas"]["ImageInvocation"] | components["schemas"]["ImageCollectionInvocation"] | components["schemas"]["LatentsInvocation"] | components["schemas"]["LatentsCollectionInvocation"] | components["schemas"]["ColorInvocation"] | components["schemas"]["ConditioningInvocation"] | components["schemas"]["ConditioningCollectionInvocation"] | components["schemas"]["ControlNetInvocation"] | components["schemas"]["ImageProcessorInvocation"] | components["schemas"]["MainModelLoaderInvocation"] | components["schemas"]["LoraLoaderInvocation"] | components["schemas"]["SDXLLoraLoaderInvocation"] | components["schemas"]["VaeLoaderInvocation"] | components["schemas"]["SeamlessModeInvocation"] | components["schemas"]["MetadataAccumulatorInvocation"] | components["schemas"]["RangeInvocation"] | components["schemas"]["RangeOfSizeInvocation"] | components["schemas"]["RandomRangeInvocation"] | components["schemas"]["CompelInvocation"] | components["schemas"]["SDXLCompelPromptInvocation"] | components["schemas"]["SDXLRefinerCompelPromptInvocation"] | components["schemas"]["ClipSkipInvocation"] | components["schemas"]["CvInpaintInvocation"] | components["schemas"]["ShowImageInvocation"] | components["schemas"]["BlankImageInvocation"] | components["schemas"]["ImageCropInvocation"] | components["schemas"]["ImagePasteInvocation"] | components["schemas"]["MaskFromAlphaInvocation"] | components["schemas"]["ImageMultiplyInvocation"] | components["schemas"]["ImageChannelInvocation"] | components["schemas"]["ImageConvertInvocation"] | components["schemas"]["ImageBlurInvocation"] | components["schemas"]["ImageResizeInvocation"] | components["schemas"]["ImageScaleInvocation"] | components["schemas"]["ImageLerpInvocation"] | components["schemas"]["ImageInverseLerpInvocation"] | components["schemas"]["ImageNSFWBlurInvocation"] | components["schemas"]["ImageWatermarkInvocation"] | components["schemas"]["MaskEdgeInvocation"] | components["schemas"]["MaskCombineInvocation"] | components["schemas"]["ColorCorrectInvocation"] | components["schemas"]["ImageHueAdjustmentInvocation"] | components["schemas"]["ImageChannelOffsetInvocation"] | components["schemas"]["ImageChannelMultiplyInvocation"] | components["schemas"]["InfillColorInvocation"] | components["schemas"]["InfillTileInvocation"] | components["schemas"]["InfillPatchMatchInvocation"] | components["schemas"]["LaMaInfillInvocation"] | components["schemas"]["CV2InfillInvocation"] | components["schemas"]["SchedulerInvocation"] | components["schemas"]["CreateDenoiseMaskInvocation"] | components["schemas"]["DenoiseLatentsInvocation"] | components["schemas"]["LatentsToImageInvocation"] | components["schemas"]["ResizeLatentsInvocation"] | components["schemas"]["ScaleLatentsInvocation"] | components["schemas"]["ImageToLatentsInvocation"] | components["schemas"]["BlendLatentsInvocation"] | components["schemas"]["AddInvocation"] | components["schemas"]["SubtractInvocation"] | components["schemas"]["MultiplyInvocation"] | components["schemas"]["DivideInvocation"] | components["schemas"]["RandomIntInvocation"] | components["schemas"]["NoiseInvocation"] | components["schemas"]["ONNXPromptInvocation"] | components["schemas"]["ONNXTextToLatentsInvocation"] | components["schemas"]["ONNXLatentsToImageInvocation"] | components["schemas"]["OnnxModelLoaderInvocation"] | components["schemas"]["FloatLinearRangeInvocation"] | components["schemas"]["StepParamEasingInvocation"] | components["schemas"]["DynamicPromptInvocation"] | components["schemas"]["PromptsFromFileInvocation"] | components["schemas"]["SDXLModelLoaderInvocation"] | components["schemas"]["SDXLRefinerModelLoaderInvocation"] | components["schemas"]["ESRGANInvocation"] | components["schemas"]["GraphInvocation"] | components["schemas"]["IterateInvocation"] | components["schemas"]["CollectInvocation"] | components["schemas"]["CannyImageProcessorInvocation"] | components["schemas"]["HedImageProcessorInvocation"] | components["schemas"]["LineartImageProcessorInvocation"] | components["schemas"]["LineartAnimeImageProcessorInvocation"] | components["schemas"]["OpenposeImageProcessorInvocation"] | components["schemas"]["MidasDepthImageProcessorInvocation"] | components["schemas"]["NormalbaeImageProcessorInvocation"] | components["schemas"]["MlsdImageProcessorInvocation"] | components["schemas"]["PidiImageProcessorInvocation"] | components["schemas"]["ContentShuffleImageProcessorInvocation"] | components["schemas"]["ZoeDepthImageProcessorInvocation"] | components["schemas"]["MediapipeFaceProcessorInvocation"] | components["schemas"]["LeresImageProcessorInvocation"] | components["schemas"]["TileResamplerProcessorInvocation"] | components["schemas"]["SegmentAnythingProcessorInvocation"]; }; }; responses: { From 8b305651f9e2fd813380d3f450724f8dd2f93474 Mon Sep 17 00:00:00 2001 From: psychedelicious <4822129+psychedelicious@users.noreply.github.com> Date: Tue, 5 Sep 2023 12:44:39 +1000 Subject: [PATCH 26/26] fix(ui): fix non-nodes validation logic being applied to nodes invoke button --- .../src/common/hooks/useIsReadyToInvoke.ts | 80 ++++++++++--------- 1 file changed, 41 insertions(+), 39 deletions(-) diff --git a/invokeai/frontend/web/src/common/hooks/useIsReadyToInvoke.ts b/invokeai/frontend/web/src/common/hooks/useIsReadyToInvoke.ts index 3820b07daf..8eaabeeedf 100644 --- a/invokeai/frontend/web/src/common/hooks/useIsReadyToInvoke.ts +++ b/invokeai/frontend/web/src/common/hooks/useIsReadyToInvoke.ts @@ -31,52 +31,54 @@ const selector = createSelector( reasons.push('No initial image selected'); } - if (activeTabName === 'nodes' && nodes.shouldValidateGraph) { - if (!nodes.nodes.length) { - reasons.push('No nodes in graph'); - } - - nodes.nodes.forEach((node) => { - if (!isInvocationNode(node)) { - return; + if (activeTabName === 'nodes') { + if (nodes.shouldValidateGraph) { + if (!nodes.nodes.length) { + reasons.push('No nodes in graph'); } - const nodeTemplate = nodes.nodeTemplates[node.data.type]; - - if (!nodeTemplate) { - // Node type not found - reasons.push('Missing node template'); - return; - } - - const connectedEdges = getConnectedEdges([node], nodes.edges); - - forEach(node.data.inputs, (field) => { - const fieldTemplate = nodeTemplate.inputs[field.name]; - const hasConnection = connectedEdges.some( - (edge) => - edge.target === node.id && edge.targetHandle === field.name - ); - - if (!fieldTemplate) { - reasons.push('Missing field template'); + nodes.nodes.forEach((node) => { + if (!isInvocationNode(node)) { return; } - if ( - fieldTemplate.required && - field.value === undefined && - !hasConnection - ) { - reasons.push( - `${node.data.label || nodeTemplate.title} -> ${ - field.label || fieldTemplate.title - } missing input` + const nodeTemplate = nodes.nodeTemplates[node.data.type]; + + if (!nodeTemplate) { + // Node type not found + reasons.push('Missing node template'); + return; + } + + const connectedEdges = getConnectedEdges([node], nodes.edges); + + forEach(node.data.inputs, (field) => { + const fieldTemplate = nodeTemplate.inputs[field.name]; + const hasConnection = connectedEdges.some( + (edge) => + edge.target === node.id && edge.targetHandle === field.name ); - return; - } + + if (!fieldTemplate) { + reasons.push('Missing field template'); + return; + } + + if ( + fieldTemplate.required && + field.value === undefined && + !hasConnection + ) { + reasons.push( + `${node.data.label || nodeTemplate.title} -> ${ + field.label || fieldTemplate.title + } missing input` + ); + return; + } + }); }); - }); + } } else { if (!model) { reasons.push('No model selected');