Size Selector
Pick a ratio, get a latent — with the channel count you actually need
- width
- height
- LATENT
- WIDTH
- HEIGHT
- FRAMES
Every model family wants a different latent shape. SD 1.5 and SDXL want four channels. Flux, SD3 and the video models want sixteen. Core's Empty Latent Image gives you dimensions and a batch and nothing else; get the channel count wrong and you don't get an error, you get a sampler that produces noise or dies several nodes later with a shape mismatch nobody can decode. 尺寸选择器 (QG_SizeSelector) is a latent factory that lets you say which kind you need.
How it works
Start with preset, a list of about forty resolutions each tagged with its ratio - 832x1216 - 2:3, 1344x768 - 16:9, widescreen and vertical variants, the usual SDXL-friendly numbers. Then optionally reshape it:
ratiooverrides the preset's aspect ratio with a string:16:9,2.39:1, even1 1with a space. Leave it at无and the preset's own ratio is used.long_edgescales the result so its long side is that many pixels, keeping the ratio.0keeps the preset's native size.factorrounds width and height up to a multiple of whatever you put here - 8, 16, 32.0disables it. This is the field that stops you shipping an 833-pixel-wide latent by accident.batch_sizeis what you'd expect.
Then the two fields that make this node worth installing:
latent_channels picks 4 or 16. SD 1.5 and SDXL: 4. Flux, SD3, and video models: 16. This is the bug the QG port fixed - the upstream node hardcoded 16 channels, which quietly broke plain SDXL latents. If you've ever had a Flux-era node produce latents that made an SDXL sampler behave strangely, this class of mistake is why.
frames is the other one. At 0 you get a plain image latent with no temporal dimension. Above 0 you get a video latent, and the node divides the frame count for the temporal compression the video VAEs apply - the tensor is built with ((frames - 1) // 4) + 1 in the time axis, so asking for 49 frames gives 13 latent frames, which is what the model actually consumes.
width and height are optional wildcard inputs. Wire anything numeric into them and a value above 0 wins over the preset. That's how you make the whole graph size-driven from a single source upstream.
Inputs and outputs
Required: preset, batch_size, long_edge, ratio, frames, factor, latent_channels. Optional: width, height (wildcards, parsed as numbers).
Outputs: LATENT (the empty latent), WIDTH and HEIGHT (the dimensions actually used, as INTs), and FRAMES (the frame count, 0 for image models).
Those integers are the useful part in a big workflow - feed WIDTH/HEIGHT into whatever needs them downstream and stop maintaining two copies of the truth. That's the plumbing principle the KB keeps coming back to: one authoritative value, fanned out by wire.
Install
cd ComfyUI/custom_nodes
git clone https://github.com/live1617/ComfyUI-QG-tools
Full ComfyUI restart; the console confirms with [QG-tools] v0.9.2 加载完成 | 节点数 24. Manager search ComfyUI-QG-Tools where the registry listing exists. Nothing to pip install - the requirements file is deliberately comments only so Manager skips pip, and this node needs only torch plus ComfyUI's model management module.
Ported from ComfyUI_Muye (MIT), searchable as size selector, aspect ratio, resolution or 尺寸选择器.
Where people get burned
FRAMES is not the latent's frame count. It reports the number you asked for; the latent holds the temporally compressed value. Don't wire FRAMES into something expecting latent["samples"].shape[2].
Wrong channel count, no error. Four vs sixteen doesn't fail at latent creation - it fails when the model's patch embedding sees a shape it doesn't recognise, several nodes downstream. If a Flux workflow produces garbage, check this widget before you check anything else.
long_edge with ratio set. Both reshape the preset, and it's easy to set a long edge that pushes the short side somewhere you didn't intend - the node's original upstream bug was assigning the long edge to both dimensions and producing a square. Fixed here, but a 21:9 with a 2048 long edge still gives you a very short side, and no model likes 460 pixels tall.
Preset numbers aren't sacred. These are hand-picked model-friendly resolutions, not magic. If you're running a model with a specific native training resolution, use factor and the override inputs to land exactly on it rather than trusting the nearest preset.
Inputs (11)
| Name | Type | Default | Description |
|---|---|---|---|
| preset | COMBO | 832x1216 - 2:3 | Preset resolutions and aspect ratios. With ratio set to none you get the preset's raw pixels, with from-preset you get the ratio printed in its label. |
| batch_size | INT | 11–4096 | Batch size. |
| long_edge | INT | 00–8192 | Long-edge pixels. 0 uses the preset's own size; any other value scales the long edge to it while keeping the aspect ratio. Both sides must stay multiples of 8 on an exact ratio, so the real long edge can land a few percent off the number you type (13:19 at 1024 becomes 1064; nothing in between is on grid). |
| ratio | COMBO | none | Overrides the aspect ratio. none uses the preset's raw pixels; from-preset uses the ratio printed in the preset's label, so 2304x1280 labelled 16:9 is really 9:5; you can also pick a fixed ratio directly. For an arbitrary ratio use the custom ratio below. |
| frames | INT | 00–1024 | Frame count. 0 is an image model with no time axis, anything above 0 is a video model. |
| factor | INT | 00–64 | Snaps width and height to a multiple of this number while keeping the aspect ratio. 0 adds no snapping, but both sides are always a multiple of 8 anyway - a latent unfolds 8 pixels per cell, so anything else would silently come out smaller than reported. The coarser the snap, the further apart the sizes a ratio can reach: at 32 a 16:9 frame moves in width steps of 512. Leave 0 when the ratio matters. |
| latent_channels | COMBO | 4 | Channels of the latent this node hands out. Any sampler rewrites this to whatever the model wants before denoising, so 4 versus 16 almost never matters - it only shows on the paths that skip the sampler. 4 for SD 1.5 / SDXL, 16 for Flux / SD3 / video. |
| widthopt | * | Optional width override of any type, parsed as a number. Wired in and above 0, it takes priority over the preset. Rounded up to a multiple of 8. | |
| heightopt | * | Optional height override of any type, parsed as a number. Rounded up to a multiple of 8. | |
| mpopt | FLOAT | 0.000–64 | Megapixels: 0 means unused. Given a value, the size comes from this area while the shape still follows the ratio or the preset, for example 1.0 or 2.0. |
| ratio_customopt | STRING | Custom aspect ratio such as 2.39:1, 5 4 or 1.85. Filled in, it wins over the ratio dropdown above; empty means the dropdown decides. |
Outputs (4)
| Name | Type | Description |
|---|---|---|
| LATENT | LATENT | The empty latent tensor. |
| WIDTH | INT | The width actually used. |
| HEIGHT | INT | The height actually used. |
| FRAMES | INT | The frame count actually used (0 = image model). |