raubatz's picture
download
raw
3.23 kB
import torch
import logging
logger = logging.getLogger(__file__)
MAX_RESOLUTION=16384
def composite(destination, source, x, y, mask=None, resize_source=False, resize_mode='bilinear'):
device = destination.device
batch_size, _, dest_height, dest_width = destination.shape
if not resize_source:
_, _, source_height, source_width = source.shape
else:
source_height, source_width = dest_height, dest_width
if x > dest_width or y > dest_height:
return destination
left = x
top = y
visible_width = min(dest_width - left, source_width)
visible_height = min(dest_height - top, source_height)
if resize_source:
resize_height, resize_width = dest_height, dest_width
else:
resize_height, resize_width = source_height, source_width
for i in range(batch_size):
source_slice = source[i:i+1].to(device)
if resize_source:
source_slice = torch.nn.functional.interpolate(source_slice, size=(resize_height, resize_width), mode=resize_mode)
if mask is None:
mask_slice = torch.ones_like(source_slice)
else:
mask_slice = mask[i:i+1].to(device)
mask_slice = torch.nn.functional.interpolate(mask_slice.reshape((-1, 1, mask_slice.shape[-2], mask_slice.shape[-1])),
size=(resize_height, resize_width), mode=resize_mode)
mask_slice = mask_slice[:, :, :visible_height, :visible_width]
dest_portion = destination[i:i+1, :, top:top+visible_height, left:left+visible_width]
source_portion = source_slice[:, :, :visible_height, :visible_width]
dest_portion.mul_(1 - mask_slice)
dest_portion.add_(source_portion * mask_slice)
# Free up memory
del source_slice, mask_slice, dest_portion, source_portion
torch.cuda.empty_cache()
return destination
class ImageCompositeMaskedOneByOne:
@classmethod
def INPUT_TYPES(s):
return {
"required": {
"destination": ("IMAGE",),
"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}),
"resize_source_mode":(["nearest", "bilinear", "bicubic", "area", "nearest-exact"],)
},
"optional": {
"mask": ("MASK",),
}
}
RETURN_TYPES = ("IMAGE",)
FUNCTION = "composite"
CATEGORY = "utils/image"
def composite(self, destination, source, x, y, resize_source, resize_source_mode= "bilinear", mask = None):
destination = destination.clone().movedim(-1, 1)
output = composite(destination, source.movedim(-1, 1), x, y, mask, resize_source, resize_source_mode).movedim(1, -1)
return (output,)
NODE_CLASS_MAPPINGS = {
#image
"ImageCompositeMaskedOneByOne": ImageCompositeMaskedOneByOne,
}
NODE_DISPLAY_NAME_MAPPINGS = {
# Image
"ImageCompositeMaskedOneByOne": "image composite masked one bye one",
}

Xet Storage Details

Size:
3.23 kB
·
Xet hash:
92b3a57446821ac3c49bab7a52cc9a3cf4a7fbbd72e13c765003ed03e5ac6b1f

Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.