commit ImageMaskScaleAsV2,ColorImage V3 nodes

This commit is contained in:
chflame163
2024-12-18 23:48:12 +08:00
parent 184e83baf9
commit 9bd65618bf
5 changed files with 167 additions and 5 deletions
+1 -1
View File
@@ -49,7 +49,7 @@ class ColorImageV2:
width = int(_s[0].strip())
height = int(_s[1].strip())
except Exception as e:
log(f"Warning: {self.NODE_NAME} invalid size, check {custom_size_file}", message_type='warning')
log(f'Warning: {self.NODE_NAME} invalid size, check "custom_size.ini"', message_type='warning')
width = custom_width
height = custom_height
+72
View File
@@ -0,0 +1,72 @@
from PIL import Image
from .imagefunc import log, tensor2pil, pil2tensor, AnyType, load_custom_size
from .color_name import LS_ColorName
any = AnyType("*")
class LS_ColorImageV3:
def __init__(self):
self.NODE_NAME = 'ColorImage V3'
@classmethod
def INPUT_TYPES(self):
size_list = ['custom']
size_list.extend(load_custom_size())
return {
"required": {
"size": (size_list,),
"custom_width": ("INT", {"default": 512, "min": 4, "max": 99999, "step": 1}),
"custom_height": ("INT", {"default": 512, "min": 4, "max": 99999, "step": 1}),
"color": ("STRING", {"default": "#000000"},),
},
"optional": {
"size_as": (any, {}),
"color_name": ("STRING", {"default": "white",},),
}
}
RETURN_TYPES = ("IMAGE", "STRING", )
RETURN_NAMES = ("image", "color",)
FUNCTION = 'color_image_v2'
CATEGORY = '😺dzNodes/LayerUtility'
def color_image_v2(self, size, custom_width, custom_height, color, size_as=None, color_name=None):
if size_as is not None:
if size_as.shape[0] > 0:
_asimage = tensor2pil(size_as[0])
else:
_asimage = tensor2pil(size_as)
width, height = _asimage.size
else:
if size == 'custom':
width = custom_width
height = custom_height
else:
try:
_s = size.split('x')
width = int(_s[0].strip())
height = int(_s[1].strip())
except Exception as e:
log(f'Warning: {self.NODE_NAME} invalid size, check "custom_size.ini"', message_type='warning')
width = custom_width
height = custom_height
if color_name is not None:
try:
color_table = LS_ColorName()
color = color_table.XKCD_NAME_TO_HEX[color_name]
except KeyError:
log(f"{self.NODE_NAME}: {color_name} not in XKCD color table, use custom color value.")
ret_image = Image.new('RGB', (width, height), color=color)
return (pil2tensor(ret_image), color,)
NODE_CLASS_MAPPINGS = {
"LayerUtility: ColorImage V3": LS_ColorImageV3
}
NODE_DISPLAY_NAME_MAPPINGS = {
"LayerUtility: ColorImage V3": "LayerUtility: ColorImage V3"
}
+1 -1
View File
@@ -53,7 +53,7 @@ class GradientImageV2:
width = int(_s[0].strip())
height = int(_s[1].strip())
except Exception as e:
log(f"Warning: {self.NODE_NAME} invalid size, check {custom_size_file}", message_type='warning')
log(f'Warning: {self.NODE_NAME} invalid size, check "custom_size.ini"', message_type='warning')
width = custom_width
height = custom_height
+92 -2
View File
@@ -90,10 +90,100 @@ class ImageMaskScaleAs:
log(f"Error: {self.NODE_NAME} skipped, because the available image or mask is not found.", message_type='error')
return (None, None, [orig_width, orig_height], 0, 0,)
class LS_ImageMaskScaleAsV2:
def __init__(self):
self.NODE_NAME = 'ImageMaskScaleAsV2'
@classmethod
def INPUT_TYPES(self):
fit_mode = ['letterbox', 'crop', 'fill']
method_mode = ['lanczos', 'bicubic', 'hamming', 'bilinear', 'box', 'nearest']
return {
"required": {
"scale_as": (any, {}),
"fit": (fit_mode,),
"method": (method_mode,),
"background_color": ("STRING", {"default": "#000000"},),
},
"optional": {
"image": ("IMAGE",), #
"mask": ("MASK",), #
}
}
RETURN_TYPES = ("IMAGE", "MASK", "BOX", "INT", "INT")
RETURN_NAMES = ("image", "mask", "original_size", "widht", "height",)
FUNCTION = 'image_mask_scale_as_v2'
CATEGORY = '😺dzNodes/LayerUtility'
def image_mask_scale_as_v2(self, scale_as, fit, method, background_color,
image=None, mask=None,
):
if scale_as.shape[0] > 0:
_asimage = tensor2pil(scale_as[0])
else:
_asimage = tensor2pil(scale_as)
target_width, target_height = _asimage.size
_mask = Image.new('L', size=_asimage.size, color='black')
_image = Image.new('RGB', size=_asimage.size, color=background_color)
orig_width = 4
orig_height = 4
resize_sampler = Image.LANCZOS
if method == "bicubic":
resize_sampler = Image.BICUBIC
elif method == "hamming":
resize_sampler = Image.HAMMING
elif method == "bilinear":
resize_sampler = Image.BILINEAR
elif method == "box":
resize_sampler = Image.BOX
elif method == "nearest":
resize_sampler = Image.NEAREST
ret_images = []
ret_masks = []
if image is not None:
for i in image:
i = torch.unsqueeze(i, 0)
_image = tensor2pil(i).convert('RGB')
orig_width, orig_height = _image.size
_image = fit_resize_image(_image, target_width, target_height, fit, resize_sampler, background_color=background_color)
ret_images.append(pil2tensor(_image))
if mask is not None:
if mask.dim() == 2:
mask = torch.unsqueeze(mask, 0)
for m in mask:
m = torch.unsqueeze(m, 0)
_mask = tensor2pil(m).convert('L')
orig_width, orig_height = _mask.size
_mask = fit_resize_image(_mask, target_width, target_height, fit, resize_sampler, background_color=background_color).convert('L')
ret_masks.append(image2mask(_mask))
if len(ret_images) > 0 and len(ret_masks) > 0:
log(f"{self.NODE_NAME} Processed {len(ret_images)} image(s).", message_type='finish')
return (torch.cat(ret_images, dim=0), torch.cat(ret_masks, dim=0), [orig_width, orig_height], target_width,
target_height,)
elif len(ret_images) > 0 and len(ret_masks) == 0:
log(f"{self.NODE_NAME} Processed {len(ret_images)} image(s).", message_type='finish')
return (torch.cat(ret_images, dim=0), None, [orig_width, orig_height], target_width, target_height,)
elif len(ret_images) == 0 and len(ret_masks) > 0:
log(f"{self.NODE_NAME} Processed {len(ret_masks)} image(s).", message_type='finish')
return (None, torch.cat(ret_masks, dim=0), [orig_width, orig_height], target_width, target_height,)
else:
log(f"Error: {self.NODE_NAME} skipped, because the available image or mask is not found.",
message_type='error')
return (None, None, [orig_width, orig_height], 0, 0,)
NODE_CLASS_MAPPINGS = {
"LayerUtility: ImageMaskScaleAs": ImageMaskScaleAs
"LayerUtility: ImageMaskScaleAs": ImageMaskScaleAs,
"LayerUtility: ImageMaskScaleAsV2": LS_ImageMaskScaleAsV2,
}
NODE_DISPLAY_NAME_MAPPINGS = {
"LayerUtility: ImageMaskScaleAs": "LayerUtility: ImageMaskScaleAs"
"LayerUtility: ImageMaskScaleAs": "LayerUtility: Image Mask Scale As",
"LayerUtility: ImageMaskScaleAsV2": "LayerUtility: Image Mask Scale As V2",
}
+1 -1
View File
@@ -1,7 +1,7 @@
[project]
name = "comfyui_layerstyle"
description = "A set of nodes for ComfyUI it generate image like Adobe Photoshop's Layer Style. the Drop Shadow is first completed node, and follow-up work is in progress."
version = "2.0.10"
version = "2.0.11"
license = "MIT"
dependencies = ["numpy", "pillow", "torch", "matplotlib", "Scipy", "scikit_image", "scikit_learn", "opencv-contrib-python", "pymatting", "timm", "colour-science", "transformers", "blend_modes", "huggingface_hub", "loguru"]