_UltraAspectFitImage
The node that reshapes your reference without cropping her face off
- image
- IMAGE
You will probably never add this node yourself. It shows up in your graph because you ticked a dropdown on its parent, and then you wonder what this underscore-prefixed box is doing between your reference image and the VAE. Short answer: it re-frames your reference photo into a canvas the Qwen VAE is happy with, and it does it without cutting anything out of the picture.
Why a whole node for "change the aspect ratio"
The Qwen Image Edit line - 2511 is still the open one worth running - works by looking at your reference and re-emitting the frame. It doesn't patch pixels, it redraws the whole thing, which is exactly why identity survives and exactly why framing matters so much. Change the input aspect ratio wrong and you get the geometric offset people keep posting about: proportions skew, the head sits low, the subject drifts. (See kg/entities/qwen-image-edit.json for the "whole-frame re-emission" failure mode in the authors' own words.)
So when the main node is set to auto aspect by framing, it wants a specific canvas per shot type: 3:4 for faces and upper-body shots, 2:3 for head-and-shoulders, thigh-up and full-body. It doesn't trust LoadImage to have given it one. Instead it forks the reference through _UltraAspectFitImage first, one instance per (reference, aspect) pair, and VAE-encodes the result. That's the entire job.
What it actually does
Two things, in this order.
It picks a size on a 32-pixel grid. 3:4 lands on multiples of 96×128 (864×1152, 960×1280, …). 2:3 lands on multiples of 64×96 (832×1248, 960×1440, …). The target pixel count tracks your source - a 1024×1024 photo comes out as 864×1152 - and it's hard-capped at 1.5 megapixels so you don't accidentally hand the sampler a 4K reference. It rounds to the nearest legal size rather than truncating, so you can end up a few percent above the source pixel count. That's fine.
It fits, it does not crop. The node builds a background by centre-cropping the source to the target ratio, resizes that to fill the canvas, and blurs it hard (radius scales with the canvas, minimum 8px). Then it scales the whole original down to fit inside that canvas, centred, and pastes it on top. No black bars, no missing chin, no squashed proportions. The toll you pay is that the model sees a soft, smeared echo of your subject around the edges of the real one.
For a LoRA dataset that's the right trade. A cropped ear in your reference becomes a cropped ear in all forty generated images.
Inputs and output
There are exactly two inputs and one output.
image- the IMAGE to re-frame. Batches are fine; every frame gets the same target size.aspect- an enum with two choices,3:4and2:3. Nothing else is accepted.
Out comes a single IMAGE with the same dtype and device it came in on. Wire it into a VAEEncode (the 2511 path) and that latent becomes the reference conditioning; on the Qwen Image 2.1 path the fitted image goes straight into the encoder node, which derives its own starting latent from it. That's why the ratios are fixed to those two: they're what the parent node's framing plan assigns, not a free-form resize control.
Installing it
It ships inside the pack, so there's nothing separate to fetch. ComfyUI Manager → Custom Nodes Manager → search Ultra LoRA Reference Images, or:
cd ComfyUI/custom_nodes
git clone https://github.com/Yamoon-jjang/comfyui-Ultra-LoRA-Reference-Images
Restart. The pack's requirements.txt genuinely has no packages in it - torch, numpy, Pillow and aiohttp come from ComfyUI itself - so there is no pip step to fail.
It's registered like any other node, just filed under the _internal category with a leading underscore - search "Ultra Aspect Fit" rather than "AspectFit" and it turns up. You can add it by hand if you're building a Qwen edit graph yourself and want a reference prepositioned at 3:4 without losing the sides of the frame.
Where it bites
- It never upscales meaningfully. If your reference is 512×512, you get roughly a 480×640 canvas. Feed it the biggest clean copy you have.
- Alpha is dropped, not composited. Only the first three channels are read. Fine for photos, odd for premultiplied PNG cut-outs.
aspectvalidates hard. Anything that isn't one of the two strings throws. From the parent node this can't happen; if you're scripting the node directly, it can.- The blur surround is real. Your subject sits faithfully in the middle, but the model is looking at a smeared double behind them.
Inputs (2)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | — | |
| aspect | COMBO | 2 options: 3:4, 2:3 |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| IMAGE | IMAGE | — |