😺NKD Paint
Scribble a ControlNet guide straight on the node — no trip to an external editor
- bg_color
- image
- image
- painted
- strokes
- mask
- inverted mask
The usual way to feed a ControlNet scribble goes like this: paint your rough layout in Krita or Photoshop, save it, drag it into ComfyUI, then run it through a preprocessor that turns your careful drawing into a mess. 😺NKD Paint skips all of it. You draw directly on the node itself, over the image your graph just made or on a blank canvas, and what comes out is already the exact conditioning image a Scribble ControlNet wants - no external editor, no save/load round trip, no preprocessor between you and the model.
It's from the same 😺NKD Basic Tools grab-bag as Mask Painter and Vector Mask, and it shares their philosophy: preview inside the node, tune while you look. Connect an image and it shows up behind the canvas at its own resolution; connect nothing and you get a plain canvas at whatever width/height you set (1024×1024 by default, 64 to 4096). Brush, erase, undo, zoom - all the painting you'd expect.
Why the scribble use case matters
ControlNet's scribble mode takes a rough hand-drawn sketch and lets the model fill in the details - the "most creative-friendly" condition, if you want the textbook line. It's how people block out a composition before the prompt does the heavy lifting. The trick is that scribble models are picky about their input: they're trained on white lines on black. NKD Paint handles that with one switch.
How it works under the hood
Flip the controlnet boolean and two things change: the brush is locked to white no matter what colour you picked, and the STROKES output becomes white-on-black. Soft strokes stay soft - a feathery edge comes out as grey, and that grey is the line's intensity to a scribble model, not a bug. The node doesn't threshold or binarise your drawing, so what you paint is literally what conditions the sampler.
Where the drawing lives is the part worth knowing before you rely on it. Each finished stroke is saved as a PNG under ComfyUI/input/nkd_paint/, and only the filename gets stored in the workflow (that's the socketless layer string field - leave it alone). The filename is a hash of the picture, so an unchanged layer is a cache hit and the graph skips re-running the node. The flip side: your scribble travels with the ComfyUI install, like any Load Image file, not inside the workflow JSON. Export a workflow with a drawing in it and whoever opens it gets a blank layer unless the file comes along too.
Inputs and outputs that matter
image(optional) - sets the canvas size and shows behind your strokes. A Load Image wired straight in appears immediately; anything a previous node produces (a crop, a VAE decode) shows after the first run.controlnet- the scribble switch. White brush, white-on-black strokes.bg_color- whatSTROKESshows where nothing is painted, and the blank canvas colour when no image is connected.
Three outputs, all useful in different graphs:
IMAGE- strokes blended over the base. Wire this downstream when you want the scribble and the source visible.STROKES- the strokes alone overbg_color, unpremultiplied straight colour. This is the one that feeds the ControlNet, or pairs with the mask for a clean RGBA where soft edges survive intact.MASK- the exact alpha of your strokes; partial opacity stays partial. Wire it wherever you'd normally use a hand-painted inpaint mask.
Installing it
ComfyUI Manager: search "ComfyUI-NKD-Basic-Tools" (or "NKD Basic Tools") and install. Manually:
cd ComfyUI/custom_nodes
git clone https://github.com/Nekodificador/ComfyUI-NKD-Basic-Tools
Then restart ComfyUI. The pack declares onnxruntime and huggingface_hub in its metadata, but those back the Face Rig and Face Crop nodes; Paint itself loads on plain ComfyUI, and the pack's loader keeps working if the heavy face stuff fails. No model downloads for this node - it's all canvas and tensor math.
Where people get tripped up
The layer folder is the biggest one. Old drawings you've stopped referencing pile up in ComfyUI/input/nkd_paint/ until you delete them, and a workflow opened on a machine that never saw the matching PNG comes back with empty strokes - the node just composites an empty layer. If you hit that, redraw or copy the file across. Also remember the canvas shows a Load Image instantly but needs one run to reveal a node-generated source behind it. And no, that controlnet toggle doesn't make your colour choices apply - it deliberately ignores them. Draw white on black on purpose, or let the node do it for you.
Inputs (6)
| Name | Type | Default | Description |
|---|---|---|---|
| layer | STRING | — | |
| width | INT | 102464–4096 | Canvas width when no image is connected. |
| height | INT | 102464–4096 | Canvas height when no image is connected. |
| bg_color | COLOR | #000000 | What the strokes output shows where nothing is painted (and the canvas colour when no image is connected). |
| controlnet | BOOLEAN | false | Scribble mode: the brush is always white and strokes is white on black. |
| imageopt | IMAGE | Optional base image. Sets the canvas size and shows behind the strokes. |
Outputs (5)
| Name | Type | Description |
|---|---|---|
| image | IMAGE | The base image untouched, so the graph can continue from it. |
| painted | IMAGE | Strokes blended over the base. |
| strokes | IMAGE | Strokes alone, straight colour with bg_color where there is nothing (white on black in controlnet mode). |
| mask | MASK | Alpha of the strokes. |
| inverted mask | MASK | 1 - mask. This is what Join Image with Alpha wants to make strokes transparent. |