2026-06-12 16:29:33 +02:00
2026-06-05 21:04:48 +02:00
2026-06-05 21:04:48 +02:00
2026-06-05 21:04:48 +02:00
2026-06-05 21:04:48 +02:00
2026-06-05 21:04:48 +02:00
2026-06-12 16:17:51 +02:00
2026-06-05 21:18:52 +02:00
2026-06-05 21:04:48 +02:00
2026-06-12 16:29:33 +02:00

ComfyUI Smart Aspect Ratio

A ComfyUI custom node that converts a megapixel target and aspect ratio into pixel dimensions (width × height). The ratio can be fixed, randomized, or detected automatically from a connected prompt.

Type cinematic ultrawide city at night and the node hands your latent a 21:9 resolution. Write 16:9 anywhere in the prompt and it obeys exactly. Or skip detection entirely and use it as a clean megapixels-plus-ratio resolution picker and/or randomize the aspect ratio for each run.

node screenshot


Features

  • 23 aspect ratios from 9:32 portrait to 32:9 landscape
  • Prompt-based detection — connect your prompt text and the node picks a fitting ratio automatically
  • Explicit override — writing 16:9 (or any accepted ratio) in the prompt forces it exactly
  • Keyword matching — terms like cinematic, widescreen, portrait, or anamorphic map to weighted ratio pools
  • Seed-controlled randomization — choose between a fixed or random ratio when nothing matches, reproducible via seed
  • Editable keyword rules — click Edit Keywords on the node to change the mapping, no restart needed

Installation

ComfyUI Manager: search for Smart Aspect Ratio.

Manual:

cd ComfyUI/custom_nodes
git clone https://github.com/dawncreatescode/comfyui-ResolutionAndAspectRatio

Restart ComfyUI. The node appears under the Resolution category.

Quick start

  1. Add the node: Add Node → Resolution → Smart Aspect Ratio.
  2. On your Empty Latent Image, connect width and height to this node.
  3. (Optional, for prompt detection) Feed the same prompt string into both your CLIP Text Encode and this node's prompt input — e.g. from a String/Primitive node:
[String: prompt] ──┬──→ [CLIP Text Encode] ──→ ...
                   └──→ [Smart Aspect Ratio] ──width───→ [Empty Latent Image]
                                              ──height──→
  1. Pick a megapixels target (1.0 ≈ SDXL native) and you're done. Without a prompt connection, the node is a simple ratio/resolution picker using the aspect_ratio dropdown.

How the ratio is chosen

Detection runs in strict priority order — first match wins:

  1. Explicit ratio in the prompt. 16:9 photo of a harbor → 16:9 (from prompt). Always wins.
  2. Keyword match. anamorphic close-up → 21:9 (anamorphic). When a keyword maps to several ratios (e.g. widescreen → 16:9 / 19:9 / 21:9), one is picked by weighted random using the seed.
  3. Fallback. Nothing matched → the fixed aspect_ratio dropdown, or a random ratio if randomize is on.

The ratio output always tells you what fired — 21:9 (from prompt), 16:9 (cinematic), 4:5 (fallback). Connect it to a Show Text node while you're tuning.

Keyword modes — and why Limited is the default

Mode What triggers detection
Off Nothing — fixed or random ratio only
AR only Only explicit ratios written in the prompt (16:9, 3:2, …)
Limited keywords (default) Explicit ratios + unambiguous format terms (widescreen, anamorphic, ultrawide, …)
All keywords Everything above + content words (cinematic, portrait, poster, phone, …)

Content words are powerful but can be unintended: in portrait of a king, "portrait" describes the subject, not the orientation — yet All mode will dutifully make the image tall. Limited only reacts to words that unambiguously describe a format, which is why it's the default. Switch to All when you want maximum hands-off behavior and your prompts don't use those words for content.

Default keyword rules

Words Ratio pool Active in
anamorphic 21:9 Limited + All
imax 4:3 Limited + All
ultrawide 21:9 32:9 Limited + All
widescreen 16:9 19:9 21:9 Limited + All
panorama, panoramic 16:9 19:9 21:9 32:9 Limited + All
square, avatar, thumbnail 1:1 All only
mobile, phone, smartphone 9:16 9:19 9:21 All only
poster 2:3 3:4 4:5 All only
cinematic 16:9 21:9 32:9 All only
banner, wallpaper 16:9 21:9 32:9 All only
landscape, horizontal, wide angle, wide shot all landscape ratios All only
portrait, vertical, tall all portrait ratios All only

Supported aspect ratios

Portrait: 2:3 3:4 3:5 4:5 5:7 5:8 7:9 9:16 9:19 9:21 9:32 · Square: 1:1 · Landscape: 3:2 4:3 5:3 5:4 7:5 8:5 9:7 16:9 19:9 21:9 32:9

Editing the rules

Click Edit Keywords on the node. Each rule has:

  • Words — comma-separated triggers (case-insensitive, phrase-aware)
  • Ratios — comma-separated pool, or $LANDSCAPE / $PORTRAIT for the full sets
  • Weights — optional per-ratio probabilities (blank = equal chance)
  • Category — limited (active in Limited + All) or all (All mode only)

Changes save to keywords.json in the node folder and apply immediately.

Node reference

Inputs

Input Type Description
megapixels dropdown Pixel budget, 0.1–2.5 MP (1.0 ≈ SDXL native, ~0.25 ≈ SD 1.5 native)
aspect_ratio dropdown Fallback ratio when detection is off or finds nothing
divisible_by dropdown Round dimensions to a multiple of 8 / 16 / 32 / 64 — see below
keyword_mode dropdown Which prompt keywords trigger detection (see modes)
randomize boolean Pick a random ratio when nothing matches
seed INT Fixed seed → reproducible picks; set control_after_generate to randomize for variety per run
prompt STRING (optional) The text to scan — same string you feed your CLIP Text Encode

Outputs

Output Description
width Image width in pixels
height Image height in pixels
ratio Selected ratio + what triggered it, e.g. 16:9 (cinematic)

Choosing divisible_by

Stable Diffusion latents require dimensions divisible by 8, so 8 is the hard minimum. Larger multiples (32, 64) are safer across models and avoid edge artifacts some checkpoints show at odd sizes — at the cost of landing slightly further from your exact ratio and megapixel target. Rule of thumb: leave it at 64; drop to 16 or 8 only if you need shapes as exact as possible and know your model handles them.

Troubleshooting

My keyword isn't detected. Check keyword_mode — content words like cinematic need All keywords. Also confirm the prompt input is actually connected; the node can't see text it isn't given.

Dimensions aren't exactly my ratio. That's divisible_by rounding. Lower it for a closer fit.

randomize gives the same ratio every run. The seed is fixed. Set the seed widget's control_after_generate to randomize.

Which ratio fired, and why? Connect the ratio output to a Show Text node — it names the trigger.

License

MIT

S
Description
No description provided
Readme MIT
239 KiB
Languages
Python 50.4%
JavaScript 49.6%