LayerMask: MaskStroke¶
Documentation¶
- Class name:
LayerMask: MaskStroke
- Category:
😺dzNodes/LayerMask
- Output node:
False
The MaskStroke node is designed to process image masks by applying transformations such as inversion, growth, width adjustment, and blurring to create stylized stroke effects around the mask's edges. It's aimed at enhancing visual elements by dynamically modifying mask boundaries for artistic or design purposes.
Input types¶
Required¶
mask
- The 'mask' parameter represents the input image mask to be transformed. It is crucial for defining the area where stroke effects will be applied, serving as the base for subsequent modifications.
- Comfy dtype:
MASK
- Python dtype:
torch.Tensor
invert_mask
- The 'invert_mask' parameter allows for the inversion of the input mask, flipping the areas to be considered as the foreground and background. This inversion is essential for achieving desired visual effects based on the mask's context.
- Comfy dtype:
BOOLEAN
- Python dtype:
bool
stroke_grow
- Specifies the growth or shrinkage of the stroke's inner boundary, adjusting the mask's coverage area before applying the stroke width. It's key for fine-tuning the effect's intensity and reach.
- Comfy dtype:
INT
- Python dtype:
int
stroke_width
- Determines the thickness of the stroke applied around the mask's edges, directly influencing the visual prominence of the stroke effect.
- Comfy dtype:
INT
- Python dtype:
int
blur
- Controls the level of blur applied to the stroke, smoothing the edges for a more refined or subtle effect.
- Comfy dtype:
INT
- Python dtype:
int
Optional¶
Output types¶
mask
- Comfy dtype:
MASK
- The transformed mask with the applied stroke effect, showcasing the adjustments made to the original mask through inversion, growth, width modification, and blurring.
- Python dtype:
torch.Tensor
- Comfy dtype:
Usage tips¶
- Infra type:
GPU
- Common nodes: unknown
Source code¶
class MaskStroke:
def __init__(self):
pass
@classmethod
def INPUT_TYPES(self):
return {
"required": {
"mask": ("MASK", ), #
"invert_mask": ("BOOLEAN", {"default": True}), # 反转mask
"stroke_grow": ("INT", {"default": 0, "min": -999, "max": 999, "step": 1}), # 收缩值
"stroke_width": ("INT", {"default": 20, "min": 0, "max": 999, "step": 1}), # 扩张值
"blur": ("INT", {"default": 6, "min": 0, "max": 100, "step": 1}), # 模糊
},
"optional": {
}
}
RETURN_TYPES = ("MASK",)
RETURN_NAMES = ("mask",)
FUNCTION = 'mask_stroke'
CATEGORY = '😺dzNodes/LayerMask'
def mask_stroke(self, mask, invert_mask, stroke_grow, stroke_width, blur,):
l_masks = []
ret_masks = []
if mask.dim() == 2:
mask = torch.unsqueeze(mask, 0)
for m in mask:
if invert_mask:
m = 1 - m
l_masks.append(tensor2pil(torch.unsqueeze(m, 0)).convert('L'))
for i in range(len(l_masks)):
_mask = l_masks[i]
grow_offset = int(stroke_width / 2)
inner_stroke = stroke_grow - grow_offset
outer_stroke = inner_stroke + stroke_width
inner_mask = expand_mask(image2mask(_mask), inner_stroke, blur)
outer_mask = expand_mask(image2mask(_mask), outer_stroke, blur)
stroke_mask = subtract_mask(outer_mask, inner_mask)
ret_masks.append(stroke_mask)
log(f"{NODE_NAME} Processed {len(ret_masks)} mask(s).", message_type='finish')
return (torch.cat(ret_masks, dim=0),)