add files
Signed-off-by: jaeseung sim <77188135+sjskoko@users.noreply.github.com>
This commit is contained in:
@@ -0,0 +1,97 @@
|
||||
import os
|
||||
import torch
|
||||
from PIL import Image
|
||||
import torchvision.transforms.functional as tf
|
||||
import logging
|
||||
|
||||
import numpy as np
|
||||
import scipy.ndimage
|
||||
import comfy.utils
|
||||
|
||||
MAX_RESOLUTION=16384
|
||||
|
||||
def composite(destination, source, x, y, mask = None, multiplier = 8, resize_source = False):
|
||||
source = source.to(destination.device)
|
||||
if resize_source:
|
||||
source = torch.nn.functional.interpolate(source, size=(destination.shape[2], destination.shape[3]), mode="bilinear")
|
||||
|
||||
source = comfy.utils.repeat_to_batch_size(source, destination.shape[0])
|
||||
|
||||
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:
|
||||
mask = mask.to(destination.device, copy=True)
|
||||
mask = torch.nn.functional.interpolate(mask.reshape((-1, 1, mask.shape[-2], mask.shape[-1])), size=(source.shape[2], source.shape[3]), mode="bilinear")
|
||||
mask = comfy.utils.repeat_to_batch_size(mask, source.shape[0])
|
||||
|
||||
# calculate the bounds of the source that will be overlapping the destination
|
||||
# this prevents the source trying to overwrite latent pixels that are out of bounds
|
||||
# of the destination
|
||||
visible_width, visible_height = (destination.shape[3] - left + min(0, x), destination.shape[2] - top + min(0, y),)
|
||||
|
||||
mask = mask[:, :, :visible_height, :visible_width]
|
||||
inverse_mask = torch.ones_like(mask) - mask
|
||||
|
||||
source_portion = mask * source[:, :, :visible_height, :visible_width]
|
||||
destination_portion = inverse_mask * destination[:, :, top:bottom, left:right]
|
||||
|
||||
print('source_portion:', source_portion.shape)
|
||||
print('destination_portion:', destination_portion.shape)
|
||||
destination[:, :, top:bottom, left:right] = source_portion + destination_portion
|
||||
return destination
|
||||
|
||||
class StickerMaskComposite:
|
||||
@classmethod
|
||||
def INPUT_TYPES(s):
|
||||
return {
|
||||
"required": {
|
||||
"destination": ("IMAGE",),
|
||||
"source": ("IMAGE",),
|
||||
"x1": ("INT", {"default": 94, "min": 0, "max": MAX_RESOLUTION, "step": 1}),
|
||||
"y1": ("INT", {"default": 700, "min": 0, "max": MAX_RESOLUTION, "step": 1}),
|
||||
"x2": ("INT", {"default": 614, "min": 0, "max": MAX_RESOLUTION, "step": 1}),
|
||||
"y2": ("INT", {"default": 700, "min": 0, "max": MAX_RESOLUTION, "step": 1}),
|
||||
"x3": ("INT", {"default": 1134, "min": 0, "max": MAX_RESOLUTION, "step": 1}),
|
||||
"y3": ("INT", {"default": 700, "min": 0, "max": MAX_RESOLUTION, "step": 1}),
|
||||
"x4": ("INT", {"default": 94, "min": 0, "max": MAX_RESOLUTION, "step": 1}),
|
||||
"y4": ("INT", {"default": 1420, "min": 0, "max": MAX_RESOLUTION, "step": 1}),
|
||||
"x5": ("INT", {"default": 614, "min": 0, "max": MAX_RESOLUTION, "step": 1}),
|
||||
"y5": ("INT", {"default": 1420, "min": 0, "max": MAX_RESOLUTION, "step": 1}),
|
||||
"x6": ("INT", {"default": 1134, "min": 0, "max": MAX_RESOLUTION, "step": 1}),
|
||||
"y6": ("INT", {"default": 1420, "min": 0, "max": MAX_RESOLUTION, "step": 1}),
|
||||
"resize_source": ("BOOLEAN", {"default": False}),
|
||||
},
|
||||
"optional": {
|
||||
"mask": ("MASK",),
|
||||
}
|
||||
}
|
||||
RETURN_TYPES = ("IMAGE",)
|
||||
FUNCTION = "composite"
|
||||
|
||||
CATEGORY = "image"
|
||||
|
||||
def composite(self, destination, source, x1, y1, x2, y2, x3, y3, x4, y4, x5, y5, x6, y6, resize_source, mask = None):
|
||||
# print(source.shape)
|
||||
size_pack = [(x1, y1), (x2, y2), (x3, y3), (x4, y4), (x5, y5), (x6, y6)]
|
||||
# print("dest", destination.shape)
|
||||
for i in range(len(size_pack)):
|
||||
destination = destination.clone().movedim(-1, 1)
|
||||
# print("source", source[i].unsqueeze(0).movedim(-1, 1).shape)
|
||||
destination = composite(destination, source[i].unsqueeze(0).movedim(-1, 1), size_pack[i][0], size_pack[i][1], mask[i].unsqueeze(0), 1, resize_source).movedim(1, -1)
|
||||
return (destination,)
|
||||
|
||||
|
||||
|
||||
NODE_CLASS_MAPPINGS = {
|
||||
"Sticker_Compositer": StickerMaskComposite,
|
||||
}
|
||||
|
||||
NODE_DISPLAY_NAME_MAPPINGS = {
|
||||
"Sticker_Compositer": "Sticker Compositer",
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
import sys
|
||||
|
||||
python = sys.executable
|
||||
|
||||
from .ComfyUI_Sticker_Compositer import NODE_CLASS_MAPPINGS, NODE_DISPLAY_NAME_MAPPINGS
|
||||
|
||||
__all__ = ['NODE_CLASS_MAPPINGS', 'NODE_DISPLAY_NAME_MAPPINGS']
|
||||
@@ -0,0 +1,21 @@
|
||||
[project]
|
||||
name = "ComfyUI-Image-Harmonizer"
|
||||
description = "NODES:Image-Harmonizer"
|
||||
version = "0.1.0"
|
||||
license = {text = "MIT License"}
|
||||
dependencies = []
|
||||
|
||||
[project.urls]
|
||||
Repository = "https://github.com/sweetndata/ComfyUI-Image-Harmonizer"
|
||||
|
||||
[tool.comfy]
|
||||
PublisherId = "sweetndata"
|
||||
DisplayName = "ComfyUI-Image-Harmonizer"
|
||||
Icon = ""
|
||||
|
||||
[tool.poetry]
|
||||
name = "ComfyUI-Image-Harmonizer"
|
||||
version = "0.1.0"
|
||||
description = ""
|
||||
authors = ["Jason Sim <sjskoko@gmail.com>"]
|
||||
readme = "README.md"
|
||||
@@ -0,0 +1,13 @@
|
||||
anyio==3.7.1 ; python_version >= "3.7" and python_version < "4.0"
|
||||
certifi==2024.8.30 ; python_version >= "3.7" and python_version < "4.0"
|
||||
exceptiongroup==1.2.2 ; python_version >= "3.7" and python_version < "3.11"
|
||||
googletrans-py==4.0.0 ; python_version >= "3.7" and python_version < "4.0"
|
||||
h11==0.14.0 ; python_version >= "3.7" and python_version < "4.0"
|
||||
h2==4.1.0 ; python_version >= "3.7" and python_version < "4.0"
|
||||
hpack==4.0.0 ; python_version >= "3.7" and python_version < "4.0"
|
||||
httpcore==0.17.3 ; python_version >= "3.7" and python_version < "4.0"
|
||||
httpx==0.24.1 ; python_version >= "3.7" and python_version < "4.0"
|
||||
hyperframe==6.0.1 ; python_version >= "3.7" and python_version < "4.0"
|
||||
idna==3.10 ; python_version >= "3.7" and python_version < "4.0"
|
||||
sniffio==1.3.1 ; python_version >= "3.7" and python_version < "4.0"
|
||||
typing-extensions==4.7.1 ; python_version >= "3.7" and python_version < "3.8"
|
||||
Reference in New Issue
Block a user