From ef11980aa13b8c1a9f371394968e9bf846d6b637 Mon Sep 17 00:00:00 2001 From: chflame163 <130118553+chflame163@users.noreply.github.com> Date: Thu, 18 Jan 2024 22:15:51 +0800 Subject: [PATCH] add ImageOpacity node --- README.MD | 14 ++++++++++ README_CN.MD | 17 +++++++++++- py/image_opacity.py | 63 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 93 insertions(+), 1 deletion(-) create mode 100644 py/image_opacity.py diff --git a/README.MD b/README.MD index 3edc113..83dbf71 100644 --- a/README.MD +++ b/README.MD @@ -81,6 +81,20 @@ Node options: Output type: * image +### ImageOpacity: +Adjust image opacity +![image](image/image_opacity_example.png) + +Node option: +* image: Image input, supporting RGB and RGBA. if is RGB, the alpha channel of the entire image will be automatically added. +* mask: Mask input. Attention that if the image input has alpha channel and different masks are input simultaneously, the original alpha channel will be overwritten by the mask. +* invert_mask: Whether to reverse the mask. +* opacity: Opacity of image. + +Output type: +* image(RGBA) +* mask + ## Example workflow image Some JSON workflow files in the workflow directory, that is example for ComfyUI. diff --git a/README_CN.MD b/README_CN.MD index 6501ede..d7a4a0a 100644 --- a/README_CN.MD +++ b/README_CN.MD @@ -3,7 +3,8 @@ ComfyUI µ±Ç°ÒÑÍê³ÉDrop ShadowºÍOuterGlow½Úµã£¬ºóÐø¹¤×÷½øÐÐÖС£ ## ¸üÐÂ˵Ã÷£º -* ÏÖÔÚlayer_mask²»ÊÇÊäÈë±ØÑ¡¡£²»ÊäÈ뽫ʹÓÃlayer_imageµÄalphaͨµÀ¡£ÔÊÐíʹÓÃÐÎ×´²»Í¬µÄlayerºÍmask£¬µ«ÊÇ³ß´ç±ØÐëÒ»Ö¡£ +* Ìí¼ÓImageOpacity½Úµã¡£ +* layer_mask²»ÊÇÊäÈë±ØÑ¡¡£²»ÊäÈ뽫ʹÓÃlayer_imageµÄalphaͨµÀ¡£ÔÊÐíʹÓÃÐÎ×´²»Í¬µÄlayerºÍmask£¬µ«ÊÇ³ß´ç±ØÐëÒ»Ö¡£ ![image](image/title.png) * Ìí¼ÓImageBlend½Úµã * DropShadow½ÚµãÈ¥µôµ÷ÊÔmaskͨµÀÊä³ö£»Ìí¼ÓOuterGlow½Úµã¡£ @@ -76,6 +77,20 @@ ComfyUI Êä³ö£º * image +### ImageOpacity£º +µ÷ÕûͼÏñ²»Í¸Ã÷¶È¡£ +![image](image/image_opacity_example.png) + +½ÚµãÑ¡Ïî˵Ã÷£º +* image: ͼÏñÊäÈ룬֧³ÖRGBºÍRGBAÊäÈë¡£Èç¹ûÊäÈëµÄÊÇRGB£¬½«×Ô¶¯Ìí¼ÓÕû¸öͼÏñµÄalphaͨµÀ¡£ +* mask: ÕÚÕÖÊäÈë¡£×¢ÒâÈç¹ûimageÊäÈëÓÐalphaͨµÀÇÒͬʱÊäÈëÁ˲»Í¬µÄmask£¬Ô­±¾µÄalphaͨµÀ½«±»mask¸²¸Ç¡£ +* invert_mask: ÊÇ·ñ·´×ªÕÚÕÖ¡£ +* opacity: ²»Í¸Ã÷¶È¡£ + +Êä³ö£º +* image(RGBA) +* mask + ## ʹÓÃʾÀý£º ÔÚworkflowĿ¼ÏÂÓÐjson¸ñʽµÄ¹¤×÷Á÷ʾÀýÎļþ¡£ diff --git a/py/image_opacity.py b/py/image_opacity.py new file mode 100644 index 0000000..2fe5e41 --- /dev/null +++ b/py/image_opacity.py @@ -0,0 +1,63 @@ +from .imagefunc import * + +class ImageOpacity: + + def __init__(self): + pass + + @classmethod + def INPUT_TYPES(self): + + return { + "required": { + "image": ("IMAGE", ), # + "opacity": ("INT", {"default": 100, "min": 0, "max": 100, "step": 1}), # é€�明度 + "invert_mask": ("BOOLEAN", {"default": True}), # å��转mask + }, + "optional": { + "mask": ("MASK",), # + } + } + + RETURN_TYPES = ("IMAGE", "MASK",) + RETURN_NAMES = ("image", "mask",) + FUNCTION = 'image_opacity' + CATEGORY = '😺dzNodes' + OUTPUT_NODE = True + + def image_opacity(self, image, opacity, invert_mask, + mask=None, + ): + + _image = tensor2pil(image).convert('RGB') + _mask = tensor2pil(image).convert('RGBA').split()[-1] + if mask is not None: + _mask = mask2image(mask).convert('L') + + # 设置é€�明度 + if invert_mask: + _color = Image.new("L", _image.size, color=(255)) + else: + _color = Image.new("L", _image.size, color=(0)) + # opacity + ret_mask = _mask + if opacity == 0: + ret_mask = _color + elif opacity < 100: + alpha = 1.0 - float(opacity) / 100 + ret_mask = Image.blend(_mask, _color, alpha) + R, G, B, = _image.split() + if invert_mask: + ret_image = Image.merge('RGBA', (R, G, B, ImageChops.invert(ret_mask))) + else: + ret_image = Image.merge('RGBA', (R, G, B, ret_mask)) + + return (pil2tensor(ret_image), image2mask(ret_mask),) + +NODE_CLASS_MAPPINGS = { + "LayerStyle_ImageOpacity": ImageOpacity +} + +NODE_DISPLAY_NAME_MAPPINGS = { + "LayerStyle_ImageOpacity": "LayerStyle: ImageOpacity" +} \ No newline at end of file