Nougan Bounding Boxes π²
Bounding Boxes without Nodes 2.0 β draw the layout, hand the model a map
- background
- bboxes
- preview
- bboxes
- elements
ComfyUI's core Create Bounding Boxes node is genuinely good - it's the difference between "a cat, somewhere" and "the cat sits bottom-left, the headline runs across the top". The catch is that it lives in the Nodes 2.0 world. If you're still on the classic canvas (a lot of us are, because half our muscle memory is right-click menus), you either don't see it or fight it.
NouganBoundingBoxes is that node rebuilt for the classic UI. Same job: you draw rectangles on a canvas, tag each one as an object or a piece of text, and the node hands you back both a picture of your layout and the structured data a model can actually consume.
What it's actually for
Layout control is the least glamorous part of prompting and the one that pays most reliably. You're placing a subject in a region, keeping a corner empty for a headline, or dictating where three characters stand so a video model doesn't merge them into one body. Text-in-image models are the big customer here: if you want the word HOME in the top third, describing it in prose is a coin flip, and boxing it is not.
The output that matters most is elements, an array of prompt elements - type, bbox, text, desc, color_palette. That's the shape nodes like MOSS-Image Layout Prompt want (character_boxes reads the numbers you see on the preview). You draw, you wire elements downstream, the model lays out to spec.
How it works
The node is a canvas plus a pixel grid. Set width and height; boxes are stored as fractions of that grid, so a layout survives a resolution change - which is why the docs say to match them to your final image size.
Three outputs:
preview- boxes drawn over a dimmedbackground, numbered, with descriptions and palette swatches. It's anIMAGEoutput: Preview Image it and see the layout before spending a sampling step.bboxes- pixel-space rectangles (x,y,width,height), the mechanical form.elements- the semantic form described above.
The bboxes input is the clever bit. It takes pixel boxes, prompt elements, or a JSON string, which means you can paste an LLM's answer straight in - or wire it live from a TextGenerate node fed by Nougan Layout LLM Prompt π§. The parser tolerates code fences, prose around the JSON, <think> blocks and trailing commas, and it accepts a wrapped {"elements": [...]} list. An element with no usable bbox gets skipped with a console note rather than exploding the run.
Upstream input and your hand-edits coexist on a simple rule: a new upstream value repaints the canvas; after that your edits win until the upstream value changes again. editor_state and last_incoming exist to make that work - they're the editor's scratch memory, leave them alone.
Inputs worth touching
Honestly, two.
width / height (64β16384, step 16). Link them from a resolution node so the canvas can't drift from what you actually render.
bboxes (optional) - wire an LLM's JSON here if you want the layout generated rather than drawn. Once you're happy with the result, disconnecting it is the way to stop the canvas resetting every run.
Installing it
It's part of the Nougan_Nodes pack, and it installs like any other pack:
cd ComfyUI/custom_nodes
git clone https://github.com/Winnougan/Nougan_Nodes
# restart ComfyUI
Or search Nougan in ComfyUI Manager. Then hard-refresh the browser (Ctrl+F5) - the canvas editor is custom JS, and a stale cached bundle is the reason people report "no canvas". On a good boot the console says [Nougan] β
Bounding Boxes loaded. No model downloads, no extra dependencies; the pack's pyproject.toml declares an empty dependency list.
Where people get burned
The Text/Object trap. A box that should render words must be type Text with the Text to render field filled in. Putting text that says "HOME" in the description of an Object box does nothing - the model reads it as a caption, not a directive. This is the single most common "the node is broken" report and it never was.
Boxes land in the wrong place. Your width/height don't match the generated image. The fractions are fractions of that number.
The canvas keeps resetting. An LLM is producing a new answer each run. Fix the seed, lower its temperature, or unplug bboxes.
Right-click gives you ComfyUI's menu. Right-click on a box, a layer row or the canvas itself, not the title bar.
One honest caveat: sending boxes to a layout-aware model is still experimental territory - MOSS layout control especially. Keep the layout prompt consistent with the boxes, and if your workflow has a prompt enhancer, turn it off. It will happily rewrite your carefully placed layout into decorative prose.
Inputs (6)
| Name | Type | Default | Description |
|---|---|---|---|
| width | INT | 102464β16384 | Width of the canvas and the pixel grid for the bounding boxes. |
| height | INT | 102464β16384 | Height of the canvas and the pixel grid for the bounding boxes. |
| backgroundopt | IMAGE | Optional image used as background in the canvas and preview. | |
| bboxesopt | BOUNDING_BOX,ARRAY,STRING | Bounding boxes, elements, or a JSON string to initialize the canvas. A new upstream value initializes the canvas; edits made on the canvas take priority and are kept until the upstream value changes again. | |
| editor_stateopt | STRING | Managed by the Nougan Bounding Boxes editor. | |
| last_incomingopt | STRING | Internal: the upstream bboxes value that last initialized the canvas. |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| preview | IMAGE | β |
| bboxes | BOUNDING_BOX | β |
| elements | ARRAY | β |