diff --git a/README.MD b/README.MD index 0e01516..15452ae 100644 --- a/README.MD +++ b/README.MD @@ -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: 1 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: 1 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_image1: The background image. +* layer_image1: Layer image for composite. +* layer_mask1: 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. + + +1 The layer_image, layer_mask and the background_image, These three items must be of the same size.。 + +Output type: * image ## Example workflow diff --git a/README_CN.MD b/README_CN.MD index 5ab602c..9bf7f1c 100644 --- a/README_CN.MD +++ b/README_CN.MD @@ -3,7 +3,9 @@ ComfyUI µ±Ç°ÒÑÍê³ÉDrop ShadowºÍOuterGlow½Úµã£¬ºóÐø¹¤×÷½øÐÐÖС£ ## ¸üÐÂ˵Ã÷£º -DropShadow½ÚµãÈ¥µôµ÷ÊÔmaskͨµÀÊä³ö£»Ìí¼ÓOuterGlow½Úµã¡£ +* Ìí¼ÓImageBlend½Úµã +* DropShadow½ÚµãÈ¥µôµ÷ÊÔmaskͨµÀÊä³ö£»Ìí¼ÓOuterGlow½Úµã¡£ +* DropShadow½ÚµãÉÏÏß¡£ ## ½Úµã˵Ã÷£º @@ -19,7 +21,7 @@ DropShadow * layer_image1: ÓÃÓںϳɵIJãͼÏñ¡£ * layer_mask1: ²ãͼÏñµÄÕÚÕÖ£¬ÒõÓ°°´´ËÉú³É¡£ * 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_image1: ±³¾°Í¼Ïñ¡£ * layer_image1: ÓÃÓںϳɵIJãͼÏñ¡£ -* layer_mask1: ²ãͼÏñµÄÕÚÕÖ£¬ÒõÓ°°´´ËÉú³É¡£ +* layer_mask1: ²ãͼÏñµÄÕÚÕÖ£¬Íâ·¢¹â°´´ËÉú³É¡£ * 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¸ñʽÃèÊö¡£ 1 background_image, layer_image, layer_maskÕâÈýÏî±ØÐëÊÇÏàͬµÄ³ß´ç¡£ Êä³ö£º * image +### ImageBlend£º +ÓÃÓںϳÉͼ²ã£¬Ìṩ¶àÖÖ»ìºÏģʽ¹©Ñ¡Ôñ£¬¿ÉÉèÖÃ͸Ã÷¶È¡£ +![image](image/image_blend_example.png) + +½ÚµãÑ¡Ïî˵Ã÷£º +![image](image/image_blend_node.png) +* background_image1: ±³¾°Í¼Ïñ¡£ +* layer_image1: ÓÃÓںϳɵIJãͼÏñ¡£ +* layer_mask1: ²ãͼÏñµÄÕÚÕÖ¡£ +* invert_mask: ÊÇ·ñ·´×ªÕÚÕÖ¡£ +* blend_mode: ͼ²ã»ìºÏģʽ£¬°üÀ¨normal¡¢multply¡¢screen¡¢add¡¢subtract¡¢difference¡¢darkerºÍlighter¡£ +* opacity: ²»Í¸Ã÷¶È¡£ + + +1 background_image, layer_image, layer_maskÕâÈýÏî±ØÐëÊÇÏàͬµÄ³ß´ç¡£ + +Êä³ö£º +* image ## ʹÓÃʾÀý£º diff --git a/image/image_blend_example.png b/image/image_blend_example.png new file mode 100644 index 0000000..4340488 Binary files /dev/null and b/image/image_blend_example.png differ diff --git a/image/image_blend_node.png b/image/image_blend_node.png new file mode 100644 index 0000000..bc77c2d Binary files /dev/null and b/image/image_blend_node.png differ diff --git a/py/__pycache__/layer_blend.cpython-311.pyc b/py/__pycache__/layer_blend.cpython-311.pyc new file mode 100644 index 0000000..4b6389a Binary files /dev/null and b/py/__pycache__/layer_blend.cpython-311.pyc differ diff --git a/py/__pycache__/outer_glow.cpython-311.pyc b/py/__pycache__/outer_glow.cpython-311.pyc index ca2d2f3..e240113 100644 Binary files a/py/__pycache__/outer_glow.cpython-311.pyc and b/py/__pycache__/outer_glow.cpython-311.pyc differ diff --git a/py/layer_blend.py b/py/layer_blend.py new file mode 100644 index 0000000..d08a48a --- /dev/null +++ b/py/layer_blend.py @@ -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" +} \ No newline at end of file diff --git a/workflow/image_blend_example.json b/workflow/image_blend_example.json new file mode 100644 index 0000000..8eddc19 --- /dev/null +++ b/workflow/image_blend_example.json @@ -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 +} \ No newline at end of file