diff --git a/README.MD b/README.MD
index 96fd983..72f6078 100644
--- a/README.MD
+++ b/README.MD
@@ -70,6 +70,7 @@ When this error has occurred, please check the network environment.
## Update
**If the dependency package error after updating, please reinstall the relevant dependency packages.
+* 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.
### ImageScaleRestoreV2
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.
### ImageScaleByAspectRatio
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.
+
### ImageScaleByAspectRatioV2
V2 Upgraded Version of ImageScaleByAspectRatio
@@ -697,6 +709,14 @@ Node options:
Output type:
* value: String format.
+### RGBValue
+Output the color value as a single R, G, B three decimal values. Supports HEX and DEC formats for ColorPicker node output.
+
+
+
+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.
+
### GetColorTone
Obtain the main color or average color from the image and output RGB values.

diff --git a/README_CN.MD b/README_CN.MD
index e4f733e..68df6c5 100644
--- a/README_CN.MD
+++ b/README_CN.MD
@@ -70,6 +70,7 @@ git clone https://github.com/chflame163/ComfyUI_LayerStyle.git
## 更新说明
**如果本插件更新后出现依赖包错误,请重新安装相关依赖包。
+ * 添加 [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: 输出图片的高。
### ImageScaleRestoreV2
ImageScaleRestore的V2升级版。
@@ -570,6 +573,8 @@ ImageScaleRestore的V2升级版。
* image: 如果有image输入,将输出缩放后的图像。
* mask: 如果有mask输入,将输出缩放后的遮罩。
* original_size: 图像的原始大小数据,用于后续节点进行恢复。
+* width: 输出图片的宽。
+* height: 输出图片的高。
### ImageScaleByAspectRatio
@@ -592,6 +597,8 @@ ImageScaleRestore的V2升级版。
* image: 如果有image输入,将输出缩放后的图像。
* mask: 如果有mask输入,将输出缩放后的遮罩。
* original_size: 图像的原始大小数据,用于后续节点进行恢复。
+* width: 输出图片的宽。
+* height: 输出图片的高。
### ImageScaleByAspectRatioV2
ImageScaleByAspectRatio的V2升级版
@@ -693,6 +700,15 @@ ImageScaleByAspectRatio的V2升级版
输出:
* value: 字符串格式。
+### RGBValue
+将色值输出为单独的R, G, B三个10进制数值。支持ColorPicker节点输出的HEX和DEC格式。
+
+
+
+节点选项说明:
+* color_value: 支持十六进制(HEX)或十进制(DEC)色值,应是string或tuple类型,强行接入其他类型将导致错误。
+
+
### GetColorTone
从图片中获取主颜色或平均色。

diff --git a/image/RGB_value_example.png b/image/RGB_value_example.png
new file mode 100644
index 0000000..d6590f6
Binary files /dev/null and b/image/RGB_value_example.png differ
diff --git a/image/image_mask_scale_as_node.png b/image/image_mask_scale_as_node.png
index 17ed6a5..dd6f5e1 100644
Binary files a/image/image_mask_scale_as_node.png and b/image/image_mask_scale_as_node.png differ
diff --git a/image/image_scale_by_aspect_ratio_node.png b/image/image_scale_by_aspect_ratio_node.png
index 8d9f77f..9375f9b 100644
Binary files a/image/image_scale_by_aspect_ratio_node.png and b/image/image_scale_by_aspect_ratio_node.png differ
diff --git a/image/image_scale_by_aspect_ratio_v2_node.png b/image/image_scale_by_aspect_ratio_v2_node.png
index 6f4a68e..33ce0c0 100644
Binary files a/image/image_scale_by_aspect_ratio_v2_node.png and b/image/image_scale_by_aspect_ratio_v2_node.png differ
diff --git a/image/image_scale_restore_node.png b/image/image_scale_restore_node.png
index 06bdcea..6634f4b 100644
Binary files a/image/image_scale_restore_node.png and b/image/image_scale_restore_node.png differ
diff --git a/image/image_scale_restore_v2_node.png b/image/image_scale_restore_v2_node.png
index 8730117..05f68d2 100644
Binary files a/image/image_scale_restore_v2_node.png and b/image/image_scale_restore_v2_node.png differ
diff --git a/py/color_to_RGBvalue.py b/py/color_to_RGBvalue.py
new file mode 100644
index 0000000..d1c3a02
--- /dev/null
+++ b/py/color_to_RGBvalue.py
@@ -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"
+}
\ No newline at end of file
diff --git a/py/data_nodes.py b/py/data_nodes.py
index 892fe3e..3893d65 100644
--- a/py/data_nodes.py
+++ b/py/data_nodes.py
@@ -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"
}
\ No newline at end of file
diff --git a/py/image_mask_scale_as.py b/py/image_mask_scale_as.py
index 342199b..80a52f0 100644
--- a/py/image_mask_scale_as.py
+++ b/py/image_mask_scale_as.py
@@ -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
diff --git a/py/image_scale_by_aspect_ratio.py b/py/image_scale_by_aspect_ratio.py
index 6a2a859..81285a3 100644
--- a/py/image_scale_by_aspect_ratio.py
+++ b/py/image_scale_by_aspect_ratio.py
@@ -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
diff --git a/py/image_scale_by_aspect_ratio_v2.py b/py/image_scale_by_aspect_ratio_v2.py
index 096ed82..90b233b 100644
--- a/py/image_scale_by_aspect_ratio_v2.py
+++ b/py/image_scale_by_aspect_ratio_v2.py
@@ -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
diff --git a/py/image_scale_restore.py b/py/image_scale_restore.py
index 28df761..5d8a186 100644
--- a/py/image_scale_restore.py
+++ b/py/image_scale_restore.py
@@ -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 = {
diff --git a/py/image_scale_restore_v2.py b/py/image_scale_restore_v2.py
index cf8f831..ed91118 100644
--- a/py/image_scale_restore_v2.py
+++ b/py/image_scale_restore_v2.py
@@ -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 = {
diff --git a/py/imagefunc.py b/py/imagefunc.py
index 18eb987..1a11b13 100644
--- a/py/imagefunc.py
+++ b/py/imagefunc.py
@@ -1,7 +1,6 @@
"""Image process functions for ComfyUI nodes
by chflame https://github.com/chflame163
-"""
-"""
+
@author: chflame
@title: LayerStyle
@nickname: LayerStyle