图像缩放
Resize with crop, pad or contain — and get the real numbers back
- image
- IMAGE
- WIDTH
- HEIGHT
Core's ImageScale does one thing: push an image to a width and height, aspect ratio be damned. That's fine until you need the image to fit a box without being squashed, and then you're doing mental arithmetic with ratios. 图像缩放 (QG_ImageResize) is the resizer for people who've been bitten by that - three fit modes, pixel or percentage measurement, and two integer outputs telling you what you actually ended up with.
How it works
Pick a measurement. On pixels, width and height are target pixel dimensions. On percentage, they're percentages of the original - 50 and 50 halves the image, 200 and 200 doubles it, and the two axes are computed independently, so mismatched percentages stretch.
Then fit decides how the image occupies the target box:
- crop - scale up until the image covers the box, then centre-crop the overflow. Output is exactly
width × height. This is the one you want for fixed-size model inputs where squashing would be visible. - pad - scale down until it fits entirely, then centre-pad the gaps. Output is exactly
width × height. Note the padding is black, not configurable - it's a zero tensor. - contain - scale to fit and stop there. Output can be smaller than the box on one axis, aspect intact. Nothing is cropped, nothing is padded.
Under the hood it calls ComfyUI's own common_upscale, so the resampling methods are the ones core exposes - nearest-exact, bilinear, area, bicubic, lanczos - and any improvement upstream makes to them shows up here without a pack update. Downscaling with area or lanczos is the sane default; nearest-exact is for pixel work where you want hard edges preserved.
Two shortcuts worth knowing because they're easy to misuse:
- Set either dimension to
0and it's derived from the other with the aspect ratio locked, which also forcescontain. Sowidth=1024, height=0means "1024 wide, however tall that makes it". - If both are
0, or if the requested size already matches the input, the image comes straight back untouched.
Inputs and outputs
image(required, IMAGE)measurement(required, enum:pixels/percentage)width,height(required, INT, 0–16384) - pixels or percent depending on measurement;0means derive.fit(required, enum:crop/pad/contain)method(required, enum) - resampling filter.- Outputs:
IMAGE, plusWIDTHandHEIGHTas INTs - the actual output dimensions, after everything.
Those two integers are the reason to prefer this over the core node in a big graph. Any subsequent step that needs to know the size - a blur radius that should scale, a crop that should centre, a paste that needs coordinates - can be wired instead of typed. The KB's plumbing notes are blunt about this being the whole point of value nodes: one source, fanned out, no silent mismatch when the image changes.
Install
cd ComfyUI/custom_nodes
git clone https://github.com/live1617/ComfyUI-QG-tools
Full restart; the console prints [QG-tools] v0.9.2 加载完成 | 节点数 24. Manager search ComfyUI-QG-Tools covers the registry case. No pip dependencies - the requirements file is comments only, deliberately, so Manager runs no pip step.
Ported from rgthree-comfy (MIT), searchable as resize, scale, fit or 图像缩放.
Where people get burned
Black bars from pad. The fill is zeros. If you're padding to a 16:9 frame and expecting it to blend into a white banner, it won't. Pad first, then composite, or pad onto a colour yourself.
Byte-identical early return. If the requested size equals the input size the node skips the resize, so an "upscale to 1024" that's already 1024 does nothing at all - including not re-encoding the image through a filter. Usually what you want; occasionally the reason a chain looks like it skipped a step.
Percentages round. round(width * W / 100) on each axis. At small sizes, 33% of 500 is 165 and 33% of 501 is 165 too - two images from the same pipeline can land one pixel apart. If exact matching matters, use pixels.
Un-divisible output sizes. There's no rounding to multiples of 8 here. A contain-fit of an odd aspect ratio regularly produces sizes that a VAE will round for you on the way in, which is fine, but the WIDTH you're reading is the pre-VAE number. Don't feed it to a latent-shaping node and expect the sampler to agree.
Inputs (6)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | — | |
| measurement | COMBO | 2 options: pixels, percentage | |
| width | INT | 00–16384 | 目标宽度:度量选「像素」时为像素值,选「百分比」时为相对原图的缩放百分比;填 0 表示由高度按比例推算。 |
| height | INT | 00–16384 | 目标高度:度量选「像素」时为像素值,选「百分比」时为相对原图的缩放百分比;填 0 表示由宽度按比例推算。 |
| fit | COMBO | crop:放大铺满目标框后居中裁掉多余部分,输出恰为目标尺寸。 pad:缩放到完全放进目标框后居中补齐空缺,输出恰为目标尺寸。 contain:缩放到完全放进目标框即返回,某一侧可能小于目标尺寸。 宽或高任一为 0 时,实际按 contain 处理。 | |
| method | COMBO | 5 options: nearest-exact, bilinear, area, bicubic, lanczos |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| IMAGE | IMAGE | 缩放后的图像。 |
| WIDTH | INT | 输出图像的实际宽度。 |
| HEIGHT | INT | 输出图像的实际高度。 |