commit RGBValue and Seed node, image scale nodes increases width and height output

This commit is contained in:
chflame
2024-05-13 12:30:00 +08:00
parent a984f5db38
commit 29cc4dc352
16 changed files with 131 additions and 33 deletions
+20
View File
@@ -70,6 +70,7 @@ When this error has occurred, please check the network environment.
## Update
<font size="4">**If the dependency package error after updating, please reinstall the relevant dependency packages. </font><br />
* Add the [RGBValue](#RGBValue) node to output the color value as a single decimal value of R, G, and B. Add the [seed](#seed) node to output the seed value. The [ImageMaskScaleAs](#ImageMaskScaleAs), [ImageScaleBySspectRatio](#ImageScaleBySspectRatio), [ImageScaleBySspectRatioV2](#ImageScaleBySspectRatioV2), [ImageScaleRestore](#ImageScaleRestore), [ImageScaleRestoreV2](#ImageScaleRestoreV2) nodes increase ```width```, ```height``` output.
* Commit [Levels](#Levels) node, it can achieve the same color levels adjustment function as Photoshop.[Sharp&Soft](#Sharp) add the "None" option.
* Commit [BlendIfMask](#BlendIfMask) node, This node cooperates with ImgaeBlendV2 or ImageBlendAdvanceV2 to achieve the same Blend If function as Photoshop.
* Commit [ColorTemperature](#ColorTemperature) and [ColorBalance](#ColorBalance) nodes, used to adjust the color temperature and color balance of the picture.
@@ -546,6 +547,8 @@ Outputs:
* image: The scaled image.
* mask: If have mask input, the scaled mask will be output.
* original_size: The original size data of the image is used for subsequent node recovery.
* width: The output image's width.
* height: The output image's height.
### <a id="table1">ImageScaleRestoreV2</a>
The V2 upgraded version of ImageScaleRestore.
@@ -577,6 +580,8 @@ Outputs:
* image: If there is an image input, the scaled image will be output.
* mask: If there is a mask input, the scaled mask will be output.
* original_size: The original size data of the image is used for subsequent node recovery.
* width: The output image's width.
* height: The output image's height.
### <a id="table1">ImageScaleByAspectRatio</a>
Scale the image or mask by aspect ratio. the scaled size can be rounded to a multiple of 8 or 16, and can be scaled to the long side size.
@@ -597,6 +602,13 @@ The _fill_ mode does not maintain frame ratio and fills the screen with width an
* longest_side: When the scale_by_longest_side is set to True, this will be used this value to the long edge of the image. when the original_size have input, this setting will be ignored.
Outputs:
* image: If have image input, the scaled image will be output.
* mask: If have mask input, the scaled mask will be output.
* original_size: The original size data of the image is used for subsequent node recovery.
* width: The output image's width.
* height: The output image's height.
### <a id="table1">ImageScaleByAspectRatioV2</a>
V2 Upgraded Version of ImageScaleByAspectRatio
@@ -697,6 +709,14 @@ Node options:
Output type:
* value: String format.
### <a id="table1">RGBValue</a>
Output the color value as a single R, G, B three decimal values. Supports HEX and DEC formats for ColorPicker node output.
![image](image/RGB_value_example.png)
Node Options:
* color_value: Supports hexadecimal (HEX) or decimal (DEC) color values and should be of string or tuple type. Forcing in other types will result in an error.
### <a id="table1">GetColorTone</a>
Obtain the main color or average color from the image and output RGB values.
![image](image/get_color_tone_example.png)
+16
View File
@@ -70,6 +70,7 @@ git clone https://github.com/chflame163/ComfyUI_LayerStyle.git
## 更新说明
<font size="4">**如果本插件更新后出现依赖包错误,请重新安装相关依赖包。
* 添加 [RGBValue](#RGBValue) 节点, 将色值输出为单独的R, G, B三个10进制数值。添加[seed](#seed) 节点,输出种子值。[ImageMaskScaleAs](#ImageMaskScaleAs), [ImageScaleBySspectRatio](#ImageScaleBySspectRatio), [ImageScaleBySspectRatioV2](#ImageScaleBySspectRatioV2), [ImageScaleRestore](#ImageScaleRestore), [ImageScaleRestoreV2](#ImageScaleRestoreV2) 节点增加```width```, ```height``` 输出。
* 添加 [Levels](#Levels) 节点, 可以实现与Photoshop相同的色阶调整功能。[Sharp&Soft](#Sharp)增加"None"选项。
* 添加 [BlendIfMask](#BlendIfMask) 节点,该节点与 ImgaeBlendV2 或者 ImageBlendAdvanceV2 配合,可以实现与Photoshop相同的混合颜色带功能。
* 添加 [ColorTemperature](#ColorTemperature) 和 [ColorBalance](#ColorBalance) 节点,用于调整图片色温和色彩平衡。
@@ -541,6 +542,8 @@ CropByMask的V2升级版。支持crop_box输入,方便裁切相同尺寸的图
* image: 缩放后的图像。
* mask: 如果有mask输入,将输出缩放后的mask。
* original_size: 图像的原始大小数据,用于后续节点进行恢复。
* width: 输出图片的宽。
* height: 输出图片的高。
### <a id="table1">ImageScaleRestoreV2</a>
ImageScaleRestore的V2升级版。
@@ -570,6 +573,8 @@ ImageScaleRestore的V2升级版。
* image: 如果有image输入,将输出缩放后的图像。
* mask: 如果有mask输入,将输出缩放后的遮罩。
* original_size: 图像的原始大小数据,用于后续节点进行恢复。
* width: 输出图片的宽。
* height: 输出图片的高。
### <a id="table1">ImageScaleByAspectRatio</a>
@@ -592,6 +597,8 @@ ImageScaleRestore的V2升级版。
* image: 如果有image输入,将输出缩放后的图像。
* mask: 如果有mask输入,将输出缩放后的遮罩。
* original_size: 图像的原始大小数据,用于后续节点进行恢复。
* width: 输出图片的宽。
* height: 输出图片的高。
### <a id="table1">ImageScaleByAspectRatioV2</a>
ImageScaleByAspectRatio的V2升级版
@@ -693,6 +700,15 @@ ImageScaleByAspectRatio的V2升级版
输出:
* value: 字符串格式。
### <a id="table1">RGBValue</a>
将色值输出为单独的R, G, B三个10进制数值。支持ColorPicker节点输出的HEX和DEC格式。
![image](image/RGB_value_example.png)
节点选项说明:
* color_value: 支持十六进制(HEX)或十进制(DEC)色值,应是string或tuple类型,强行接入其他类型将导致错误。
### <a id="table1">GetColorTone</a>
从图片中获取主颜色或平均色。
![image](image/get_color_tone_example.png)
Binary file not shown.

After

Width:  |  Height:  |  Size: 238 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 135 KiB

After

Width:  |  Height:  |  Size: 81 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 179 KiB

After

Width:  |  Height:  |  Size: 106 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 167 KiB

After

Width:  |  Height:  |  Size: 113 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 170 KiB

After

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 116 KiB

After

Width:  |  Height:  |  Size: 95 KiB

+45
View File
@@ -0,0 +1,45 @@
from .imagefunc import *
NODE_NAME = 'RGB Value'
any = AnyType("*")
class ColorValuetoRGBValue:
def __init__(self):
pass
@classmethod
def INPUT_TYPES(self):
return {
"required": {
"color_value": (any, {}),
},
"optional": {
}
}
RETURN_TYPES = ("INT", "INT", "INT")
RETURN_NAMES = ("R", "G", "B")
FUNCTION = 'color_value_to_rgb_value'
CATEGORY = '😺dzNodes/LayerUtility'
def color_value_to_rgb_value(self, color_value,):
R, G, B = 0, 0, 0
if isinstance(color_value, str):
color = Hex_to_RGB(color_value)
R, G, B = color[0], color[1], color[2]
elif isinstance(color_value, tuple):
R, G, B = color_value[0], color_value[1], color_value[2]
else:
log(f"{NODE_NAME}: color_value input type must be tuple or string.", message_type="error")
return (R, G, B,)
NODE_CLASS_MAPPINGS = {
"LayerUtility: RGB Value": ColorValuetoRGBValue
}
NODE_DISPLAY_NAME_MAPPINGS = {
"LayerUtility: RGB Value": "LayerUtility: RGB Value"
}
+21 -3
View File
@@ -2,6 +2,23 @@ from .imagefunc import AnyType
any = AnyType("*")
class SeedNode:
def __init__(self):
pass
@classmethod
def INPUT_TYPES(self):
return {"required": {
"seed":("INT", {"default": 0, "min": 0, "max": 99999999999999999999, "step": 1}),
},}
RETURN_TYPES = ("INT",)
RETURN_NAMES = ("seed",)
FUNCTION = 'seed_node'
CATEGORY = '😺dzNodes/LayerUtility'
def seed_node(self, seed):
return (seed,)
class BooleanOperator:
def __init__(self):
@@ -143,14 +160,14 @@ class BooleanNode:
NODE_CLASS_MAPPINGS = {
"LayerUtility: BooleanOperator": BooleanOperator,
"LayerUtility: NumberCalculator": NumberCalculator,
"LayerUtility: TextBox": TextBoxNode,
"LayerUtility: Integer": IntegerNode,
"LayerUtility: Float": FloatNode,
"LayerUtility: Boolean": BooleanNode
"LayerUtility: Boolean": BooleanNode,
"LayerUtility: Seed": SeedNode
}
NODE_DISPLAY_NAME_MAPPINGS = {
@@ -159,5 +176,6 @@ NODE_DISPLAY_NAME_MAPPINGS = {
"LayerUtility: TextBox": "LayerUtility: TextBox",
"LayerUtility: Integer": "LayerUtility: Integer",
"LayerUtility: Float": "LayerUtility: Float",
"LayerUtility: Boolean": "LayerUtility: Boolean"
"LayerUtility: Boolean": "LayerUtility: Boolean",
"LayerUtility: Seed": "LayerUtility: Seed"
}
+6 -6
View File
@@ -27,8 +27,8 @@ class ImageMaskScaleAs:
}
}
RETURN_TYPES = ("IMAGE", "MASK", "BOX",)
RETURN_NAMES = ("image", "mask", "original_size")
RETURN_TYPES = ("IMAGE", "MASK", "BOX", "INT", "INT")
RETURN_NAMES = ("image", "mask", "original_size", "widht", "height",)
FUNCTION = 'image_mask_scale_as'
CATEGORY = '😺dzNodes/LayerUtility'
@@ -77,16 +77,16 @@ class ImageMaskScaleAs:
ret_masks.append(image2mask(_mask))
if len(ret_images) > 0 and len(ret_masks) >0:
log(f"{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],)
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"{NODE_NAME} Processed {len(ret_images)} image(s).", message_type='finish')
return (torch.cat(ret_images, dim=0), None, [orig_width, orig_height],)
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"{NODE_NAME} Processed {len(ret_masks)} image(s).", message_type='finish')
return (None, torch.cat(ret_masks, dim=0), [orig_width, orig_height],)
return (None, torch.cat(ret_masks, dim=0), [orig_width, orig_height], target_width, target_height,)
else:
log(f"Error: {NODE_NAME} skipped, because the available image or mask is not found.", message_type='error')
return (None, None, [orig_width, orig_height],)
return (None, None, [orig_width, orig_height], 0, 0,)
NODE_CLASS_MAPPINGS = {
"LayerUtility: ImageMaskScaleAs": ImageMaskScaleAs
+8 -8
View File
@@ -33,8 +33,8 @@ class ImageScaleByAspectRatio:
}
}
RETURN_TYPES = ("IMAGE", "MASK", "BOX",)
RETURN_NAMES = ("image", "mask", "original_size")
RETURN_TYPES = ("IMAGE", "MASK", "BOX", "INT", "INT",)
RETURN_NAMES = ("image", "mask", "original_size", "width", "height",)
FUNCTION = 'image_scale_by_aspect_ratio'
CATEGORY = '😺dzNodes/LayerUtility'
@@ -65,14 +65,14 @@ class ImageScaleByAspectRatio:
_width, _height = tensor2pil(orig_masks[0]).size
if (orig_width > 0 and orig_width != _width) or (orig_height > 0 and orig_height != _height):
log(f"Error: {NODE_NAME} skipped, because the mask is does'nt match image.", message_type='error')
return (None, None, None)
return (None, None, None, 0, 0,)
elif orig_width + orig_height == 0:
orig_width = _width
orig_height = _height
if orig_width + orig_height == 0:
log(f"Error: {NODE_NAME} skipped, because the image or mask at least one must be input.", message_type='error')
return (None, None, None)
return (None, None, None, 0, 0,)
if aspect_ratio == 'original':
ratio = orig_width / orig_height
@@ -137,16 +137,16 @@ class ImageScaleByAspectRatio:
ret_masks.append(image2mask(_mask))
if len(ret_images) > 0 and len(ret_masks) >0:
log(f"{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],)
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"{NODE_NAME} Processed {len(ret_images)} image(s).", message_type='finish')
return (torch.cat(ret_images, dim=0), None,[orig_width, orig_height],)
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"{NODE_NAME} Processed {len(ret_masks)} image(s).", message_type='finish')
return (None, torch.cat(ret_masks, dim=0),[orig_width, orig_height],)
return (None, torch.cat(ret_masks, dim=0),[orig_width, orig_height], target_width, target_height,)
else:
log(f"Error: {NODE_NAME} skipped, because the available image or mask is not found.", message_type='error')
return (None, None, None)
return (None, None, None, 0, 0,)
NODE_CLASS_MAPPINGS = {
"LayerUtility: ImageScaleByAspectRatio": ImageScaleByAspectRatio
+8 -8
View File
@@ -33,8 +33,8 @@ class ImageScaleByAspectRatioV2:
}
}
RETURN_TYPES = ("IMAGE", "MASK", "BOX",)
RETURN_NAMES = ("image", "mask", "original_size")
RETURN_TYPES = ("IMAGE", "MASK", "BOX", "INT", "INT",)
RETURN_NAMES = ("image", "mask", "original_size", "width", "height",)
FUNCTION = 'image_scale_by_aspect_ratio'
CATEGORY = '😺dzNodes/LayerUtility'
@@ -65,14 +65,14 @@ class ImageScaleByAspectRatioV2:
_width, _height = tensor2pil(orig_masks[0]).size
if (orig_width > 0 and orig_width != _width) or (orig_height > 0 and orig_height != _height):
log(f"Error: {NODE_NAME} skipped, because the mask is does'nt match image.", message_type='error')
return (None, None, None)
return (None, None, None, 0, 0,)
elif orig_width + orig_height == 0:
orig_width = _width
orig_height = _height
if orig_width + orig_height == 0:
log(f"Error: {NODE_NAME} skipped, because the image or mask at least one must be input.", message_type='error')
return (None, None, None)
return (None, None, None, 0, 0,)
if aspect_ratio == 'original':
ratio = orig_width / orig_height
@@ -136,16 +136,16 @@ class ImageScaleByAspectRatioV2:
ret_masks.append(image2mask(_mask))
if len(ret_images) > 0 and len(ret_masks) >0:
log(f"{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],)
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"{NODE_NAME} Processed {len(ret_images)} image(s).", message_type='finish')
return (torch.cat(ret_images, dim=0), None, [orig_width, orig_height],)
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"{NODE_NAME} Processed {len(ret_masks)} image(s).", message_type='finish')
return (None, torch.cat(ret_masks, dim=0), [orig_width, orig_height],)
return (None, torch.cat(ret_masks, dim=0), [orig_width, orig_height], target_width, target_height,)
else:
log(f"Error: {NODE_NAME} skipped, because the available image or mask is not found.", message_type='error')
return (None, None, None)
return (None, None, None, 0, 0,)
NODE_CLASS_MAPPINGS = {
"LayerUtility: ImageScaleByAspectRatio V2": ImageScaleByAspectRatioV2
+3 -3
View File
@@ -24,8 +24,8 @@ class ImageScaleRestore:
}
}
RETURN_TYPES = ("IMAGE", "MASK", "BOX",)
RETURN_NAMES = ("image", "mask", "original_size")
RETURN_TYPES = ("IMAGE", "MASK", "BOX", "INT", "INT")
RETURN_NAMES = ("image", "mask", "original_size", "width", "height",)
FUNCTION = 'image_scale_restore'
CATEGORY = '😺dzNodes/LayerUtility'
@@ -98,7 +98,7 @@ class ImageScaleRestore:
ret_masks.append(image2mask(ret_mask))
log(f"{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],)
return (torch.cat(ret_images, dim=0), torch.cat(ret_masks, dim=0), [orig_width, orig_height], target_width, target_height,)
NODE_CLASS_MAPPINGS = {
+3 -3
View File
@@ -25,8 +25,8 @@ class ImageScaleRestoreV2:
}
}
RETURN_TYPES = ("IMAGE", "MASK", "BOX",)
RETURN_NAMES = ("image", "mask", "original_size")
RETURN_TYPES = ("IMAGE", "MASK", "BOX", "INT", "INT")
RETURN_NAMES = ("image", "mask", "original_size", "width", "height",)
FUNCTION = 'image_scale_restore'
CATEGORY = '😺dzNodes/LayerUtility'
@@ -106,7 +106,7 @@ class ImageScaleRestoreV2:
ret_masks.append(image2mask(ret_mask))
log(f"{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],)
return (torch.cat(ret_images, dim=0), torch.cat(ret_masks, dim=0), [orig_width, orig_height], target_width, target_height,)
NODE_CLASS_MAPPINGS = {
+1 -2
View File
@@ -1,7 +1,6 @@
"""Image process functions for ComfyUI nodes
by chflame https://github.com/chflame163
"""
"""
@author: chflame
@title: LayerStyle
@nickname: LayerStyle