|
|
|
@ -2,14 +2,16 @@ import torch
|
|
|
|
|
|
|
|
|
|
from nodes import MAX_RESOLUTION
|
|
|
|
|
|
|
|
|
|
def composite(destination, source, x, y, mask = None, multiplier = 8):
|
|
|
|
|
def composite(destination, source, x, y, mask = None, multiplier = 8, resize_source = False):
|
|
|
|
|
if resize_source:
|
|
|
|
|
source = torch.nn.functional.interpolate(source, size=(destination.shape[2], destination.shape[3]), mode="bilinear")
|
|
|
|
|
|
|
|
|
|
x = max(-source.shape[3] * multiplier, min(x, destination.shape[3] * multiplier))
|
|
|
|
|
y = max(-source.shape[2] * multiplier, min(y, destination.shape[2] * multiplier))
|
|
|
|
|
|
|
|
|
|
left, top = (x // multiplier, y // multiplier)
|
|
|
|
|
right, bottom = (left + source.shape[3], top + source.shape[2],)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if mask is None:
|
|
|
|
|
mask = torch.ones_like(source)
|
|
|
|
|
else:
|
|
|
|
@ -40,6 +42,7 @@ class LatentCompositeMasked:
|
|
|
|
|
"source": ("LATENT",),
|
|
|
|
|
"x": ("INT", {"default": 0, "min": 0, "max": MAX_RESOLUTION, "step": 8}),
|
|
|
|
|
"y": ("INT", {"default": 0, "min": 0, "max": MAX_RESOLUTION, "step": 8}),
|
|
|
|
|
"resize_source": ("BOOLEAN", {"default": False}),
|
|
|
|
|
},
|
|
|
|
|
"optional": {
|
|
|
|
|
"mask": ("MASK",),
|
|
|
|
@ -50,11 +53,11 @@ class LatentCompositeMasked:
|
|
|
|
|
|
|
|
|
|
CATEGORY = "latent"
|
|
|
|
|
|
|
|
|
|
def composite(self, destination, source, x, y, mask = None):
|
|
|
|
|
def composite(self, destination, source, x, y, resize_source, mask = None):
|
|
|
|
|
output = destination.copy()
|
|
|
|
|
destination = destination["samples"].clone()
|
|
|
|
|
source = source["samples"]
|
|
|
|
|
output["samples"] = composite(destination, source, x, y, mask, 8)
|
|
|
|
|
output["samples"] = composite(destination, source, x, y, mask, 8, resize_source)
|
|
|
|
|
return (output,)
|
|
|
|
|
|
|
|
|
|
class ImageCompositeMasked:
|
|
|
|
@ -66,6 +69,7 @@ class ImageCompositeMasked:
|
|
|
|
|
"source": ("IMAGE",),
|
|
|
|
|
"x": ("INT", {"default": 0, "min": 0, "max": MAX_RESOLUTION, "step": 1}),
|
|
|
|
|
"y": ("INT", {"default": 0, "min": 0, "max": MAX_RESOLUTION, "step": 1}),
|
|
|
|
|
"resize_source": ("BOOLEAN", {"default": False}),
|
|
|
|
|
},
|
|
|
|
|
"optional": {
|
|
|
|
|
"mask": ("MASK",),
|
|
|
|
@ -76,9 +80,9 @@ class ImageCompositeMasked:
|
|
|
|
|
|
|
|
|
|
CATEGORY = "image"
|
|
|
|
|
|
|
|
|
|
def composite(self, destination, source, x, y, mask = None):
|
|
|
|
|
def composite(self, destination, source, x, y, resize_source, mask = None):
|
|
|
|
|
destination = destination.clone().movedim(-1, 1)
|
|
|
|
|
output = composite(destination, source.movedim(-1, 1), x, y, mask, 1).movedim(1, -1)
|
|
|
|
|
output = composite(destination, source.movedim(-1, 1), x, y, mask, 1, resize_source).movedim(1, -1)
|
|
|
|
|
return (output,)
|
|
|
|
|
|
|
|
|
|
class MaskToImage:
|
|
|
|
|