add ImageBlend node

This commit is contained in:
chflame163
2024-01-18 18:50:05 +08:00
committed by GitHub
parent 2649bbff11
commit 1cd7800ed6
8 changed files with 314 additions and 11 deletions
+24 -3
View File
@@ -7,7 +7,9 @@ Currently completed Drop Shadow and OuterGlow nodes, and follow-up work is in pr
[中文说明点这里](./README_CN.MD)
## Update
Remove the mask channel output from the DropShadow node; Add the OuterGlow node.
* Commit ImageBlend node.
* Remove the mask channel output from the DropShadow node; Commit OuterGlow node.
* Commit DropShadow node.
## Node Description
@@ -33,7 +35,7 @@ Node options:
<sup>1</sup> The layer_image, layer_mask and the background_image, These three items must be of the same size.
Output type:
Output type:
* image
@@ -55,7 +57,26 @@ Node options:
<sup>1</sup> The layer_image, layer_mask and the background_image, These three items must be of the same size.
输出:
Output type:
* image
### ImageBlend:
Composit layer image and background image, multiple blend modes are available for option, and transparency can be set.
![image](image/image_blend_example.png)
Node options:
![image](image/image_blend_node.png)
* background_image<sup>1</sup>: The background image.
* layer_image<sup>1</sup>: Layer image for composite.
* layer_mask<sup>1</sup>: Mask for layer_image.
* invert_mask: Whether to reverse the mask.
* blend_mode: Blending method of glow, there are **_normal, multply, screen, add, subtract, difference, darker_** and **_lighter_**.
* opacity: Opacity of blend.
<sup>1</sup> The layer_image, layer_mask and the background_image, These three items must be of the same size.。
Output type:
* image
## Example workflow
+28 -8
View File
@@ -3,7 +3,9 @@ ComfyUI
当前已完成Drop Shadow和OuterGlow节点,后续工作进行中。
## 更新说明:
DropShadow节点去掉调试mask通道输出;添加OuterGlow节点。
* 添加ImageBlend节点
* DropShadow节点去掉调试mask通道输出;添加OuterGlow节点。
* DropShadow节点上线。
## 节点说明:
@@ -19,7 +21,7 @@ DropShadow
* layer_image<sup>1</sup>: 用于合成的层图像。
* layer_mask<sup>1</sup>: 层图像的遮罩,阴影按此生成。
* invert_mask: 是否反转遮罩。
* blend_mode: 阴影的混合方式,包括normal、multply、screen、add、subtract、difference、darker和lighter。
* blend_mode: 阴影的混合模式,包括normal、multply、screen、add、subtract、difference、darker和lighter。
* opacity: 阴影的不透明度。
* distance_x: 阴影的水平方向偏移量。
* distance_y: 阴影的垂直方向偏移量。
@@ -40,19 +42,37 @@ DropShadow
![image](image/outer_glow_node.png)
* background_image<sup>1</sup>: 背景图像。
* layer_image<sup>1</sup>: 用于合成的层图像。
* layer_mask<sup>1</sup>: 层图像的遮罩,阴影按此生成。
* layer_mask<sup>1</sup>: 层图像的遮罩,外发光按此生成。
* invert_mask: 是否反转遮罩。
* blend_mode: 外发光的混合方式,包括normal、multply、screen、add、subtract、difference、darker和lighter。
* opacity: 外发光的不透明度。
* grow: 外发光扩张幅度。
* blur:外发光模糊程度。
* glow_color: 外发光颜色,使用16进制RGB格式描述。
* blend_mode: 发光的混合模式,包括normal、multply、screen、add、subtract、difference、darker和lighter。
* opacity: 发光的不透明度。
* grow: 发光扩张幅度。
* blur:发光模糊程度。
* glow_color: 发光颜色,使用16进制RGB格式描述。
<sup>1</sup> background_image, layer_image, layer_mask这三项必须是相同的尺寸。
输出:
* image
### ImageBlend:
用于合成图层,提供多种混合模式供选择,可设置透明度。
![image](image/image_blend_example.png)
节点选项说明:
![image](image/image_blend_node.png)
* background_image<sup>1</sup>: 背景图像。
* layer_image<sup>1</sup>: 用于合成的层图像。
* layer_mask<sup>1</sup>: 层图像的遮罩。
* invert_mask: 是否反转遮罩。
* blend_mode: 图层混合模式,包括normal、multply、screen、add、subtract、difference、darker和lighter。
* opacity: 不透明度。
<sup>1</sup> background_image, layer_image, layer_mask这三项必须是相同的尺寸。
输出:
* image
## 使用示例:
Binary file not shown.

After

Width:  |  Height:  |  Size: 400 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 86 KiB

Binary file not shown.
Binary file not shown.
+60
View File
@@ -0,0 +1,60 @@
from .imagefunc import *
class LayerBlend:
def __init__(self):
pass
@classmethod
def INPUT_TYPES(self):
chop_mode = ['normal','multply','screen','add','subtract','difference','darker','lighter']
return {
"required": {
"background_image": ("IMAGE", ), #
"layer_image": ("IMAGE",), #
"invert_mask": ("BOOLEAN", {"default": True}), # 反转mask
"blend_mode": (chop_mode,), # 混合模式
"opacity": ("INT", {"default": 100, "min": 0, "max": 100, "step": 1}), # 透明度
},
"optional": {
"layer_mask": ("MASK",), #
}
}
RETURN_TYPES = ("IMAGE",)
RETURN_NAMES = ("image",)
FUNCTION = 'layer_blend'
CATEGORY = '😺dzNodes'
OUTPUT_NODE = True
def layer_blend(self, background_image, layer_image,
invert_mask, blend_mode, opacity,
layer_mask=None,
):
#
_layer = tensor2pil(layer_image)
_canvas = tensor2pil(background_image)
_mask = None
if layer_mask is not None and invert_mask:
layer_mask = 1 - layer_mask
# 合成layer
_comp = chop_image(tensor2pil(background_image), _layer, blend_mode, opacity)
if layer_mask is not None:
alpha = tensor2pil(layer_mask).convert('L')
_canvas.paste(_comp, mask=alpha)
else:
_canvas.paste(_comp)
ret_image = _canvas
return (pil2tensor(ret_image),)
NODE_CLASS_MAPPINGS = {
"LayerStyle_ImageBlend": LayerBlend
}
NODE_DISPLAY_NAME_MAPPINGS = {
"LayerStyle_ImageBlend": "LayerStyle: ImageBlend"
}
+202
View File
@@ -0,0 +1,202 @@
{
"last_node_id": 5,
"last_link_id": 5,
"nodes": [
{
"id": 1,
"type": "LoadImage",
"pos": [
327,
175
],
"size": {
"0": 315,
"1": 314
},
"flags": {},
"order": 0,
"mode": 0,
"outputs": [
{
"name": "IMAGE",
"type": "IMAGE",
"links": [
1
],
"shape": 3,
"slot_index": 0
},
{
"name": "MASK",
"type": "MASK",
"links": null,
"shape": 3
}
],
"properties": {
"Node name for S&R": "LoadImage"
},
"widgets_values": [
"512x512bkgd (3).jpg",
"image"
]
},
{
"id": 2,
"type": "LoadImage",
"pos": [
680,
176
],
"size": {
"0": 315,
"1": 314
},
"flags": {},
"order": 1,
"mode": 0,
"outputs": [
{
"name": "IMAGE",
"type": "IMAGE",
"links": [
2
],
"shape": 3,
"slot_index": 0
},
{
"name": "MASK",
"type": "MASK",
"links": [
5
],
"shape": 3,
"slot_index": 1
}
],
"properties": {
"Node name for S&R": "LoadImage"
},
"widgets_values": [
"512x512 (5).png",
"image"
]
},
{
"id": 3,
"type": "LayerStyle_ImageBlend",
"pos": [
1041,
203
],
"size": {
"0": 315,
"1": 146
},
"flags": {},
"order": 2,
"mode": 0,
"inputs": [
{
"name": "background_image",
"type": "IMAGE",
"link": 1
},
{
"name": "layer_image",
"type": "IMAGE",
"link": 2
},
{
"name": "layer_mask",
"type": "MASK",
"link": 5
}
],
"outputs": [
{
"name": "image",
"type": "IMAGE",
"links": [
4
],
"shape": 3,
"slot_index": 0
}
],
"properties": {
"Node name for S&R": "LayerStyle_ImageBlend"
},
"widgets_values": [
true,
"subtract",
50
]
},
{
"id": 4,
"type": "SaveImage",
"pos": [
1401,
195
],
"size": [
315,
270
],
"flags": {},
"order": 3,
"mode": 0,
"inputs": [
{
"name": "images",
"type": "IMAGE",
"link": 4
}
],
"properties": {},
"widgets_values": [
"ComfyUI"
]
}
],
"links": [
[
1,
1,
0,
3,
0,
"IMAGE"
],
[
2,
2,
0,
3,
1,
"IMAGE"
],
[
4,
3,
0,
4,
0,
"IMAGE"
],
[
5,
2,
1,
3,
2,
"MASK"
]
],
"groups": [],
"config": {},
"extra": {},
"version": 0.4
}