Mask On Canvas
Put your mask on a canvas — white, tinted, or plain grayscale
- mask
- IMAGE
Same idea as its sibling Image On Canvas, but for a MASK - and the important difference is that this node outputs an IMAGE, not a mask. So it's really about seeing masks, previewing them, and building colored overlays, not about passing a mask tensor along.
Why bother? Because inpainting is only as good as your mask, and most mask-producing nodes are bad at showing you what they produced. White in a ComfyUI mask means "this region will be re-denoised" - that's the convention every inpainting node relies on - so before you burn a sampling pass you want to actually look at what's covered. This node turns a mask into a visual you can preview or save: tint it red like a Photoshop quick-mask over a colored backdrop, or render it white-on-black as a clean mask plate. That's also handy for compositing masks into a fixed-size canvas when you're building regional or area-conditioned workflows that expect a specific canvas layout.
How it works
The MASK tensor is converted to grayscale (it auto-detects whether values are 0–1 or 0–255, a nice touch), then a canvas is built at your container_width × container_height and filled with background_color - default black, because white-on-black is the natural mask look. The mask is resized with LANCZOS and pasted at your x/y, clamped and cropped to the canvas bounds.
The mask_color field is the interesting knob. Give it a color (default #FFFFFF) and the mask is drawn in that color with the grayscale mask acting as its alpha channel: bright pixels - mask value 1.0, the region that changes - paint opaque, dark pixels let the background show through. Leave it empty and you get plain grayscale pasted opaquely.
The inputs that matter
mask- the MASK tensor to draw.background_color- hex, default#000000(black, the natural backdrop for a mask plate).container_width/container_height- canvas size, default 512×512.mask_x/mask_y,mask_width/mask_height- position and rendered size, defaults 0,0 and 256×256.mask_color- hex tint, default#FFFFFF. Clear this field to get plain grayscale.
Output: IMAGE.
Where people get burned
- The default
mask_coloris#FFFFFF, which is not empty. Leave it alone and you get a white-tinted overlay, not grayscale. To get the grayscale mode you have to actively clear the field to an empty string - easy to miss, and the two modes look genuinely different. - Grayscale vs. colored are not the same paste. Colored mode alpha-composites, so only the bright parts of the mask paint and your canvas color shows through the shadows. Grayscale mode pastes the whole rectangle opaque - the black parts of the mask cover the canvas color too. If your mask has a black background, grayscale mode will eat your background color.
- Remember the convention: white = the region that changes. A white-on-black plate reads as "this is what gets edited." If it looks backwards, it's the mask semantics, not the node.
- Only the first mask of a batch is drawn. Feed single masks, or split the batch.
- The output is IMAGE, not MASK. It's for preview, compositing, and annotation. If your downstream inpaint node needs a MASK tensor, keep the original mask wire and feed it directly - don't try to pipe this node's output into a mask input.
Installation
Same tiny pack as Andalusi Image Loader and Image On Canvas. No requirements.txt, no model downloads, nothing beyond ComfyUI's stock dependencies.
cd ComfyUI/custom_nodes
git clone https://github.com/AndalusiLLC/comfyui_andalusi.git
Restart ComfyUI, or use ComfyUI Manager and search for "Andalusi." It's a small personal pack by Kornesh Kanan (Kobaisy) - clean and readable, but effectively unmaintained, so don't hold your breath for updates.
Troubleshooting
- Mask looks reversed - white is "will change," black is "stays." If your tint fills the unmasked area, your mask upstream is inverted.
- Background color is invisible - you're in grayscale mode with a mask that has a black background, which covers the canvas. Give it a
mask_coloror convert the mask to a white-on-black form first. - Can't wire the output into an inpaint mask input - expected. This outputs IMAGE; keep the original MASK wire for that.
Inputs (9)
| Name | Type | Default | Description |
|---|---|---|---|
| mask | MASK | — | |
| background_color | STRING | #000000 | Background color in hex format (e.g., #FF0000 for red) |
| container_width | INT | 5121–8192 | Width of the canvas container |
| container_height | INT | 5121–8192 | Height of the canvas container |
| mask_x | INT | 00–8192 | X position of the mask on the canvas |
| mask_y | INT | 00–8192 | Y position of the mask on the canvas |
| mask_width | INT | 2561–8192 | Width of the mask on the canvas |
| mask_height | INT | 2561–8192 | Height of the mask on the canvas |
| mask_color | STRING | #FFFFFF | Color to draw the mask in hex format (e.g., #FF0000 for red). Leave empty for grayscale. |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| IMAGE | IMAGE | — |