Fit To Aspect Node
Fit any image to a target aspect ratio without the letterbox math
- image
- image
- pad_top
- pad_bottom
- pad_left
- pad_right
If you've ever needed to shove a 4:3 photo into a 16:9 canvas for an img2img pass, a ControlNet workflow, or a video model that demands a specific frame size, you know the drill: resize, do the padding math by hand, hope the result doesn't look squished. Fit To Aspect Node does that one job - resize an image to fit inside a target aspect ratio, then hand you back the exact padding values it would take to fill the rest. No distortion, no guesswork.
It's a tiny node from a tiny pack (one class, no extras), and nobody on Reddit is talking about it, so treat this as the source-code read rather than community lore. It works - with one surprise about what it doesn't do, below.
How it works
Drop in any IMAGE, pick an aspect ratio, and the node does the geometry for you:
- Fit inside, don't crop. It scales the image down with Lanczos so it fits within the target while keeping the original proportions. If your image is already smaller than the target, it leaves it alone - this node never upscales.
- 11 presets with sensible target resolutions: 1:1 → 1024×1024, 16:9 → 1392×752, 21:9 → 1568×672, 3:2, 2:3, 4:5, 5:4, 3:4, 4:3, and the rotated video ones 9:16 and 9:21. Or type a custom
width:heightorwidthxheight(e.g.1280:720) for your own target pixels. - Padding placement is yours to choose.
expansion_directiondefaults tocenter, buttop,bottom,left,right, and the four corners are all recognized - pick which side gets the letterbox.
Here's the thing the README gets wrong: the Spanish README claims it "fills the empty areas with black." It does not. Read the source and you'll see it only computes the pad amounts and returns them as integers - the returned image is the resized-but-unpadded picture. The author set it up so you wire the four pad values into a padding node (KJNodes' ImagePad is the usual suspect) and do the composite yourself. The pads are the whole point: pad_top, pad_bottom, pad_left, pad_right each come out as an INT telling you exactly how many pixels to add on that side.
Inputs and outputs that matter
Only three inputs, all required: image, aspect_ratio (default 16:9), and expansion_direction (default center). Both text fields are plain strings, not dropdowns - ComfyUI renders them as text boxes, so type the values exactly. That matters because a misspelled direction like centre matches no branch in the code, the pad variables never get set, and the node throws an UnboundLocalError instead of quietly doing something reasonable. If it's erroring for no obvious reason, check your spelling first.
Outputs: image plus the four pad_* ints described above. Feed image → your pad node, feed the pad ints into its padding inputs, done.
Install
The easy way: ComfyUI Manager → search "FitToAspectNode" (or the pack title "ComfyUI Charly FitToAspectNode") → install → restart. Manual way:
cd ComfyUI/custom_nodes
git clone https://github.com/charlyad142/ComfyUI_Charly_FitToAspectNode
# restart ComfyUI
It'll show up in the image/resize category. Dependencies are just torch, numpy and Pillow - all already part of a working ComfyUI install, and the whole thing runs on CPU. There's no requirements.txt, no model files, no GPU work. This is one of those packs where the risk is basically zero.
The gotchas worth knowing
- It won't give you a padded image on its own. The README oversells; if you wire the output straight into a sampler you'll get a smaller-than-target image, not a letterboxed one. Add the pad step.
- Batches get silently dropped. If your input has a batch dimension, it only processes the first frame and returns a batch of one. Fine for stills, wrong for video pipelines that pipe whole batches in.
- Small sources stay small. No upscaling here - if you need to grow an image to fill a canvas, pair it with a proper upscaler (a hires-fix pass or ESRGAN) before or after.
Honest verdict: for a one-job utility this is solid, and the pad-output design is actually the right call even if the README didn't explain it. It's not going to replace ImageScale or a proper crop-and-stitch node for serious work, but when you just need a clean fit-to-canvas with known padding, it does exactly what it says on the tin - math included.
Inputs (3)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | — | |
| aspect_ratio | STRING | 16:9 | — |
| expansion_direction | STRING | center | — |
Outputs (5)
| Name | Type | Description |
|---|---|---|
| image | IMAGE | — |
| pad_top | INT | — |
| pad_bottom | INT | — |
| pad_left | INT | — |
| pad_right | INT | — |