From 7cdda00a5493aea09083006b627c1b8285bd40d8 Mon Sep 17 00:00:00 2001 From: psychedelicious <4822129+psychedelicious@users.noreply.github.com> Date: Tue, 29 Oct 2024 09:00:15 +1000 Subject: [PATCH] feat(ui): rearrange canvas paste back nodes to save an image step We were scaling the unscaled image and mask down before doing the paste-back, but this adds an extraneous step & image output. We can do the paste-back first, then scale to output size after. So instead of 2 resizes before the paste-back, we have 1 resize after. The end result is the same. --- .../nodes/util/graph/generation/addInpaint.ts | 30 +++++++----------- .../util/graph/generation/addOutpaint.ts | 31 +++++++------------ 2 files changed, 24 insertions(+), 37 deletions(-) diff --git a/invokeai/frontend/web/src/features/nodes/util/graph/generation/addInpaint.ts b/invokeai/frontend/web/src/features/nodes/util/graph/generation/addInpaint.ts index a171b56ed4..3772c069f2 100644 --- a/invokeai/frontend/web/src/features/nodes/util/graph/generation/addInpaint.ts +++ b/invokeai/frontend/web/src/features/nodes/util/graph/generation/addInpaint.ts @@ -69,16 +69,6 @@ export const addInpaint = async ({ type: 'img_resize', ...scaledSize, }); - const resizeImageToOriginalSize = g.addNode({ - id: getPrefixedId('resize_image_to_original_size'), - type: 'img_resize', - ...originalSize, - }); - const resizeMaskToOriginalSize = g.addNode({ - id: getPrefixedId('resize_mask_to_original_size'), - type: 'img_resize', - ...originalSize, - }); const createGradientMask = g.addNode({ id: getPrefixedId('create_gradient_mask'), type: 'create_gradient_mask', @@ -92,6 +82,11 @@ export const addInpaint = async ({ type: 'canvas_v2_mask_and_crop', mask_blur: params.maskBlur, }); + const resizeOutput = g.addNode({ + id: getPrefixedId('resize_output'), + type: 'img_resize', + ...originalSize, + }); // Resize initial image and mask to scaled size, feed into to gradient mask g.addEdge(alphaToMask, 'image', resizeMaskToScaledSize, 'image'); @@ -108,21 +103,20 @@ export const addInpaint = async ({ g.addEdge(createGradientMask, 'denoise_mask', denoise, 'denoise_mask'); - // After denoising, resize the image and mask back to original size - g.addEdge(l2i, 'image', resizeImageToOriginalSize, 'image'); - g.addEdge(createGradientMask, 'expanded_mask_area', resizeMaskToOriginalSize, 'image'); + // Paste the generated masked image back onto the original image + g.addEdge(l2i, 'image', canvasPasteBack, 'generated_image'); + g.addEdge(createGradientMask, 'expanded_mask_area', canvasPasteBack, 'mask'); - // Finally, paste the generated masked image back onto the original image - g.addEdge(resizeImageToOriginalSize, 'image', canvasPasteBack, 'generated_image'); - g.addEdge(resizeMaskToOriginalSize, 'image', canvasPasteBack, 'mask'); + // Finally, resize the output back to the original size + g.addEdge(canvasPasteBack, 'image', resizeOutput, 'image'); // Do the paste back if we are sending to gallery (in which case we want to see the full image), or if we are sending // to canvas but not outputting only masked regions if (!canvasSettings.sendToCanvas || !canvasSettings.outputOnlyMaskedRegions) { - canvasPasteBack.source_image = { image_name: initialImage.image_name }; + g.addEdge(resizeImageToScaledSize, 'image', canvasPasteBack, 'source_image'); } - return canvasPasteBack; + return resizeOutput; } else { // No scale before processing, much simpler const i2l = addImageToLatents(g, modelLoader.type === 'flux_model_loader', fp32, initialImage.image_name); diff --git a/invokeai/frontend/web/src/features/nodes/util/graph/generation/addOutpaint.ts b/invokeai/frontend/web/src/features/nodes/util/graph/generation/addOutpaint.ts index e566e6e1b8..80ec9edd84 100644 --- a/invokeai/frontend/web/src/features/nodes/util/graph/generation/addOutpaint.ts +++ b/invokeai/frontend/web/src/features/nodes/util/graph/generation/addOutpaint.ts @@ -112,40 +112,33 @@ export const addOutpaint = async ({ g.addEdge(vaeSource, 'vae', i2l, 'vae'); g.addEdge(i2l, 'latents', denoise, 'latents'); - // Resize the output image back to the original size - const resizeOutputImageToOriginalSize = g.addNode({ - id: getPrefixedId('resize_image_to_original_size'), - type: 'img_resize', - ...originalSize, - }); - const resizeOutputMaskToOriginalSize = g.addNode({ - id: getPrefixedId('resize_mask_to_original_size'), - type: 'img_resize', - ...originalSize, - }); const canvasPasteBack = g.addNode({ id: getPrefixedId('canvas_v2_mask_and_crop'), type: 'canvas_v2_mask_and_crop', mask_blur: params.maskBlur, }); + const resizeOutput = g.addNode({ + id: getPrefixedId('resize_output'), + type: 'img_resize', + ...originalSize, + }); // Resize initial image and mask to scaled size, feed into to gradient mask - // After denoising, resize the image and mask back to original size - g.addEdge(l2i, 'image', resizeOutputImageToOriginalSize, 'image'); - g.addEdge(createGradientMask, 'expanded_mask_area', resizeOutputMaskToOriginalSize, 'image'); + // Paste the generated masked image back onto the original image + g.addEdge(l2i, 'image', canvasPasteBack, 'generated_image'); + g.addEdge(createGradientMask, 'expanded_mask_area', canvasPasteBack, 'mask'); - // Finally, paste the generated masked image back onto the original image - g.addEdge(resizeOutputImageToOriginalSize, 'image', canvasPasteBack, 'generated_image'); - g.addEdge(resizeOutputMaskToOriginalSize, 'image', canvasPasteBack, 'mask'); + // Finally, resize the output back to the original size + g.addEdge(canvasPasteBack, 'image', resizeOutput, 'image'); // Do the paste back if we are sending to gallery (in which case we want to see the full image), or if we are sending // to canvas but not outputting only masked regions if (!canvasSettings.sendToCanvas || !canvasSettings.outputOnlyMaskedRegions) { - canvasPasteBack.source_image = { image_name: initialImage.image_name }; + g.addEdge(resizeInputImageToScaledSize, 'image', canvasPasteBack, 'source_image'); } - return canvasPasteBack; + return resizeOutput; } else { infill.image = { image_name: initialImage.image_name }; // No scale before processing, much simpler