Nodes/PortraitUtils/Scale from Config
ComfyUI Node

Scale from Config

Hand a plain FLOAT to somebody else's upscaler

By heyburns·Created about a year ago·Updated 23 days ago· 3
Scale from Config
  • finish_config
  • scale
◄scalefinal_upscale►

What it's for

Your upscale factors live in a Finish & Run Config bundle. Most upscalers are not PortraitUtils nodes and want a plain FLOAT - an "upscale by" widget or a scale input. Bundles don't connect to primitive sockets, so something has to unpack it.

Scale from Config does exactly that: finish_config in, scale out, and a selector telling it which of the two factors you want. No maths, no state, no side effects.

Inputs and outputs

Required: finish_config (PORTRAIT_FINISH_CONFIG_V2) and scale, a dropdown with two options - initial_upscale or final_upscale. Default is final_upscale. That's the entire node. Output: scale (FLOAT).

The two values come from the config as 0.1–100. If you need them, they're 2.0 and 4.0 out of the box - the default shape being "one moderate pass to get the pixels, one heavier pass for detail."

Where it fits

Keep the decision in the config and the consumer wherever it already is:

Finish & Run Config ──> Scale from Config [initial_upscale] ─ FLOAT ─> first upscaler
                    └─> Scale from Config [final_upscale]   ─ FLOAT ─> second upscaler

Two readers, two consumers, one place to change the numbers. If you find yourself editing three widgets across two nodes to change a 2x into a 3x, this node is the fix - and it's a much smaller fix than a context-bus overhaul.

Worth being clear about what a scale factor does and doesn't buy you. If your upscaler's job is more pixels - an ESRGAN model, a Lanczos resize - then 4x is a deterministic multiplier and this reader is exactly right. If its job is more invented detail - a tile-ControlNet pass, a detail model - then the factor is closer to a hint, and pushing it past what the model handles well gives you softness, not detail. And in both cases, most of these numbers only make sense as a final step: an upscale early in the chain means every later operation runs on 4x the pixels for no gain.

Where people get burned

Feeding this into the wrong socket. It emits a FLOAT; if your upscaler's scaling widget takes a plain number, perfect. If it exposes a fixed model choice or an enum of 2x/4x, you're better off setting that node's own widget and skipping the reader - a converter isn't going to invent a dropdown for you.

The other one is subtler: because the value arrives as a wire, the upscaler's own widget disappears or gets overridden, depending on the node. If a scale change doesn't seem to take effect, check whether the bundle is actually connected - a disconnected reader input doesn't error, it just isn't there.

And don't try to route finish_config into a generic primitive node. It's a typed bundle; only PortraitUtils readers and consumers take it.

The whole family is one input, one output, zero decisions:

  • Seed from Config - the run seed as an INT.
  • Crop Prompt from Config - subject_mask as a STRING.
  • Edit Prompt from Config - one of the four edit/stitch prompts.
  • Outpaint Prompt from Config - the outpainting prompt.
  • Save Info from Source - filename and output directory from the loader.

Install

Part of PortraitUtils. ComfyUI Manager → search PortraitUtils (publisher heyburns, GPLv3), or:

cd ComfyUI/custom_nodes
git clone https://github.com/heyburns/PortraitUtils
/path/to/ComfyUI/venv/bin/python -m pip install -r PortraitUtils/requirements.txt

Install into ComfyUI's Python environment - numpy, Pillow, opencv-python-headless and tifffile, with only one OpenCV variant - then restart the ComfyUI server. The pack supplies no upscaler weights; bring your own ESRGAN or detail model.

CategoryPortraitUtils/Config V2/Readers

Inputs (2)

NameTypeDefaultDescription
finish_configPORTRAIT_FINISH_CONFIG_V2—
scaleCOMBOfinal_upscale2 options: initial_upscale, final_upscale

Outputs (1)

NameTypeDescription
scaleFLOAT—