ComfyUI Node

Mask Painter

Paint a mask by hand, right on the node

By mmmmmmmmme·Created 6 months ago·Updated 6 months ago· 0
Mask Painter
  • input_image
  • output_mask
mask_data{}

ComfyUI will hand you a mask from a detection node, a color range, or a Segment Anything click. But sometimes you just want to draw one yourself - a little inpainting patch on a face, a spot to regenerate, a region to protect. That's what MaskPainter is for: feed it an image, scribble white over what you want masked on a canvas that lives inside the node, and it hands you a proper MASK tensor. No models, no download, no API. The name is honest; the --version 0.0 stamped on the description is more honest than the author probably meant it to be.

How it works

The interesting part is the split personality. The Python class takes input_image plus a hidden STRING widget called mask_data. When the node runs, the backend converts your image to a base64 PNG and ships it to the browser; the pack's JS (mask_painter_widget.js) draws that image on a canvas and lets you paint. Every stroke is turned back into a base64 PNG and stored in the hidden mask_data widget. On the next execute, the backend decodes it, converts it to grayscale, normalizes to 0–1, resizes to the input's exact dimensions, and returns output_mask.

The inputs you actually touch:

  • input_image - the IMAGE you want to mask. The code only reads the first frame of a batch, so feed a single image, not a stack.
  • mask_data - hidden and automatic. It's the transport for your painting, and it gets saved into the workflow JSON. The catch: a few brush strokes mean a lot of base64, so save files balloon fast.
  • output_mask (MASK) - the only output. Wire it into anything that eats a mask: InpaintModelConditioning, VAEEncodeForInpaint, a ControlNet with a mask input, or a compositing node. White is masked, black is clear - the standard convention.

On the node's canvas you get a brush-size box (1–999px) and a Clear All button. There's no eraser; Clear All is your undo button, so brush deliberately.

Install and use

Install through ComfyUI Manager by searching "ComfyUI Image Mask Painter", or:

cd ComfyUI/custom_nodes
git clone https://github.com/mmmmmmmmme/ComfyUI_ImageMaskPainter

Then restart ComfyUI. The README and the pyproject both stress a full restart after first install - the JS extension won't render otherwise. Dependencies are pillow, numpy, and torch, all of which ComfyUI already has, so there's nothing heavy to download.

The workflow from the README: plug in an image, select the node and click Execute this node (it's marked an output node precisely so you can run it alone), paint on the canvas, then run the workflow to get your mask out.

The honest part

This is a prototype - the category is literally mmmmmmmmm, the author writes "welcome to perfect it," and 0.1's changelog reads "Fix Mask disappear after execution" and "Attempt to fix node no render when first load." So expect rough edges. Two real ones: if your mask vanishes after a run, or the canvas is blank the first time the node loads, restart ComfyUI and make sure you're on the latest commit - those are the exact bugs the 0.1 update chased. And when there's no mask data at all, the node silently outputs an all-black (empty) mask rather than complaining, so a "nothing happened" result usually means you never painted anything.

For the workflow-level decision: if a model or detector can find the region for you, let it - that's what SAM and the detection packs are for. Reach for MaskPainter when you want a 30-second manual touch-up and don't want to leave the graph to do it. For a hand-drawn mask in a pinch it works. Just don't stake a production pipeline on a 0.0.

Categorymmmmmmmmm

Inputs (2)

NameTypeDefaultDescription
input_imageIMAGE
mask_dataSTRING{}

Outputs (1)

NameTypeDescription
output_maskMASK