canvas: improve paste back (or try to)

This commit is contained in:
blessedcoolant 2024-02-22 10:23:18 +05:30 committed by psychedelicious
parent 8f6c2a8b92
commit 68d79c002d
7 changed files with 208 additions and 122 deletions

View File

@ -17,16 +17,12 @@ from invokeai.app.invocations.fields import (
WithMetadata, WithMetadata,
) )
from invokeai.app.invocations.primitives import ImageOutput from invokeai.app.invocations.primitives import ImageOutput
from invokeai.app.services.image_records.image_records_common import ImageCategory from invokeai.app.services.image_records.image_records_common import ImageCategory, ResourceOrigin
from invokeai.app.services.shared.invocation_context import InvocationContext from invokeai.app.services.shared.invocation_context import InvocationContext
from invokeai.backend.image_util.invisible_watermark import InvisibleWatermark from invokeai.backend.image_util.invisible_watermark import InvisibleWatermark
from invokeai.backend.image_util.safety_checker import SafetyChecker from invokeai.backend.image_util.safety_checker import SafetyChecker
from .baseinvocation import ( from .baseinvocation import BaseInvocation, Classification, invocation
BaseInvocation,
Classification,
invocation,
)
@invocation("show_image", title="Show Image", tags=["image"], category="image", version="1.0.1") @invocation("show_image", title="Show Image", tags=["image"], category="image", version="1.0.1")
@ -934,3 +930,42 @@ class SaveImageInvocation(BaseInvocation, WithMetadata, WithBoard):
image_dto = context.images.save(image=image) image_dto = context.images.save(image=image)
return ImageOutput.build(image_dto) return ImageOutput.build(image_dto)
@invocation(
"iai_canvas_paste_back",
title="InvokeAI Canvas Paste Back",
tags=["image", "combine"],
category="image",
version="1.0.0",
)
class IAICanvasPasteBackInvocation(BaseInvocation, WithMetadata, WithBoard):
"""Combines two images by using the mask provided"""
source_image: ImageField = InputField(description="The source image")
target_image: ImageField = InputField(default=None, description="The target image")
mask: ImageField = InputField(
description="The mask to use when pasting",
)
mask_blur: int = InputField(default=0, ge=0, description="The amount to blur the mask by")
def _prepare_mask(self, mask: Image.Image):
mask_array = numpy.array(mask)
kernel = numpy.ones((self.mask_blur, self.mask_blur), numpy.uint8)
dilated_mask_array = cv2.erode(mask_array, kernel, iterations=3)
dilated_mask = Image.fromarray(dilated_mask_array)
if self.mask_blur > 0:
mask = dilated_mask.filter(ImageFilter.GaussianBlur(self.mask_blur))
return ImageOps.invert(mask.convert("L"))
def invoke(self, context: InvocationContext) -> ImageOutput:
source_image = context.images.get_pil(self.source_image.image_name)
target_image = context.images.get_pil(self.target_image.image_name)
mask = self._prepare_mask(context.images.get_pil(self.mask.image_name))
# Merge the bands back together
source_image.paste(target_image, (0, 0), mask)
image_dto = context.images.save(image=source_image)
return ImageOutput.build(image_dto)

View File

@ -1,7 +1,13 @@
import { logger } from 'app/logging/logger'; import { logger } from 'app/logging/logger';
import type { RootState } from 'app/store/store'; import type { RootState } from 'app/store/store';
import { getBoardField, getIsIntermediate } from 'features/nodes/util/graph/graphBuilderUtils'; import type {
import type { ImageDTO, ImageToLatentsInvocation, NoiseInvocation, NonNullableGraph } from 'services/api/types'; CreateGradientMaskInvocation,
IAICanvasPasteBackInvocation,
ImageDTO,
ImageToLatentsInvocation,
NoiseInvocation,
NonNullableGraph,
} from 'services/api/types';
import { addControlNetToLinearGraph } from './addControlNetToLinearGraph'; import { addControlNetToLinearGraph } from './addControlNetToLinearGraph';
import { addIPAdapterToLinearGraph } from './addIPAdapterToLinearGraph'; import { addIPAdapterToLinearGraph } from './addIPAdapterToLinearGraph';
@ -29,6 +35,7 @@ import {
POSITIVE_CONDITIONING, POSITIVE_CONDITIONING,
SEAMLESS, SEAMLESS,
} from './constants'; } from './constants';
import { getBoardField, getIsIntermediate } from './graphBuilderUtils';
/** /**
* Builds the Canvas tab's Inpaint graph. * Builds the Canvas tab's Inpaint graph.
@ -61,8 +68,8 @@ export const buildCanvasInpaintGraph = (
} = state.generation; } = state.generation;
if (!model) { if (!model) {
log.error('No Image found in state'); log.error('No model found in state');
throw new Error('No Image found in state'); throw new Error('No model found in state');
} }
// The bounding box determines width and height, not the width and height params // The bounding box determines width and height, not the width and height params
@ -106,7 +113,6 @@ export const buildCanvasInpaintGraph = (
is_intermediate, is_intermediate,
prompt: negativePrompt, prompt: negativePrompt,
}, },
[INPAINT_IMAGE]: { [INPAINT_IMAGE]: {
type: 'i2l', type: 'i2l',
id: INPAINT_IMAGE, id: INPAINT_IMAGE,
@ -146,12 +152,12 @@ export const buildCanvasInpaintGraph = (
fp32, fp32,
}, },
[CANVAS_OUTPUT]: { [CANVAS_OUTPUT]: {
type: 'color_correct', type: 'iai_canvas_paste_back',
id: CANVAS_OUTPUT, id: CANVAS_OUTPUT,
is_intermediate: getIsIntermediate(state), is_intermediate: getIsIntermediate(state),
board: getBoardField(state), board: getBoardField(state),
reference: canvasInitImage, mask_blur: canvasCoherenceEdgeSize,
use_cache: false, source_image: canvasInitImage,
}, },
}, },
edges: [ edges: [
@ -325,7 +331,7 @@ export const buildCanvasInpaintGraph = (
field: 'mask', field: 'mask',
}, },
}, },
// Color Correct The Inpainted Result // Resize Down
{ {
source: { source: {
node_id: LATENTS_TO_IMAGE, node_id: LATENTS_TO_IMAGE,
@ -336,16 +342,6 @@ export const buildCanvasInpaintGraph = (
field: 'image', field: 'image',
}, },
}, },
{
source: {
node_id: INPAINT_IMAGE_RESIZE_DOWN,
field: 'image',
},
destination: {
node_id: CANVAS_OUTPUT,
field: 'image',
},
},
{ {
source: { source: {
node_id: MASK_RESIZE_UP, node_id: MASK_RESIZE_UP,
@ -356,6 +352,17 @@ export const buildCanvasInpaintGraph = (
field: 'image', field: 'image',
}, },
}, },
// Paste Back
{
source: {
node_id: INPAINT_IMAGE_RESIZE_DOWN,
field: 'image',
},
destination: {
node_id: CANVAS_OUTPUT,
field: 'target_image',
},
},
{ {
source: { source: {
node_id: MASK_RESIZE_DOWN, node_id: MASK_RESIZE_DOWN,
@ -377,29 +384,27 @@ export const buildCanvasInpaintGraph = (
image: canvasInitImage, image: canvasInitImage,
}; };
graph.edges.push( graph.nodes[INPAINT_CREATE_MASK] = {
// Color Correct The Inpainted Result ...(graph.nodes[INPAINT_CREATE_MASK] as CreateGradientMaskInvocation),
{ mask: canvasMaskImage,
source: { };
node_id: LATENTS_TO_IMAGE,
field: 'image', // Paste Back
}, graph.nodes[CANVAS_OUTPUT] = {
destination: { ...(graph.nodes[CANVAS_OUTPUT] as IAICanvasPasteBackInvocation),
node_id: CANVAS_OUTPUT, mask: canvasMaskImage,
field: 'image', };
},
graph.edges.push({
source: {
node_id: LATENTS_TO_IMAGE,
field: 'image',
}, },
{ destination: {
source: { node_id: CANVAS_OUTPUT,
node_id: MASK_RESIZE_DOWN, field: 'target_image',
field: 'image', },
}, });
destination: {
node_id: CANVAS_OUTPUT,
field: 'mask',
},
}
);
} }
// Add Seamless To Graph // Add Seamless To Graph

View File

@ -1,6 +1,5 @@
import { logger } from 'app/logging/logger'; import { logger } from 'app/logging/logger';
import type { RootState } from 'app/store/store'; import type { RootState } from 'app/store/store';
import { getBoardField, getIsIntermediate } from 'features/nodes/util/graph/graphBuilderUtils';
import type { import type {
ImageDTO, ImageDTO,
ImageToLatentsInvocation, ImageToLatentsInvocation,
@ -40,6 +39,7 @@ import {
POSITIVE_CONDITIONING, POSITIVE_CONDITIONING,
SEAMLESS, SEAMLESS,
} from './constants'; } from './constants';
import { getBoardField, getIsIntermediate } from './graphBuilderUtils';
/** /**
* Builds the Canvas tab's Outpaint graph. * Builds the Canvas tab's Outpaint graph.
@ -149,8 +149,8 @@ export const buildCanvasOutpaintGraph = (
id: INPAINT_CREATE_MASK, id: INPAINT_CREATE_MASK,
is_intermediate, is_intermediate,
coherence_mode: canvasCoherenceMode, coherence_mode: canvasCoherenceMode,
minimum_denoise: canvasCoherenceMinDenoise,
edge_radius: canvasCoherenceEdgeSize, edge_radius: canvasCoherenceEdgeSize,
minimum_denoise: canvasCoherenceMinDenoise,
}, },
[DENOISE_LATENTS]: { [DENOISE_LATENTS]: {
type: 'denoise_latents', type: 'denoise_latents',
@ -171,7 +171,7 @@ export const buildCanvasOutpaintGraph = (
fp32, fp32,
}, },
[CANVAS_OUTPUT]: { [CANVAS_OUTPUT]: {
type: 'color_correct', type: 'iai_canvas_paste_back',
id: CANVAS_OUTPUT, id: CANVAS_OUTPUT,
is_intermediate: getIsIntermediate(state), is_intermediate: getIsIntermediate(state),
board: getBoardField(state), board: getBoardField(state),
@ -455,7 +455,7 @@ export const buildCanvasOutpaintGraph = (
field: 'image', field: 'image',
}, },
}, },
// Color Correct The Inpainted Result // Paste Back
{ {
source: { source: {
node_id: INPAINT_INFILL_RESIZE_DOWN, node_id: INPAINT_INFILL_RESIZE_DOWN,
@ -463,17 +463,17 @@ export const buildCanvasOutpaintGraph = (
}, },
destination: { destination: {
node_id: CANVAS_OUTPUT, node_id: CANVAS_OUTPUT,
field: 'reference', field: 'source_image',
}, },
}, },
{ {
source: { source: {
node_id: INPAINT_IMAGE_RESIZE_DOWN, node_id: LATENTS_TO_IMAGE,
field: 'image', field: 'image',
}, },
destination: { destination: {
node_id: CANVAS_OUTPUT, node_id: CANVAS_OUTPUT,
field: 'image', field: 'target_image',
}, },
}, },
{ {
@ -503,7 +503,6 @@ export const buildCanvasOutpaintGraph = (
}; };
graph.edges.push( graph.edges.push(
// Color Correct The Inpainted Result
{ {
source: { source: {
node_id: INPAINT_INFILL, node_id: INPAINT_INFILL,
@ -511,7 +510,7 @@ export const buildCanvasOutpaintGraph = (
}, },
destination: { destination: {
node_id: CANVAS_OUTPUT, node_id: CANVAS_OUTPUT,
field: 'reference', field: 'source_image',
}, },
}, },
{ {
@ -521,7 +520,7 @@ export const buildCanvasOutpaintGraph = (
}, },
destination: { destination: {
node_id: CANVAS_OUTPUT, node_id: CANVAS_OUTPUT,
field: 'image', field: 'target_image',
}, },
}, },
{ {

View File

@ -1,7 +1,8 @@
import { logger } from 'app/logging/logger'; import { logger } from 'app/logging/logger';
import type { RootState } from 'app/store/store'; import type { RootState } from 'app/store/store';
import type { import type {
CreateDenoiseMaskInvocation, CreateGradientMaskInvocation,
IAICanvasPasteBackInvocation,
ImageDTO, ImageDTO,
ImageToLatentsInvocation, ImageToLatentsInvocation,
NoiseInvocation, NoiseInvocation,
@ -54,15 +55,15 @@ export const buildCanvasSDXLInpaintGraph = (
cfgRescaleMultiplier: cfg_rescale_multiplier, cfgRescaleMultiplier: cfg_rescale_multiplier,
scheduler, scheduler,
steps, steps,
img2imgStrength: strength,
seed, seed,
vaePrecision, vaePrecision,
shouldUseCpuNoise, shouldUseCpuNoise,
seamlessXAxis,
seamlessYAxis,
canvasCoherenceMode, canvasCoherenceMode,
canvasCoherenceMinDenoise, canvasCoherenceMinDenoise,
canvasCoherenceEdgeSize, canvasCoherenceEdgeSize,
seamlessXAxis,
seamlessYAxis,
img2imgStrength: strength,
} = state.generation; } = state.generation;
const { refinerModel, refinerStart } = state.sdxl; const { refinerModel, refinerStart } = state.sdxl;
@ -78,8 +79,9 @@ export const buildCanvasSDXLInpaintGraph = (
// We may need to set the inpaint width and height to scale the image // We may need to set the inpaint width and height to scale the image
const { scaledBoundingBoxDimensions, boundingBoxScaleMethod } = state.canvas; const { scaledBoundingBoxDimensions, boundingBoxScaleMethod } = state.canvas;
const fp32 = vaePrecision === 'fp32';
const is_intermediate = true; const is_intermediate = true;
const fp32 = vaePrecision === 'fp32';
const isUsingScaledDimensions = ['auto', 'manual'].includes(boundingBoxScaleMethod); const isUsingScaledDimensions = ['auto', 'manual'].includes(boundingBoxScaleMethod);
let modelLoaderNodeId = SDXL_MODEL_LOADER; let modelLoaderNodeId = SDXL_MODEL_LOADER;
@ -95,17 +97,20 @@ export const buildCanvasSDXLInpaintGraph = (
[modelLoaderNodeId]: { [modelLoaderNodeId]: {
type: 'sdxl_model_loader', type: 'sdxl_model_loader',
id: modelLoaderNodeId, id: modelLoaderNodeId,
is_intermediate,
model, model,
}, },
[POSITIVE_CONDITIONING]: { [POSITIVE_CONDITIONING]: {
type: 'sdxl_compel_prompt', type: 'sdxl_compel_prompt',
id: POSITIVE_CONDITIONING, id: POSITIVE_CONDITIONING,
is_intermediate,
prompt: positivePrompt, prompt: positivePrompt,
style: positiveStylePrompt, style: positiveStylePrompt,
}, },
[NEGATIVE_CONDITIONING]: { [NEGATIVE_CONDITIONING]: {
type: 'sdxl_compel_prompt', type: 'sdxl_compel_prompt',
id: NEGATIVE_CONDITIONING, id: NEGATIVE_CONDITIONING,
is_intermediate,
prompt: negativePrompt, prompt: negativePrompt,
style: negativeStylePrompt, style: negativeStylePrompt,
}, },
@ -148,12 +153,12 @@ export const buildCanvasSDXLInpaintGraph = (
fp32, fp32,
}, },
[CANVAS_OUTPUT]: { [CANVAS_OUTPUT]: {
type: 'color_correct', type: 'iai_canvas_paste_back',
id: CANVAS_OUTPUT, id: CANVAS_OUTPUT,
is_intermediate: getIsIntermediate(state), is_intermediate: getIsIntermediate(state),
board: getBoardField(state), board: getBoardField(state),
reference: canvasInitImage, mask_blur: canvasCoherenceEdgeSize,
use_cache: false, source_image: canvasInitImage,
}, },
}, },
edges: [ edges: [
@ -208,7 +213,7 @@ export const buildCanvasSDXLInpaintGraph = (
field: 'clip2', field: 'clip2',
}, },
}, },
// Connect everything to Inpaint // Connect Everything To Inpaint Node
{ {
source: { source: {
node_id: POSITIVE_CONDITIONING, node_id: POSITIVE_CONDITIONING,
@ -336,7 +341,7 @@ export const buildCanvasSDXLInpaintGraph = (
field: 'mask', field: 'mask',
}, },
}, },
// Color Correct The Inpainted Result // Resize Down
{ {
source: { source: {
node_id: LATENTS_TO_IMAGE, node_id: LATENTS_TO_IMAGE,
@ -347,16 +352,6 @@ export const buildCanvasSDXLInpaintGraph = (
field: 'image', field: 'image',
}, },
}, },
{
source: {
node_id: INPAINT_IMAGE_RESIZE_DOWN,
field: 'image',
},
destination: {
node_id: CANVAS_OUTPUT,
field: 'image',
},
},
{ {
source: { source: {
node_id: MASK_RESIZE_UP, node_id: MASK_RESIZE_UP,
@ -367,6 +362,17 @@ export const buildCanvasSDXLInpaintGraph = (
field: 'image', field: 'image',
}, },
}, },
// Paste Back
{
source: {
node_id: INPAINT_IMAGE_RESIZE_DOWN,
field: 'image',
},
destination: {
node_id: CANVAS_OUTPUT,
field: 'target_image',
},
},
{ {
source: { source: {
node_id: MASK_RESIZE_DOWN, node_id: MASK_RESIZE_DOWN,
@ -387,34 +393,28 @@ export const buildCanvasSDXLInpaintGraph = (
...(graph.nodes[INPAINT_IMAGE] as ImageToLatentsInvocation), ...(graph.nodes[INPAINT_IMAGE] as ImageToLatentsInvocation),
image: canvasInitImage, image: canvasInitImage,
}; };
graph.nodes[INPAINT_CREATE_MASK] = { graph.nodes[INPAINT_CREATE_MASK] = {
...(graph.nodes[INPAINT_CREATE_MASK] as CreateDenoiseMaskInvocation), ...(graph.nodes[INPAINT_CREATE_MASK] as CreateGradientMaskInvocation),
image: canvasInitImage, mask: canvasMaskImage,
}; };
graph.edges.push( // Paste Back
// Color Correct The Inpainted Result graph.nodes[CANVAS_OUTPUT] = {
{ ...(graph.nodes[CANVAS_OUTPUT] as IAICanvasPasteBackInvocation),
source: { mask: canvasMaskImage,
node_id: LATENTS_TO_IMAGE, };
field: 'image',
}, graph.edges.push({
destination: { source: {
node_id: CANVAS_OUTPUT, node_id: LATENTS_TO_IMAGE,
field: 'image', field: 'image',
},
}, },
{ destination: {
source: { node_id: CANVAS_OUTPUT,
node_id: MASK_RESIZE_DOWN, field: 'target_image',
field: 'image', },
}, });
destination: {
node_id: CANVAS_OUTPUT,
field: 'mask',
},
}
);
} }
// Add Seamless To Graph // Add Seamless To Graph
@ -431,7 +431,7 @@ export const buildCanvasSDXLInpaintGraph = (
} }
} }
// optionally add custom VAE // Add VAE
addVAEToGraph(state, graph, modelLoaderNodeId); addVAEToGraph(state, graph, modelLoaderNodeId);
// add LoRA support // add LoRA support

View File

@ -59,18 +59,18 @@ export const buildCanvasSDXLOutpaintGraph = (
cfgRescaleMultiplier: cfg_rescale_multiplier, cfgRescaleMultiplier: cfg_rescale_multiplier,
scheduler, scheduler,
steps, steps,
img2imgStrength: strength,
seed, seed,
vaePrecision, vaePrecision,
shouldUseCpuNoise, shouldUseCpuNoise,
canvasCoherenceMode,
canvasCoherenceMinDenoise,
canvasCoherenceEdgeSize,
infillTileSize, infillTileSize,
infillPatchmatchDownscaleSize, infillPatchmatchDownscaleSize,
infillMethod, infillMethod,
seamlessXAxis, seamlessXAxis,
seamlessYAxis, seamlessYAxis,
img2imgStrength: strength, canvasCoherenceMode,
canvasCoherenceMinDenoise,
canvasCoherenceEdgeSize,
} = state.generation; } = state.generation;
const { refinerModel, refinerStart } = state.sdxl; const { refinerModel, refinerStart } = state.sdxl;
@ -108,12 +108,14 @@ export const buildCanvasSDXLOutpaintGraph = (
[POSITIVE_CONDITIONING]: { [POSITIVE_CONDITIONING]: {
type: 'sdxl_compel_prompt', type: 'sdxl_compel_prompt',
id: POSITIVE_CONDITIONING, id: POSITIVE_CONDITIONING,
is_intermediate,
prompt: positivePrompt, prompt: positivePrompt,
style: positiveStylePrompt, style: positiveStylePrompt,
}, },
[NEGATIVE_CONDITIONING]: { [NEGATIVE_CONDITIONING]: {
type: 'sdxl_compel_prompt', type: 'sdxl_compel_prompt',
id: NEGATIVE_CONDITIONING, id: NEGATIVE_CONDITIONING,
is_intermediate,
prompt: negativePrompt, prompt: negativePrompt,
style: negativeStylePrompt, style: negativeStylePrompt,
}, },
@ -161,6 +163,7 @@ export const buildCanvasSDXLOutpaintGraph = (
denoising_start: refinerModel ? Math.min(refinerStart, 1 - strength) : 1 - strength, denoising_start: refinerModel ? Math.min(refinerStart, 1 - strength) : 1 - strength,
denoising_end: refinerModel ? refinerStart : 1, denoising_end: refinerModel ? refinerStart : 1,
}, },
[LATENTS_TO_IMAGE]: { [LATENTS_TO_IMAGE]: {
type: 'l2i', type: 'l2i',
id: LATENTS_TO_IMAGE, id: LATENTS_TO_IMAGE,
@ -168,7 +171,7 @@ export const buildCanvasSDXLOutpaintGraph = (
fp32, fp32,
}, },
[CANVAS_OUTPUT]: { [CANVAS_OUTPUT]: {
type: 'color_correct', type: 'iai_canvas_paste_back',
id: CANVAS_OUTPUT, id: CANVAS_OUTPUT,
is_intermediate: getIsIntermediate(state), is_intermediate: getIsIntermediate(state),
board: getBoardField(state), board: getBoardField(state),
@ -249,7 +252,7 @@ export const buildCanvasSDXLOutpaintGraph = (
field: 'mask1', field: 'mask1',
}, },
}, },
// Connect Everything To Inpaint // Plug Everything Into Inpaint Node
{ {
source: { source: {
node_id: POSITIVE_CONDITIONING, node_id: POSITIVE_CONDITIONING,
@ -311,7 +314,7 @@ export const buildCanvasSDXLOutpaintGraph = (
field: 'denoise_mask', field: 'denoise_mask',
}, },
}, },
// Decode inpainted latents to image
{ {
source: { source: {
node_id: SDXL_DENOISE_LATENTS, node_id: SDXL_DENOISE_LATENTS,
@ -419,8 +422,7 @@ export const buildCanvasSDXLOutpaintGraph = (
field: 'image', field: 'image',
}, },
}, },
// Take combined mask and resize
// Take combined mask and resize and then blur
{ {
source: { source: {
node_id: MASK_COMBINE, node_id: MASK_COMBINE,
@ -431,7 +433,6 @@ export const buildCanvasSDXLOutpaintGraph = (
field: 'image', field: 'image',
}, },
}, },
// Resize Results Down // Resize Results Down
{ {
source: { source: {
@ -463,7 +464,7 @@ export const buildCanvasSDXLOutpaintGraph = (
field: 'image', field: 'image',
}, },
}, },
// Color Correct The Inpainted Result // Paste Back
{ {
source: { source: {
node_id: INPAINT_INFILL_RESIZE_DOWN, node_id: INPAINT_INFILL_RESIZE_DOWN,
@ -471,17 +472,17 @@ export const buildCanvasSDXLOutpaintGraph = (
}, },
destination: { destination: {
node_id: CANVAS_OUTPUT, node_id: CANVAS_OUTPUT,
field: 'reference', field: 'source_image',
}, },
}, },
{ {
source: { source: {
node_id: INPAINT_IMAGE_RESIZE_DOWN, node_id: LATENTS_TO_IMAGE,
field: 'image', field: 'image',
}, },
destination: { destination: {
node_id: CANVAS_OUTPUT, node_id: CANVAS_OUTPUT,
field: 'image', field: 'target_image',
}, },
}, },
{ {
@ -511,7 +512,6 @@ export const buildCanvasSDXLOutpaintGraph = (
}; };
graph.edges.push( graph.edges.push(
// Color Correct The Inpainted Result
{ {
source: { source: {
node_id: INPAINT_INFILL, node_id: INPAINT_INFILL,
@ -519,7 +519,7 @@ export const buildCanvasSDXLOutpaintGraph = (
}, },
destination: { destination: {
node_id: CANVAS_OUTPUT, node_id: CANVAS_OUTPUT,
field: 'reference', field: 'source_image',
}, },
}, },
{ {
@ -529,7 +529,7 @@ export const buildCanvasSDXLOutpaintGraph = (
}, },
destination: { destination: {
node_id: CANVAS_OUTPUT, node_id: CANVAS_OUTPUT,
field: 'image', field: 'target_image',
}, },
}, },
{ {
@ -559,7 +559,7 @@ export const buildCanvasSDXLOutpaintGraph = (
} }
} }
// optionally add custom VAE // Add VAE
addVAEToGraph(state, graph, modelLoaderNodeId); addVAEToGraph(state, graph, modelLoaderNodeId);
// add LoRA support // add LoRA support

File diff suppressed because one or more lines are too long

View File

@ -150,6 +150,8 @@ export type ImageScaleInvocation = S['ImageScaleInvocation'];
export type InfillPatchMatchInvocation = S['InfillPatchMatchInvocation']; export type InfillPatchMatchInvocation = S['InfillPatchMatchInvocation'];
export type InfillTileInvocation = S['InfillTileInvocation']; export type InfillTileInvocation = S['InfillTileInvocation'];
export type CreateDenoiseMaskInvocation = S['CreateDenoiseMaskInvocation']; export type CreateDenoiseMaskInvocation = S['CreateDenoiseMaskInvocation'];
export type CreateGradientMaskInvocation = S['CreateGradientMaskInvocation'];
export type IAICanvasPasteBackInvocation = S['IAICanvasPasteBackInvocation'];
export type MaskEdgeInvocation = S['MaskEdgeInvocation']; export type MaskEdgeInvocation = S['MaskEdgeInvocation'];
export type RandomIntInvocation = S['RandomIntInvocation']; export type RandomIntInvocation = S['RandomIntInvocation'];
export type CompelInvocation = S['CompelInvocation']; export type CompelInvocation = S['CompelInvocation'];