Skip to content

Commit 06e0b5b

Browse files
committed
added the MaskCoverFourCorners node.
1 parent 6d5ec0c commit 06e0b5b

File tree

3 files changed

+72
-2
lines changed

3 files changed

+72
-2
lines changed

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,9 @@ Generates a mask from the face model of the Reactor face swap node output. The m
5151
## MaskAutoSelector
5252
Check the three input masks. If any are available, return the first. If none are available, raise an exception.
5353

54+
## MaskCoverFourCorners
55+
Generates a mask by covering the selected corners with circular edges. This mask can be used as an attention mask to remove watermarks from the corners.
56+
5457
## CheckpointLoaderSimpleWithSwitch
5558
Enhanced the official LoadCheckpoint node by integrating three switches. Each switch controls whether a specific component is loaded. When a switch is turned off, the corresponding component will not be loaded. if you use the extra vae and close the model's vae loading, that will save memory.
5659

nodes.py

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -583,7 +583,72 @@ def get_max_distance(self, keypoints):
583583
max_distance = max(max_distance, distance)
584584

585585
return max_distance
586+
587+
588+
class MaskCoverFourCorners:
589+
590+
@classmethod
591+
def INPUT_TYPES(self):
592+
593+
return {
594+
"required": {
595+
"width": ("INT", {"default": 1024, "min": 0, "max": 8096, "step": 8}),
596+
"height": ("INT", {"default": 1024, "min": 0, "max": 8096, "step": 8}),
597+
"radius": ("INT", {"default": 100, "min": 0, "max": 8096, "step": 5}),
598+
"draw_top_left": ("BOOLEAN", {"default": False}),
599+
"draw_top_right": ("BOOLEAN", {"default": False}),
600+
"draw_bottom_right": ("BOOLEAN", {"default": True}),
601+
"draw_bottom_left": ("BOOLEAN", {"default": False}),
602+
},
603+
"optional": {
604+
"size_as": ("IMAGE",),
605+
}
606+
}
607+
608+
RETURN_TYPES = ("MASK",)
609+
FUNCTION = 'mask_get'
610+
CATEGORY = 'utils/mask'
611+
612+
def mask_get(self, size_as=None, width=1024, height=1024, radius=100,
613+
draw_top_left=False, draw_top_right=False, draw_bottom_right=True, draw_bottom_left=False):
614+
if size_as is not None:
615+
height, width = size_as.shape[-3:-1]
616+
result = self.create_mask_with_arcs(width, height, radius,draw_top_left, draw_top_right,draw_bottom_right,draw_bottom_left)
617+
618+
result = torch.unsqueeze(torch.tensor(np.clip(result/255, 0, 1)), 0)
619+
return (result,)
620+
621+
def create_mask_with_arcs(self, width=None, height=None, radius=50,
622+
draw_top_left=True, draw_top_right=True, draw_bottom_right=True, draw_bottom_left=True):
623+
"""
624+
Creates a mask with circular arcs at the corners.
625+
626+
:param width: Width of the mask.
627+
:param height: Height of the mask.
628+
:param radius: Radius of the circular arcs.
629+
:param draw_top_left: Boolean indicating whether to draw an arc at the top-left corner.
630+
:param draw_top_right: Boolean indicating whether to draw an arc at the top-right corner.
631+
:param draw_bottom_right: Boolean indicating whether to draw an arc at the bottom-right corner.
632+
:param draw_bottom_left: Boolean indicating whether to draw an arc at the bottom-left corner.
633+
:return: Mask image with arcs drawn.
634+
"""
635+
636+
# Create a white mask
637+
mask = np.ones((height, width), dtype=np.uint8) * 255
638+
639+
# Draw arcs on the mask, filling them with black color
640+
if draw_top_left: # Top-left corner
641+
cv2.ellipse(mask, (0, 0), (radius, radius), 0, 0, 90, 0, -1) # Fill with black
642+
if draw_top_right: # Top-right corner
643+
cv2.ellipse(mask, (width, 0), (radius, radius), 0, 90, 180, 0, -1) # Fill with black
644+
if draw_bottom_right: # Bottom-right corner
645+
cv2.ellipse(mask, (width, height), (radius, radius), 0, 180, 270, 0, -1) # Fill with black
646+
if draw_bottom_left: # Bottom-left corner
647+
cv2.ellipse(mask, (0, height), (radius, radius), 0, 0, -90, 0, -1) # Fill with black
648+
649+
return mask
586650

651+
587652
class MaskAutoSelector:
588653
@classmethod
589654
def INPUT_TYPES(self):
@@ -1068,6 +1133,7 @@ def forward(self, image, upscale_model, tile_size=512, threshold_of_xl_area=0.9)
10681133
"MaskFastGrow": MaskFastGrow,
10691134
"MaskAutoSelector": MaskAutoSelector,
10701135
"MaskFromFaceModel": MaskFromFaceModel,
1136+
"MaskCoverFourCorners": MaskCoverFourCorners,
10711137

10721138
#loader
10731139
"CheckpointLoaderSimpleWithSwitch": CheckpointLoaderSimpleWithSwitch,
@@ -1102,6 +1168,7 @@ def forward(self, image, upscale_model, tile_size=512, threshold_of_xl_area=0.9)
11021168
"MaskFastGrow": "Mask Grow Fast",
11031169
"MaskAutoSelector": "Mask Auto Selector",
11041170
"MaskFromFaceModel": "Mask from FaceModel",
1171+
"MaskCoverFourCorners": "Mask Cover Four Corners",
11051172

11061173
# Loader
11071174
"CheckpointLoaderSimpleWithSwitch": "Load Checkpoint with Switch",

pyproject.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
[project]
22
name = "comfyui-utils-nodes"
3-
description = "Nodes:LoadImageWithSwitch, ImageBatchOneOrMore, ModifyTextGender, GenderControlOutput, ImageCompositeMaskedWithSwitch, ColorCorrectOfUtils, SplitMask, MaskFastGrow, CheckpointLoaderSimpleWithSwitch, ImageResizeTo8x, MatchImageRatioToPreset, UpscaleImageWithModelIfNeed, MaskFromFaceModel etc."
4-
version = "1.1.1"
3+
description = "Nodes:LoadImageWithSwitch, ImageBatchOneOrMore, ModifyTextGender, GenderControlOutput, ImageCompositeMaskedWithSwitch, ColorCorrectOfUtils, SplitMask, MaskFastGrow, CheckpointLoaderSimpleWithSwitch, ImageResizeTo8x, MatchImageRatioToPreset, UpscaleImageWithModelIfNeed, MaskFromFaceModel, MaskCoverFourCorners etc."
4+
version = "1.1.2"
55
license = { file = "LICENSE" }
66
dependencies = []
77

0 commit comments

Comments
 (0)