commit RGBValue and Seed node, image scale nodes increases width and height output
@@ -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.
|
||||
|
||||

|
||||
|
||||
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.
|
||||

|
||||
|
||||
@@ -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格式。
|
||||
|
||||

|
||||
|
||||
节点选项说明:
|
||||
* color_value: 支持十六进制(HEX)或十进制(DEC)色值,应是string或tuple类型,强行接入其他类型将导致错误。
|
||||
|
||||
|
||||
### <a id="table1">GetColorTone</a>
|
||||
从图片中获取主颜色或平均色。
|
||||

|
||||
|
||||
|
After Width: | Height: | Size: 238 KiB |
|
Before Width: | Height: | Size: 135 KiB After Width: | Height: | Size: 81 KiB |
|
Before Width: | Height: | Size: 179 KiB After Width: | Height: | Size: 106 KiB |
|
Before Width: | Height: | Size: 167 KiB After Width: | Height: | Size: 113 KiB |
|
Before Width: | Height: | Size: 170 KiB After Width: | Height: | Size: 92 KiB |
|
Before Width: | Height: | Size: 116 KiB After Width: | Height: | Size: 95 KiB |
@@ -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"
|
||||
}
|
||||
@@ -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"
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 = {
|
||||
|
||||
@@ -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,7 +1,6 @@
|
||||
"""Image process functions for ComfyUI nodes
|
||||
by chflame https://github.com/chflame163
|
||||
"""
|
||||
"""
|
||||
|
||||
@author: chflame
|
||||
@title: LayerStyle
|
||||
@nickname: LayerStyle
|
||||
|
||||