diff --git a/README.MD b/README.MD index 30c1468..7f63279 100644 --- a/README.MD +++ b/README.MD @@ -13,6 +13,9 @@ Nodes are divided into four groups according to their functions: LayerStyle, Lay [中文说明点这里](./README_CN.MD) ## Update +* Add new types of [blend mode](#blend) between images. now supports up to 19 hybrid modes. add **color_burn, color_dodge, linear_burn, linear_dodge, overlay, soft_light, hard_light, vivid_light, pin_light, linear_light** and **hard_mix**. +The newly added hybrid mode is applicable to all nodes that support hybrid mode. +* Commit [ColorMap](#ColorMap) filter node to create a pseudo color heatmap effect. * Commit [WaterColor](#WaterColor) and [SkinBeauty](#SkinBeauty) nodes。These are image filters that generate watercolor and skin smoothness effects. * Commit [ImageShift](#ImageShift) node to shift the image and output a displacement seam mask, making it convenient to create continuous textures. * Commit [ImageMaskScaleAs](#ImageMaskScaleAs) node to adjust the image or mask size based on the reference image. @@ -644,6 +647,16 @@ Node options: * angle: Angle of channel separation. * mode: Channel shift arrangement order. +### ColorMap +Pseudo color heat map effect. +![image](image/colormap_result.png) + +Node options: +![image](image/color_map_node.png) +* color_map: Effect type. there are a total of 22 types of effects, as shown in the above figure. +* opacity: The opacity of the color map effect. + + ### MotionBlur Make the image motion blur ![image](image/motion_blur_example.png) @@ -664,12 +677,16 @@ Node options: 2 The mask not a mandatory input item. the alpha channel of the image is used by default. If the image input does not include an alpha channel, the entire image's alpha channel will be automatically created. if have masks input simultaneously, the alpha channel will be overwrite by the mask. -3 The blend mode include **_normal, multply, screen, add, subtract, difference, darker_** and **_lighter_**. +3 The blend mode include **normal, multply, screen, add, subtract, difference, darker, color_burn, color_dodge, linear_burn, linear_dodge, overlay, soft_light, hard_light, vivid_light, pin_light, linear_light, and hard_mix.** all of 19 blend modes in total. 4 The RGB color described by hexadecimal RGB format, like '#FA3D86'. 5 The layer_image and layer_mask must be of the same size. +3 Preview of the blend mode +![image](image/blend_mode_result.png) + + ## Example workflow image Some JSON workflow files in the workflow directory, that is example for ComfyUI. @@ -683,7 +700,6 @@ LayerFilter: * Contour * Findedge * PhotoStyle -* ColorMap ## How to install diff --git a/README_CN.MD b/README_CN.MD index aa7d132..16497d8 100644 --- a/README_CN.MD +++ b/README_CN.MD @@ -10,6 +10,8 @@ ComfyUI * [LayerFilter](#LayerFilter)½Úµã×éÌṩͼÏñЧ¹ûÂ˾µ¡£ ## ¸üÐÂ˵Ã÷ +* ͼÏñÖ®¼äµÄ[»ìºÏģʽ](#»ìºÏģʽ)Ôö¼ÓÐÂÀàÐÍ£¬ÐÂÔöcolor_burnÑÕÉ«¼ÓÉî, color_dodgeÑÕÉ«¼õµ­, linear_burnÏßÐÔ¼ÓÉî, linear_dodgeÏßÐÔ¼õµ­, overlayµþ¼Ó, soft_lightÈá¹â, hard_lightÇ¿¹â, vivid_lightÁÁ¹â, pin_lightµã¹â, linear_lightÏßÐÔ¹â, hard_mixʵɫ»ìºÏ¡£ÐÂÔöµÄ»ìºÏģʽÊÊÓÃÓÚËùÓÐÖ§³Ö»ìºÏģʽµÄ½Úµã¡£ +* Ìí¼Ó[ColorMap](#ColorMap) Â˾µ½Úµã£¬ÓÃÓÚÖÆ×÷α²ÊÉ«ÈÈÁ¦Í¼Ð§¹û¡£ * Ìí¼Ó[WaterColor](#WaterColor) ºÍ [SkinBeauty](#SkinBeauty) ½Úµã¡£ÕâÊÇÁ½¸öͼÏñÂ˾µ£¬Éú³ÉË®²Ê»­ºÍĥƤЧ¹û¡£ * Ìí¼Ó[ImageShift](#ImageShift) ½Úµã£¬Ê¹Í¼Æ¬²úÉúÎ»ÒÆ£¬¿ÉÊä³öÎ»ÒÆ½Ó·ìÕÚÕÖ£¬·½±ãÖÆ×÷Á¬ÐøÌùͼ¡£ * Ìí¼Ó[ImageMaskScaleAs](#ImageMaskScaleAs) ½Úµã£¬¿É¸ù¾Ý²Î¿¼Í¼Æ¬µ÷ÕûͼÏñ»òÕÚÕÖ´óС¡£ @@ -628,6 +630,15 @@ mask * angle: ͨµÀ·ÖÀëµÄ½Ç¶È¡£ * mode: ͨµÀ´íλÅÅÁÐ˳Ðò¡£ +### ColorMap +α²ÊÉ«ÈÈÁ¦Í¼Ð§¹û¡£ +![image](image/colormap_result.png) + +½ÚµãÑ¡Ïî˵Ã÷: +![image](image/color_map_node.png) +* color_map: Ч¹ûÀàÐÍ¡£¹²22ÖÖ£¬¸÷ÖÖÀàÐ͵ÄЧ¹ûÈçÉÏͼËùʾ¡£ +* opacity: α²ÊɫЧ¹ûµÄ²»Í¸Ã÷¶È¡£ + ### MotionBlur Ô˶¯Ä£ºý¡£ ![image](image/motion_blur_example.png) @@ -646,9 +657,11 @@ mask ## ½Úµã×¢½â 1 image¡¢maskºÍbackground_image(Èç¹ûÓÐÊäÈë)ÕâÈýÏî±ØÐëÊÇÏàͬµÄ³ß´ç¡£ 2 mask²»ÊDZØÐëµÄÊäÈëÏĬÈÏʹÓÃimageµÄalphaͨµÀ£¬Èç¹ûimageÊäÈë²»°üº¬alphaͨµÀ½«×Ô¶¯´´½¨Õû¸öͼÏñµÄalphaͨµÀ¡£Èç¹ûÊäÈëmask£¬Ô­±¾µÄalphaͨµÀ½«±»mask¸²¸Ç¡£ -3 »ìºÏģʽ°üÀ¨normal¡¢multply¡¢screen¡¢add¡¢subtract¡¢difference¡¢darkerºÍlighter¡£ +3 »ìºÏģʽ°üÀ¨normal¡¢multply¡¢screen¡¢add¡¢subtract¡¢difference¡¢darker¡¢lighter¡¢color_burn¡¢color_dodge¡¢linear_burn¡¢linear_dodge¡¢overlay¡¢soft_light¡¢hard_light¡¢vivid_light¡¢pin_light¡¢linear_light¡¢hard_mix¡£ 4 ÑÕɫʹÓÃ16½øÖÆRGB×Ö·û´®¸ñʽÃèÊö£¬ÀýÈç '#FA3D86'¡£ 5 imageºÍmaskÕâÁ½Ïî±ØÐëÊÇÏàͬµÄ³ß´ç¡£ +3 »ìºÏģʽԤÀÀ +![image](image/blend_mode_result.png) ## ʹÓÃʾÀý @@ -663,7 +676,7 @@ LayerFilter: * Emboss * Contour * Findedge -* ColorMap + ## °²×°·½·¨ diff --git a/image/blend_mode_result.png b/image/blend_mode_result.png new file mode 100644 index 0000000..64c955c Binary files /dev/null and b/image/blend_mode_result.png differ diff --git a/image/color_map_node.png b/image/color_map_node.png new file mode 100644 index 0000000..ad0bfc6 Binary files /dev/null and b/image/color_map_node.png differ diff --git a/image/colormap_result.png b/image/colormap_result.png new file mode 100644 index 0000000..3e42aa8 Binary files /dev/null and b/image/colormap_result.png differ diff --git a/py/color_map.py b/py/color_map.py new file mode 100644 index 0000000..2e6a1f9 --- /dev/null +++ b/py/color_map.py @@ -0,0 +1,47 @@ +from .imagefunc import * + +colormap_list = ['autumn', 'bone', 'jet', 'winter', 'rainbow', 'ocean', + 'summer', 'sprint', 'cool', 'HSV', 'pink', 'hot', + 'parula', 'magma', 'inferno', 'plasma', 'viridis', 'cividis', + 'twilight', 'twilight_shifted', 'turbo', 'deepgreen'] + +class ColorMap: + + def __init__(self): + pass + + @classmethod + def INPUT_TYPES(self): + + return { + "required": { + "image": ("IMAGE", ), + "color_map": (colormap_list,), + "opacity": ("INT", {"default": 100, "min": 0, "max": 100, "step": 1}), # é€�明度 + }, + "optional": { + } + } + + RETURN_TYPES = ("IMAGE",) + RETURN_NAMES = ("image",) + FUNCTION = 'color_map' + CATEGORY = '😺dzNodes/LayerFilter' + OUTPUT_NODE = True + + def color_map(self, image, color_map, opacity + ): + + _canvas = tensor2pil(image) + _image = image_to_colormap(_canvas, colormap_list.index(color_map)) + ret_image = chop_image(_canvas, _image, 'normal', opacity) + + return (pil2tensor(ret_image),) + +NODE_CLASS_MAPPINGS = { + "LayerFilter: ColorMap": ColorMap +} + +NODE_DISPLAY_NAME_MAPPINGS = { + "LayerFilter: ColorMap": "LayerFilter: ColorMap" +} \ No newline at end of file diff --git a/py/color_overlay.py b/py/color_overlay.py index d1223d9..d4dcb5d 100644 --- a/py/color_overlay.py +++ b/py/color_overlay.py @@ -7,7 +7,7 @@ class ColorOverlay: @classmethod def INPUT_TYPES(self): - chop_mode = ['normal','multply','screen','add','subtract','difference','darker','lighter'] + return { "required": { "background_image": ("IMAGE", ), # diff --git a/py/drop_shadow.py b/py/drop_shadow.py index 85adb45..881b7dc 100644 --- a/py/drop_shadow.py +++ b/py/drop_shadow.py @@ -7,7 +7,7 @@ class DropShadow: @classmethod def INPUT_TYPES(self): - chop_mode = ['normal','multply','screen','add','subtract','difference','darker','lighter'] + return { "required": { "background_image": ("IMAGE", ), # diff --git a/py/get_color_tone.py b/py/get_color_tone.py index b045a01..04244fa 100644 --- a/py/get_color_tone.py +++ b/py/get_color_tone.py @@ -17,8 +17,8 @@ class GetColorTone: } } - RETURN_TYPES = ("STRING",) - RETURN_NAMES = ("RGB color in HEX",) + RETURN_TYPES = ("STRING", "LIST") + RETURN_NAMES = ("RGB color in HEX", "HSV color in list") FUNCTION = 'get_color_tone' CATEGORY = '😺dzNodes/LayerUtility' OUTPUT_NODE = True @@ -31,8 +31,9 @@ class GetColorTone: ret_color = get_image_color_tone(_canvas) else: ret_color = get_image_color_average(_canvas) + hsv_color = RGB_to_HSV(Hex_to_RGB(ret_color)) - return (ret_color,) + return (ret_color, hsv_color) NODE_CLASS_MAPPINGS = { "LayerUtility: GetColorTone": GetColorTone diff --git a/py/gradient_overlay.py b/py/gradient_overlay.py index e671a74..af567ce 100644 --- a/py/gradient_overlay.py +++ b/py/gradient_overlay.py @@ -7,7 +7,7 @@ class GradientOverlay: @classmethod def INPUT_TYPES(self): - chop_mode = ['normal','multply','screen','add','subtract','difference','darker','lighter'] + return { "required": { "background_image": ("IMAGE", ), # @@ -62,7 +62,7 @@ class GradientOverlay: # start_color = RGB_to_Hex((start_alpha, start_alpha, start_alpha)) end_color = RGB_to_Hex((end_alpha, end_alpha, end_alpha)) - comp_alpha = gradint(start_color, end_color, _layer.width, _layer.height, float(angle)) + comp_alpha = gradient(start_color, end_color, _layer.width, _layer.height, float(angle)) comp_alpha = ImageChops.invert(comp_alpha).convert('L') _comp.paste(_layer, comp_alpha) _canvas.paste(_comp, mask=_mask) diff --git a/py/image_blend.py b/py/image_blend.py index 6681602..a989d3f 100644 --- a/py/image_blend.py +++ b/py/image_blend.py @@ -7,7 +7,7 @@ class ImageBlend: @classmethod def INPUT_TYPES(self): - chop_mode = ['normal','multply','screen','add','subtract','difference','darker','lighter'] + return { "required": { "background_image": ("IMAGE", ), # diff --git a/py/image_blend_advance.py b/py/image_blend_advance.py index b3eacf5..f2fef2e 100644 --- a/py/image_blend_advance.py +++ b/py/image_blend_advance.py @@ -8,7 +8,7 @@ class ImageBlendAdvance: @classmethod def INPUT_TYPES(self): - chop_mode = ['normal','multply','screen','add','subtract','difference','darker','lighter'] + mirror_mode = ['None', 'horizontal', 'vertical'] method_mode = ['lanczos', 'bicubic', 'hamming', 'bilinear', 'box', 'nearest'] return { diff --git a/py/imagefunc.py b/py/imagefunc.py index 9b1a28e..bd868ed 100644 --- a/py/imagefunc.py +++ b/py/imagefunc.py @@ -9,6 +9,7 @@ import scipy.ndimage import cv2 from typing import Union, List from PIL import Image, ImageFilter, ImageChops, ImageDraw, ImageOps +from skimage import img_as_float, img_as_ubyte import colorsys def log(message): @@ -17,6 +18,12 @@ def log(message): '''Converter''' +def cv22ski(cv2_image:np.ndarray) -> np.array: + return img_as_float(cv2_image) + +def ski2cv2(ski:np.array) -> np.ndarray: + return img_as_ubyte(ski) + def cv22pil(cv2_img:np.ndarray) -> Image: cv2_img = cv2.cvtColor(cv2_img, cv2.COLOR_BGR2RGB) return Image.fromarray(cv2_img) @@ -61,6 +68,145 @@ def mask2image(mask:torch.Tensor) -> Image: '''Image Functions''' +# 颜色加深 +def blend_color_burn(background_image:Image, layer_image:Image) -> Image: + img_1 = cv22ski(pil2cv2(background_image)) + img_2 = cv22ski(pil2cv2(layer_image)) + img = 1 - (1 - img_2) / (img_1 + 0.001) + mask_1 = img < 0 + mask_2 = img > 1 + img = img * (1 - mask_1) + img = img * (1 - mask_2) + mask_2 + return cv22pil(ski2cv2(img)) + +# 颜色å‡�æ·¡ +def blend_color_dodge(background_image:Image, layer_image:Image) -> Image: + img_1 = cv22ski(pil2cv2(background_image)) + img_2 = cv22ski(pil2cv2(layer_image)) + img = img_2 / (1.0 - img_1 + 0.001) + mask_2 = img > 1 + img = img * (1 - mask_2) + mask_2 + return cv22pil(ski2cv2(img)) + +# 线性加深 +def blend_linear_burn(background_image:Image, layer_image:Image) -> Image: + img_1 = cv22ski(pil2cv2(background_image)) + img_2 = cv22ski(pil2cv2(layer_image)) + img = img_1 + img_2 - 1 + mask_1 = img < 0 + img = img * (1 - mask_1) + return cv22pil(ski2cv2(img)) + +# 线性å‡�æ·¡ +def blend_linear_dodge(background_image:Image, layer_image:Image) -> Image: + img_1 = cv22ski(pil2cv2(background_image)) + img_2 = cv22ski(pil2cv2(layer_image)) + img = img_1 + img_2 + mask_2 = img > 1 + img = img * (1 - mask_2) + mask_2 + return cv22pil(ski2cv2(img)) + +# å�˜äº® +def blend_lighten(background_image:Image, layer_image:Image) -> Image: + img_1 = cv22ski(pil2cv2(background_image)) + img_2 = cv22ski(pil2cv2(layer_image)) + img = img_1 - img_2 + mask = img > 0 + img = img_1 * mask + img_2 * (1 - mask) + return cv22pil(ski2cv2(img)) + +# å�˜æš— +def blend_dark(background_image:Image, layer_image:Image) -> Image: + img_1 = cv22ski(pil2cv2(background_image)) + img_2 = cv22ski(pil2cv2(layer_image)) + img = img_1 - img_2 + mask = img < 0 + img = img_1 * mask + img_2 * (1 - mask) + return cv22pil(ski2cv2(img)) + +# 滤色 +def blend_screen(background_image:Image, layer_image:Image) -> Image: + img_1 = cv22ski(pil2cv2(background_image)) + img_2 = cv22ski(pil2cv2(layer_image)) + img = 1 - (1 - img_1) * (1 - img_2) + return cv22pil(ski2cv2(img)) + +# å� åŠ  +def blend_overlay(background_image:Image, layer_image:Image) -> Image: + img_1 = cv22ski(pil2cv2(background_image)) + img_2 = cv22ski(pil2cv2(layer_image)) + mask = img_2 < 0.5 + img = 2 * img_1 * img_2 * mask + (1 - mask) * (1 - 2 * (1 - img_1) * (1 - img_2)) + return cv22pil(ski2cv2(img)) + +# 柔光 +def blend_soft_light(background_image:Image, layer_image:Image) -> Image: + img_1 = cv22ski(pil2cv2(background_image)) + img_2 = cv22ski(pil2cv2(layer_image)) + mask = img_1 < 0.5 + T1 = (2 * img_1 - 1) * (img_2 - img_2 * img_2) + img_2 + T2 = (2 * img_1 - 1) * (np.sqrt(img_2) - img_2) + img_2 + img = T1 * mask + T2 * (1 - mask) + return cv22pil(ski2cv2(img)) + +# 强光 +def blend_hard_light(background_image:Image, layer_image:Image) -> Image: + img_1 = cv22ski(pil2cv2(background_image)) + img_2 = cv22ski(pil2cv2(layer_image)) + mask = img_1 < 0.5 + T1 = 2 * img_1 * img_2 + T2 = 1 - 2 * (1 - img_1) * (1 - img_2) + img = T1 * mask + T2 * (1 - mask) + return cv22pil(ski2cv2(img)) + +# 亮光 +def blend_vivid_light(background_image:Image, layer_image:Image) -> Image: + img_1 = cv22ski(pil2cv2(background_image)) + img_2 = cv22ski(pil2cv2(layer_image)) + mask = img_1 < 0.5 + T1 = 1 - (1 - img_2) / (2 * img_1 + 0.001) + T2 = img_2 / (2 * (1 - img_1) + 0.001) + mask_1 = T1 < 0 + mask_2 = T2 > 1 + T1 = T1 * (1 - mask_1) + T2 = T2 * (1 - mask_2) + mask_2 + img = T1 * mask + T2 * (1 - mask) + return cv22pil(ski2cv2(img)) + +# 点光 +def blend_pin_light(background_image:Image, layer_image:Image) -> Image: + img_1 = cv22ski(pil2cv2(background_image)) + img_2 = cv22ski(pil2cv2(layer_image)) + mask_1 = img_2 < (img_1 * 2 - 1) + mask_2 = img_2 > 2 * img_1 + T1 = 2 * img_1 - 1 + T2 = img_2 + T3 = 2 * img_1 + img = T1 * mask_1 + T2 * (1 - mask_1) * (1 - mask_2) + T3 * mask_2 + return cv22pil(ski2cv2(img)) + +# 线性光 +def blend_linear_light(background_image:Image, layer_image:Image) -> Image: + img_1 = cv22ski(pil2cv2(background_image)) + img_2 = cv22ski(pil2cv2(layer_image)) + img = img_2 + img_1 * 2 - 1 + mask_1 = img < 0 + mask_2 = img > 1 + img = img * (1 - mask_1) + img = img * (1 - mask_2) + mask_2 + return cv22pil(ski2cv2(img)) + + +def blend_hard_mix(background_image:Image, layer_image:Image) -> Image: + img_1 = cv22ski(pil2cv2(background_image)) + img_2 = cv22ski(pil2cv2(layer_image)) + img = img_1 + img_2 + mask = img_1 + img_2 > 1 + img = img * (1 - mask) + mask + img = img * mask + return cv22pil(ski2cv2(img)) + + def shift_image(image:Image, distance_x:int, distance_y:int, background_color:str='#000000', cyclic:bool=False) -> Image: width = image.width height = image.height @@ -102,6 +248,30 @@ def chop_image(background_image:Image, layer_image:Image, blend_mode:str, opacit ret_image = ImageChops.darker(background_image, layer_image) if blend_mode == 'lighter': ret_image = ImageChops.lighter(background_image, layer_image) + if blend_mode == 'color_burn': + ret_image = blend_color_burn(background_image, layer_image) + if blend_mode == 'color_dodge': + ret_image = blend_color_dodge(background_image, layer_image) + if blend_mode == 'linear_burn': + ret_image = blend_linear_burn(background_image, layer_image) + if blend_mode == 'linear_dodge': + ret_image = blend_linear_dodge(background_image, layer_image) + if blend_mode == 'overlay': + ret_image = blend_overlay(background_image, layer_image) + if blend_mode == 'soft_light': + ret_image = blend_soft_light(background_image, layer_image) + if blend_mode == 'hard_light': + ret_image = blend_hard_light(background_image, layer_image) + if blend_mode == 'vivid_light': + ret_image = blend_vivid_light(background_image, layer_image) + if blend_mode == 'pin_light': + ret_image = blend_pin_light(background_image, layer_image) + if blend_mode == 'linear_light': + ret_image = blend_linear_light(background_image, layer_image) + if blend_mode == 'hard_mix': + ret_image = blend_hard_mix(background_image, layer_image) + + # opacity if opacity == 0: ret_image = background_image @@ -410,7 +580,6 @@ def lut_apply(image:Image, lut_file:str) -> Image: _image.putpixel((x, y), new_pixel) return _image - def color_adapter(image:Image, ref_image:Image) -> Image: image = pil2cv2(image) ref_image = pil2cv2(ref_image) @@ -556,6 +725,8 @@ def gray_threshold(image:Image, thresh:int=127, otsu:bool=False) -> Image: return cv22pil(thresh).convert('L') +def image_to_colormap(image:Image, index:int) -> Image: + return cv22pil(cv2.applyColorMap(pil2cv2(image), index)) '''Color Functions''' @@ -573,6 +744,10 @@ def Hex_to_RGB(inhex) -> tuple: rgb = (int(rval, 16), int(gval, 16), int(bval, 16)) return tuple(rgb) +def RGB_to_HSV(RGB:tuple) -> list: + HSV = colorsys.rgb_to_hsv(RGB[0] / 255.0, RGB[1] / 255.0, RGB[2] / 255.0) + return [int(x * 360) for x in HSV] + '''Value Functions''' def step_value(start_value, end_value, total_step, step) -> float: # 按当å‰�步数在总步数中的ä½�置返回比例值 @@ -604,4 +779,10 @@ def has_letters(string:str) -> bool: class AnyType(str): """A special class that is always equal in not equal comparisons. Credit to pythongosssss""" def __ne__(self, __value: object) -> bool: - return False \ No newline at end of file + return False + +'''Constant''' + +chop_mode = ['normal', 'multply', 'screen', 'add', 'subtract', 'difference', 'darker', 'lighter', + 'color_burn', 'color_dodge', 'linear_burn', 'linear_dodge', 'overlay', + 'soft_light', 'hard_light', 'vivid_light', 'pin_light', 'linear_light', 'hard_mix'] \ No newline at end of file diff --git a/py/inner_glow.py b/py/inner_glow.py index e6db05e..f136e4e 100644 --- a/py/inner_glow.py +++ b/py/inner_glow.py @@ -7,7 +7,9 @@ class InnerGlow: @classmethod def INPUT_TYPES(self): - chop_mode = ['screen', 'add', 'lighter', 'normal', 'multply', 'subtract','difference','darker'] + chop_mode = ['screen', 'add', 'lighter', 'normal', 'multply', 'subtract','difference','darker', + 'color_burn', 'color_dodge', 'linear_burn', 'linear_dodge', 'overlay', + 'soft_light', 'hard_light', 'vivid_light', 'pin_light', 'linear_light', 'hard_mix'] return { "required": { "background_image": ("IMAGE", ), # diff --git a/py/inner_shadow.py b/py/inner_shadow.py index 35cc20d..1d326d2 100644 --- a/py/inner_shadow.py +++ b/py/inner_shadow.py @@ -7,7 +7,7 @@ class InnerShadow: @classmethod def INPUT_TYPES(self): - chop_mode = ['normal','multply','screen','add','subtract','difference','darker','lighter'] + return { "required": { "background_image": ("IMAGE", ), # diff --git a/py/outer_glow.py b/py/outer_glow.py index f13b74d..582fd9b 100644 --- a/py/outer_glow.py +++ b/py/outer_glow.py @@ -7,7 +7,9 @@ class OuterGlow: @classmethod def INPUT_TYPES(self): - chop_mode = ['screen', 'add', 'lighter', 'normal', 'multply', 'subtract','difference','darker'] + chop_mode = ['screen', 'add', 'lighter', 'normal', 'multply', 'subtract', 'difference', 'darker', + 'color_burn', 'color_dodge', 'linear_burn', 'linear_dodge', 'overlay', + 'soft_light', 'hard_light', 'vivid_light', 'pin_light', 'linear_light', 'hard_mix'] return { "required": { "background_image": ("IMAGE", ), # diff --git a/py/stroke.py b/py/stroke.py index 1ad7374..b2c46fa 100644 --- a/py/stroke.py +++ b/py/stroke.py @@ -7,7 +7,7 @@ class Stroke: @classmethod def INPUT_TYPES(self): - chop_mode = ['normal','multply','screen','add','subtract','difference','darker','lighter'] + return { "required": { "background_image": ("IMAGE", ), # diff --git a/requirements.txt b/requirements.txt index eed1d98..2bd74b9 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,4 +3,5 @@ pillow torch matplotlib Scipy -opencv-python \ No newline at end of file +opencv-python +scikit_image \ No newline at end of file