Aspect Ratio to Size (Trim Margin)
Overscan your sampling, crop clean afterward
- width x height
- width
- height
- margin
Here's a workflow trick that looks weird until you see why it exists: sample an image larger than you actually want, with margins around the edges, then crop the margins off afterward. The extra border gives the diffusion model room to breathe - edges of a generation are where artifacts gather, and anything composited or upscaled later benefits from starting with context outside the final frame. Aspect Ratio to Size (Trim Margin) is this pack's version of that overscan idea: it computes a sampling size that extends past your target edges, keeps it on clean resolution steps, and bundles the four margins so a matching trim node can crop it back to exactly what you asked for.
It's the sibling of the plain Aspect Ratio to Size and ships in the same pair as the pack's Trim Image by Margin node - the one eats the other's output.
How it works
You specify the size you want after trimming, and the node works out the sampling size including margins. The fields split along that line:
width_ratio/height_ratio- your target aspect after trimming.actual_width/actual_height- the size remaining after the crop. These are the ones you edit.width/height- the sampling size including margins. Read-only; this is what you feed the sampler.margin_top/margin_right/margin_bottom/margin_left- the four edges.min_unit(default 32) - the snap step for the sampling size.actual_ratio- read-only display of the trimmed ratio.
The clever constraint is in how the margins work: the top and bottom margins are linked (their total is either 0 or min_unit), and so are right and left. That keeps the sampling size divisible by min_unit while preserving symmetry in how much overscan each side gets. The whole sampling size stays on the resolution step grid, so you never pay the "can't divide by 64" tax to get the overscan.
Outputs are the same size bundle as the base node - width x height, width, height - plus a margin output that carries the four edge values for Trim Image by Margin. Leave margin unconnected and the trim node passes the image through untouched, which is the safe default.
Why overscan at all?
Two honest reasons. First, seam and edge quality: diffusion models produce weaker content near image borders, so sampling with margins means the useful region of the latent is interior, not edge. Second, post-processing: if you're upscaling or compositing, having clean, exactly-ratioed edges to trim to beats trying to sample exactly the target size and praying the model lands on it.
The one footgun
The margin fields are linked, not free - you can't set an arbitrary overscan on just one side and expect the node to keep the size divisible. That's a feature (it preserves the alignment invariant), but it surprises people who want an asymmetric crop. If you genuinely need lopsided margins, do the crop with a general crop node instead; this one is built for the symmetric overscan case.
Installing
Part of kinorax/comfyui-info-prompt-toolkit:
cd ComfyUI/custom_nodes
git clone https://github.com/kinorax/comfyui-info-prompt-toolkit.git
cd comfyui-info-prompt-toolkit
pip install -r requirements.txt
or install "Info-Prompt-Toolkit" via ComfyUI Manager, then restart. No model files. Pair it with Trim Image by Margin from the same pack - they're designed as one unit, and the pack's Set Margin Extra / Get Margin Extra nodes can even store the margins in image-info extras so they survive a save/load round-trip.
Inputs (12)
| Name | Type | Default | Description |
|---|---|---|---|
| width_ratio | INT | 101–4096 | Aspect ratio width after trimming margins |
| height_ratio | INT | 161–4096 | Aspect ratio height after trimming margins |
| min_unit | COMBO | 32 | Minimum size step for the sampling size including margins |
| margin_top | INT | 00–16376 | Linked with margin_bottom; their total is 0 or min_unit |
| margin_right | INT | 00–16376 | Linked with margin_left; their total is 0 or min_unit |
| margin_bottom | INT | 00–16376 | Linked with margin_top; their total is 0 or min_unit |
| margin_left | INT | 00–16376 | Linked with margin_right; their total is 0 or min_unit |
| width | INT | 8648–16384 | Sampling width including margins (display only) |
| height | INT | 13768–16384 | Sampling height including margins (display only) |
| actual_width | INT | 8648–16384 | Width remaining after trimming margins |
| actual_height | INT | 13768–16384 | Height remaining after trimming margins |
| actual_ratio | STRING | Actual ratio after trimming margins (display only) |
Outputs (4)
| Name | Type | Description |
|---|---|---|
| width x height | IPT-Size | — |
| width | INT | — |
| height | INT | — |
| margin | IPT-Margin | — |