Whisker: Shape Mask
Shape Mask — build a mask from numbers, not brush strokes
- image
- mask
Most masks in ComfyUI arrive from somewhere else. A detector draws a box around a face, BiRefNet predicts a foreground alpha, or you open the mask editor and paint with a mouse. All of that is overkill when you already know the region geometrically - the bottom strip where burned-in subtitles live, the circle you want for an avatar crop, the band of canvas the light is supposed to come from. Whisker: Shape Mask exists for exactly that case: you give it pixel numbers, it hands you a mask.
What you actually get
Two outputs. The mask is flat 1.0 inside the shape and 0.0 everywhere else - a clean, deterministic region selector you can wire into an inpaint path, a MaskComposite, or a latent noise mask. The image is the same shape painted white over bg_color, so with the default #000000 you get the classic white-on-black plate that people used to hand-draw for ControlNet tests and quick img2img sanity checks.
It's a light utility, not a headline node. The reason to keep it around is that a numeric mask is reproducible: the same workflow gives you the same mask on every run and every machine, which hand-painted masks famously do not.
How it works
Under the hood it's Pillow, not a model. The node makes an L-mode canvas at canvas width × canvas height, draws a rectangle at the resolved anchor, and converts it to a float tensor. Two details are worth knowing because they explain the behaviour you'll see.
First, the placement uses an edge anchor, not a grid cell. The nine position options are resolved by an edge-anchoring helper, so bottom-center sits flush on the bottom edge and top-left is pinned to the corner. Only the middle row/column actually centres anything. That's deliberate - the shape can never fall outside the canvas - but it surprises people coming from three-by-three grid nodes.
Second, the shape is clamped, never scaled. Ask for x = 4000 on a 1024-wide canvas and you don't get an error, you get a mask that's the full canvas width. Ask for 200 and you get 200.
corner_radius isn't pixels - it's a percent of the maximum rounding, which is half the shorter side. So 50 on a 512×512 square gives you a 128px radius, and 100 switches the drawing routine entirely to an inscribed ellipse. It's a circle when x equals y, which is the fastest way to get a round avatar mask in this ecosystem.
blur runs a Gaussian over the mask before the image is composited, and the image is built by blending white over bg_color through that same mask. That's why the soft edge looks identical in both outputs - no drifting halo between the mask and the plate.
The inputs you'll actually touch
x/y- shape width and height in pixels. Yes, the names are a trap; the author's own tooltips say "Shape width in pixels" and "Shape height in pixels."xis not a position. Position comes from the enum.position- one of nine anchors,middle-centerby default.corner_radiusandblur- 0–100 percent and 0–200 pixels respectively. Keep blur modest: 8–32 gives a believable feathered edge, and 200 on a small shape just dissolves it.bg_color- hex only, with or without the#, three or six digits.#000works;blackthrows.
canvas width / canvas height step in eights for a reason: latent-space nodes want dimensions divisible by 8, and a mask you'll feed into SetLatentNoiseMask should match the image you're masking.
Install
ComfyUI Manager, search ComfyUI-Whisker-Nodes, install, restart. Or from the command line:
cd ComfyUI/custom_nodes
git clone https://github.com/nerdywhiskers/ComfyUI-Whisker-Nodes
pip install -r ComfyUI-Whisker-Nodes/requirements.txt
Portable build on Windows:
cd ComfyUI_windows_portable\ComfyUI\custom_nodes
git clone https://github.com/nerdywhiskers/ComfyUI-Whisker-Nodes
cd ..\..
python_embeded\python.exe -m pip install -r ComfyUI\custom_nodes\ComfyUI-Whisker-Nodes\requirements.txt
Then look under Add Node → whisker-nodes.
Worth flagging: the pack's requirements.txt pulls transformers>=4.40 and timm>=1.0 because of the background-removal nodes. Shape Mask itself imports only numpy, torch and Pillow - all of which ComfyUI already ships. So installing the pack to get this one node drags in a chunk of dependency weight you don't strictly need. The first run of the BG-removal nodes also downloads BiRefNet (~880 MB, MIT) or RMBG-2.0 (~885 MB, non-commercial) into your HuggingFace cache - irrelevant to this node, but it's the install's real cost.
Gotchas
The bg_color parser is strict - a typo like #00 or white raises Invalid hex color and the node fails rather than falling back. Blame that one on the string field, not on you.
If a mask looks off-centre, check position before you check the maths: at bottom-right a 200px shape touches both the right and bottom edges, with all the empty space above and to the left.
And if you're loading an old workflow that calls a node called Ratio Mask, it still works - the pack keeps the legacy ratio_mask class id pointing at the same implementation, so saved graphs don't break on update.
Finally, remember what this node is not: there's no alpha in the image output, no rotation, no polygons. It's rectangles, rounded rectangles and ellipses. If your region isn't one of those, you want a detector or a painted mask - the pack's own BG Remove + Compose node handles the "cut a subject out and place it" job much better than a geometric stencil will.
Inputs (8)
| Name | Type | Default | Description |
|---|---|---|---|
| canvas width | INT | 102416–8192 | — |
| canvas height | INT | 102416–8192 | — |
| x | INT | 5121–8192 | Shape width in pixels (clamped to the canvas). |
| y | INT | 5121–8192 | Shape height in pixels (clamped to the canvas). |
| position | COMBO | middle-center | 9 options: top-left, top-center, top-right, middle-left, middle-center, middle-right, +3 |
| bg_color | STRING | #000000 | — |
| corner_radius | FLOAT | 00–100 | Corner rounding as a percent of the maximum (half the shorter side). 100 draws an inscribed ellipse — a circle when x equals y. |
| blur | FLOAT | 0.00–200 | — |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| image | IMAGE | — |
| mask | MASK | — |