Scale from Prepare Info
Did You Actually Gain Pixels, or Just Crop?
- prepare_info
- value
This is the reader that answers the question everyone asks about their prepared photo: what happened to it? It takes the typed preparation result, you pick which number you want, and it hands you one FLOAT.
The field dropdown is the whole node:
scale_factor(default) - the resize applied to the padded canvas, as a single factor.scale_x/scale_y- the same thing per axis, which is not always identical once padding and a forced aspect ratio are in play.crop_loss_percent- the percentage of source pixels thrown away by the crop. Note the units: this one is a percentage, not a ratio, and it counts discarded source pixels only, not padding.
One output, value.
Why it's worth a node
Because scale_factor and crop_loss_percent pull in opposite directions, and a good-looking preparation can be bad on one of them.
scale_factor describes resizing the padded canvas up to your editor tier. Under 1.0 means you downscaled - the tier was smaller than your crop, so you threw detail away before the model ever saw it. That's the number that tells you whether "Auto (preserve detail)" picked the tier you expected; on a 20 MP scan, no tier is going to preserve everything, and this is where you find out how much got shed.
crop_loss_percent tells you how aggressively the framing cut in. A tight portrait crop that discards 65% of a page scan is usually a good move - you didn't want the tablecloth. The same number on a landscape photograph where you meant to keep the whole scene is a warning that your forced aspect or your mask pushed the frame somewhere you didn't intend.
Read together, they separate two very different failures: "the model got fewer pixels than I had" (scale) versus "the model never saw the part I cared about" (crop).
scale_x versus scale_y is the subtle one and the reason both exist. When the target aspect ratio doesn't match the crop-plus-padding shape, the two axes don't scale equally, and comparing them tells you how much the frame was stretched to fit rather than cropped to fit. It's also the pair you want if a downstream node needs to map coordinates between prepared_image and the original - though if you're doing that, use the coordinate transforms in the JSON diagnostics rather than rolling your own from the scale factors, because padding shifts the origin.
Wiring
Smart Photo Prepare.prepare_info → Scale from Prepare Info.prepare_info
field = crop_loss_percent
value → a display/note, a comparison, a gate
The float is a plain value, so it drops into anything numeric: a note node while you tune framing, a switch that routes to a bigger upscale when scale_factor came out above 1, or a filename suffix that records what happened. It does not modify the image - it only reads the plan.
Setting field to something the node doesn't know raises out loud, naming the field and the valid set, rather than silently returning zero. Same pattern as the rest of the readers: a wrong connection is an error you can read.
Install
Shipped in the pack. ComfyUI Manager → search PortraitUtils → install, then restart the ComfyUI server; a browser refresh won't pick up new Python nodes.
cd ComfyUI/custom_nodes
git clone https://github.com/heyburns/PortraitUtils
/path/to/ComfyUI/venv/bin/python -m pip install -r PortraitUtils/requirements.txt
Use ComfyUI's own Python - the venv's bin/python on Linux/macOS, python_embeded for Windows portable installs. The pack's requirements are just numpy, Pillow, opencv-python-headless, and tifffile; keep to a single OpenCV wheel variant. It lives under PortraitUtils/Photo Edit V2/Readers.
If value is 1.0 and you expected something else, that's usually not this node - it means preparation chose a tier matching your crop, which is the healthy case, or you're on the Direct / No Editor path where the source scale is deliberately retained. Check the Active Editor Target before you go hunting for a bug.
Inputs (2)
| Name | Type | Default | Description |
|---|---|---|---|
| prepare_info | PORTRAIT_PREPARATION_INFO_V2 | — | |
| field | COMBO | scale_factor | 4 options: scale_factor, scale_x, scale_y, crop_loss_percent |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| value | FLOAT | — |