GoyAIcanvas Paint (Image + Mask)
Paint an inpaint mask with a real brush, not by guessing pixels
- source_image
- image
- mask
- report
Every inpainting workflow needs a mask, and the fastest way to get a good mask is to draw it. But ComfyUI's built-in mask painting is basic, and if you're doing Ideogram-style image editing, you often want to paint and see the image you're editing at the same time. GoyAIcanvas Paint is a small dedicated painter: open its canvas, import or connect an image, brush over what you want changed, and it outputs both the IMAGE and the MASK ready for your inpainting or edit nodes.
The name tells you the scope - it's a canvas paint utility, deliberately without the layer/gesture machinery of IAMCCS's bigger Frame Designer. If you just want image + mask out of a paint session, this is the one.
How it works
The frontend paints strokes into a JSON paint_data payload (an embedded image as a data URL plus a list of strokes with points, mode, and brush size). The backend, which is plain Python + PIL, then:
- Resolves the image. Priority order: an embedded image in
paint_datawins, then the connectedsource_image(iffallbackisconnected_image), then a blank canvas atwidth×height. - Builds the mask from strokes. Strokes marked
paintfill white on the mask;erasestrokes fill black (inpaint masks are conventionally white = area to regenerate). The brush size controls stroke width, and the code draws smooth lines with capped ends between points. - Returns
image,mask, and areportwith stroke/pixel stats.
Both outputs match the image's dimensions - width and height are inferred from whichever image source actually got used, so you don't get a size-mismatched mask. The default fallback of connected_image means the connected image is used if the paint data is empty, which makes it forgiving for first-time wiring.
Inputs that matter
paint_data- the JSON the canvas writes; you don't hand-edit this.source_image- optional IMAGE to paint over; connect it unless the canvas already embeds one.width/height- only used when the fallback is a blank canvas. Defaults 1024×576.
Install
Part of IAMCCS-nodes:
cd ComfyUI/custom_nodes
git clone https://github.com/IAMCCS/IAMCCS-nodes.git
Or ComfyUI Manager → "IAMCCS" → install → restart. It uses only PIL/numpy/torch - no extra dependencies.
Gotchas
The mask is built from strokes at their stored coordinates - if the canvas was painted at a different resolution than the connected image, you can get misaligned masks, so paint at the image's native resolution. And remember the mask convention: painted = white (regenerate), erased = black (keep). If your inpaint fills the wrong area, check your stroke mode rather than the node. It's a source of clean IMAGE+MASK pairs, not an inpaint node itself - the actual editing happens downstream.
Inputs (5)
| Name | Type | Default | Description |
|---|---|---|---|
| paint_data | STRING | — | |
| width | INT | 10241–8192 | — |
| height | INT | 5761–8192 | — |
| fallback | COMBO | connected_image | 2 options: blank, connected_image |
| source_imageopt | IMAGE | — |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| image | IMAGE | — |
| mask | MASK | — |
| report | STRING | — |