Nodes/Create Bounding Boxes (Auto-Rescale)/Create Bounding Boxes (Auto-Rescale)
ComfyUI Node

Create Bounding Boxes (Auto-Rescale)

Stop your layout squashing when the resolution changes

By jambread-git·Created 23 days ago·Updated 22 days ago· 0
Create Bounding Boxes (Auto-Rescale)
  • editor_state
  • background
  • bboxes
  • last_incoming
  • preview
  • bboxes
  • elements
◄width1024►
◄height1024►
◄draw_width0►
◄draw_height0►

You drew a nice layout: a character on the left third, a table on the right, a text block along the bottom. Then you swapped the resolution and every box slid into the top-left corner, like the whole scene had been scaled down and pasted on. Nothing errored. The boxes are just wrong now.

That's not you being bad at drawing boxes. It's how core ComfyUI's Create Bounding Boxes behaves when width and height come from a link instead of the widgets. Create Bounding Boxes (Auto-Rescale) is a drop-in replacement that fixes exactly that and not much else - same widgets, same three outputs, so your graphs don't need rewiring.

Why the boxes break in the first place

Bounding-box layout prompting is what Ideogram 4 made mainstream: describe each element, give it a box, and the model composes to that spec. Core ComfyUI's Create Bounding Boxes is the free way in - draw on a canvas, get pixel-space bboxes plus the structured elements list an Ideogram-style text encoder wants.

The catch: the canvas stores boxes in the pixel grid of the node's own width/height widgets. Feed those from a ResolutionSelector or a PrimitiveInt - how you'd build a resolution-switchable workflow - and at execution the node sees a different canvas than the one you drew on. Core re-interprets your coordinates as-is, so boxes drawn for 1024×1024 land in the corner of a 1920×1080 render. Layout gone.

This node keeps a mirror of the drawing space and rescales before anything else happens.

How it works

The hidden draw_width / draw_height widgets record the canvas size you actually drew at, maintained automatically by the frontend extension. At run time, if the effective width/height differ from that mirror, every box's x, y, width and height is multiplied by the ratio of new to old size, clamped to the canvas, minimum 1px. Then the rescaled list goes through the same core conversion functions the stock node uses, so the outputs are identical - just correct.

Setting draw_width to 0 switches auto-rescale off - that's what you'll see in a core-node workflow you swapped over.

Two behaviours carry over from core, and both trip people up: an upstream value on bboxes re-initialises the canvas, but edits you make on the canvas win until that upstream value actually changes again. And the ordering rule is real - background element first, foreground last, because the list is stacking order.

The inputs that matter

  • width / height - the canvas grid (64–16384). Link a resolution node if you want one workflow at several sizes; leave them if you don't.
  • editor_state - the canvas itself. Drag on empty space to draw, drag inside to move, eight handles to resize, double-click to edit a description, Del to delete, Alt+click to grab a box hidden under another. Obj and text tabs, per-box colours, grid-snap toggle.
  • background (optional) - an image to trace over instead of a blank canvas. It shows up in the preview.
  • bboxes (optional) - pipe in an existing box set or JSON to seed the canvas.

Outputs: preview (IMAGE, boxes over your background), bboxes (pixel rectangles), elements (the structured list). preview alone justifies the node - it registers as an output node, so you see your layout without screenshotting the canvas.

Installing it

ComfyUI Manager, search ComfyUI-BBox-AutoRescale or the registry name comfyui-bbox-autorescale, install, restart, then look for "Create Bounding Boxes (Auto-Rescale)" in the palette. Or:

cd ComfyUI/custom_nodes
git clone https://github.com/jambread-git/ComfyUI-BBox-AutoRescale

No pip dependencies - pyproject.toml ships an empty dependency set and the node only touches ComfyUI core. Two requirements: your ComfyUI needs comfy_extras/nodes_bounding_boxes.py, and the node uses the V3 comfy_api.latest API - on an older build you get an import error at startup, not a working node.

Where it bites

Aspect-ratio changes still stretch. The rescale is per-axis, which is the mathematically obvious thing and still surprises people: sketch a layout on a square canvas, run at 16:9, and boxes get wider rather than re-composed. Coordinates survive, proportions don't. Draw at the aspect ratio you actually intend to render.

The boxes are a request, not a command. Ideogram 4 honours them because boxes are in its trained caption schema. On Krea 2 it partly works by accident - the Qwen3-VL encoder saw bounding boxes in training - and Krea has said there's no official support. On an SDXL checkpoint or a Flux graph, a perfectly rescaled box has nowhere to plug in at all.

It's a one-person project, three months late to its own party. v1.0.3, MIT, one author, English and Japanese README, published to the Comfy Registry. The layout-box wave crested around June–July 2026 with Ideogram 4 and Krea 2; this shipped in October to fix a wart that outlived the hype. Install it, but pin the commit - there's no support team.

Categoryutilities

Inputs (8)

NameTypeDefaultDescription
widthINT102464–16384Width of the canvas and the pixel grid for the bounding boxes. Connect ResolutionSelector or any INT source here.
heightINT102464–16384Height of the canvas and the pixel grid for the bounding boxes. Connect ResolutionSelector or any INT source here.
editor_stateBOUNDING_BOXESDraw bounding boxes and set each box type, text, description, color palette. Start with background element first and foreground last. Boxes are stored in the canvas space you drew them in and are auto-rescaled to the effective (linked) width/height at run time.
draw_widthINT00–16384Internal use, managed automatically by the canvas frontend: the width the saved boxes were drawn in. Hidden from the UI; set to 0 to disable auto-rescale.
draw_heightINT00–16384Internal use, managed automatically by the canvas frontend: the height the saved boxes were drawn in. Hidden from the UI; set to 0 to disable auto-rescale.
backgroundoptIMAGEOptional image used as background in the canvas and preview.
bboxesoptBOUNDING_BOX,ARRAY,STRINGBounding 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.
last_incomingoptBOUNDING_BOXESInternal state managed by the canvas: the upstream bboxes value that last initialized it. Leave empty to re-initialize the canvas from the bboxes input on the next run.

Outputs (3)

NameTypeDescription
previewIMAGE—
bboxesBOUNDING_BOX—
elementsARRAY—