Draw Mask On Image
Paint a Colour Through a Mask, Per Frame, Without the Round Trip
- image
- mask
- images
Sooner or later you need to see the mask. Not as a separate black-and-white image, but overlaid on the picture: did the detector catch the whole face or just the chin? Did the feather reach the hair? Draw Mask On Image is that, for a whole batch, in one node.
What it actually does
For each frame it blends the image towards color, weighted by m = mask × alpha:
rgb × (1 − m) + color × m
An RGBA frame keeps the larger of its own alpha and m. That's it - a straight linear blend towards a target colour, per frame, no compositing node in between.
The details that make it practical:
- A mask of a different size than the image is scaled to the image with nearest-neighbour. So a mask you made at half resolution still works.
- Fewer masks than frames: they repeat in order. More masks than frames: extras are ignored. Batch mismatches don't blow up, which is the single most common reason mask workflows die.
- A missing or empty mask returns the image unchanged. An empty image batch passes through. You can leave it in the graph while you build the rest.
- Frames are blended one at a time into one preallocated output, and the inputs are never copied - so a 100-frame 1080p batch doesn't triple its own memory footprint doing this.
Inputs and outputs
image- RGB or RGBA.mask- theMASK.color- a string widget, default0, 0, 0. This is the one to read carefully: it takesr, g, borr, g, b, acomma-separated, where a value above 1 is read as 0–255 and anything else as 0–1. So255, 0, 0, 128is a half-opacity red, and1, 0, 0is also red, and1, 1, 1is white - not 1/255 grey. It also accepts#rgb,#rgba,#rrggbb,#rrggbbaa. Alpha is the opacity, and it's 1 when you leave it out.device-cpu(default) orgpu.- Output:
images, the blended batch, same shape as the input.
The alpha-in-color thing is the nicest part of the design. 255, 0, 255, 90 is a loud magenta wash you can still see the image through - much better for judging a mask than a solid fill or a 50/50 blend you didn't choose.
What it's for
Debugging, mostly. A magenta overlay tells you in one glance what a SAM or YOLO detection actually grabbed, and the same overlay on a video batch tells you whether a detector is jittering frame to frame - flicker is invisible in a still mask and obvious when you scrub an overlay.
Beyond debugging, it's a competent compositor for flat-colour work: paint a region solid for a graphic, lay a colour grade over the subject only, or produce a matte-region preview for someone who doesn't want to read a black-and-white PNG.
If what you want is an actual composite with real image content, this isn't it - use ImageCompositeMasked or run the region through a second sampler. This node paints a colour, and it's honest about that.
Install
The usual for this pack: ComfyUI Manager, search ComfyUI-BCNodes, install. Or:
cd ComfyUI/custom_nodes
git clone https://github.com/0xBeycan/ComfyUI-BCNodes
pip install -r ComfyUI-BCNodes/requirements.txt
Restart and search BCNodes in the node library (it sits under BCNodes/mask). requirements.txt is opencv-python, postfx and caption-audit; this node needs none of them to load. If ComfyUI still has an old ComfyUI-AutoBypass folder from the pack's earlier name, delete it - the two will clash.
Gotchas
The color parser is strict and will raise rather than guess. A colour in a form it doesn't recognise, or one whose value count doesn't match the image's channels, stops the run with a message about what to fix. That's better than silently painting black, but it means rgb(255,0,0) - not one of the documented forms - is an error, not a colour. Stick to the documented formats; #rrggbb is the least error-prone.
Second: because a too-short mask list repeats in order and a too-long one gets truncated, a shape mismatch fails quietly. If your overlay is covering the wrong thing on frame 30, check the mask batch length before you check the mask itself.
Third: device matters more than you'd expect on video batches. Blending 300 frames at 4K on CPU is measurable; on GPU it's free. The default is conservative on purpose - flip it yourself.
Inputs (4)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | — | |
| mask | MASK | — | |
| color | STRING | 0, 0, 0 | RGB or RGBA, comma-separated, each value 0-255 or 0-1 (a value above 1 is read as 0-255), or #rgb / #rgba / #rrggbb / #rrggbbaa. Alpha is the opacity, 1 when absent. Ex: 255, 0, 0, 128 |
| deviceopt | COMBO | cpu | Device the frames are blended on. |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| images | IMAGE | — |