EmAySee Mask Expand Shrink XY
Grow or shrink a mask — with independent X and Y
- mask
- MASK
The one mask node you'll actually use in every inpaint job
Mask expansion is the most boring, most necessary operation in inpainting. You select a region, the selection hugs the subject too tightly, you want it to bleed outward so the regeneration has room to blend - or you want it pulled inward so the fix doesn't spill into the background. EmAySee_MaskExpandShrinkXY does both directions, and it lets you control X and Y separately, which is the part that makes it a keeper.
Why separate axes matter: a person is usually wider than they are tall in feature terms - grow a face-selection mask horizontally but not vertically and you get a better-shaped inpaint region. In the mask-based inpainting world, edge quality is everything, and expanding the masked area is the standard trick for avoiding hard seams after denoising. This node is the "feather by geometry" complement to actual mask blur: blur softens the edge, this changes the boundary.
How it works
Positive values dilate, negative values erode, each axis independently. Expansion is a max_pool2d with a kernel sized 2n+1 - classic morphological dilation that grows the white region by n pixels. Shrinking inverts the trick: it max-pools the inverted mask (1 - max_pool(1 - mask)) and inverts back, which erodes the boundary by n pixels. Zero on both axes returns the mask untouched. It's the same machinery core ComfyUI's GrowMask uses, just with the X/Y split exposed instead of one uniform value.
Inputs and output
mask(MASK) - the selection.expand_x(INT, −1024 to 1024, default 0) - pixels to grow (positive) or shrink (negative) horizontally.expand_y(INT, −1024 to 1024, default 0) - same, vertically.
Output: MASK - the modified mask.
Install
From ComfyUI_EmAySee_CustomNodes:
cd ComfyUI/custom_nodes
git clone https://github.com/EmAySee/ComfyUI_EmAySee_CustomNodes
# restart ComfyUI
Or via ComfyUI Manager → "ComfyUI_EmAySee_CustomNodes". No dependencies.
Gotchas
Dilation-based expansion grows in pixels at the mask's resolution - if your mask is at latent resolution, 8px of expansion is 8 latent px, not 8 output px, so scale your values accordingly. Also, hard-edged max-pool growth can leave the boundary square/blocky; pair with a blur/feather to soften it. There's a sibling node, EmAySee_MaskExpandXY, that only does the positive direction (min 0) - if you never shrink, that one is marginally simpler, but since this node handles both with the same two inputs, there's little reason to reach for the limited twin.
Inputs (3)
| Name | Type | Default | Description |
|---|---|---|---|
| mask | MASK | — | |
| expand_x | INT | 0-1024–1024 | — |
| expand_y | INT | 0-1024–1024 | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| MASK | MASK | — |