Nodes/ComfyUI-PixelConstrainedScaler/Pixel Constrained Scaler
ComfyUI Node

Pixel Constrained Scaler

The scaler that only does math — and saves your VRAM doing it

By neonr-0·Created 10 months ago·Updated 10 months ago· 1
Pixel Constrained Scaler
  • image
  • image_passthrough
  • constrained_width
  • constrained_height
  • constrained_aspect_ratio
  • original_aspect_ratio
min_res256
max_res2048
max_megapixels2.4
scaling_factor1.5
multiple_of8

Pixel Constrained Scaler does not resize your image. Read that again, because it's the whole trick: it's a calculator with an image input. You feed it a picture, it works out what width and height you should resize to so you stay under a hard megapixel cap while keeping the aspect ratio, and it hands you the numbers plus the untouched image. Then you plug those numbers into an actual resize node. It exists because "just feed the big image in" is exactly how ComfyUI workflows OOM - video models especially will happily try to process a 4K still and eat your whole VRAM.

The author's own pitch is image-to-image and image-to-video, and that's the honest use case. It's also a neat fit for the workflow the upscaling crowd keeps rediscovering: downscale a soft source before you run a generative upscaler, because there's no detail at full resolution to recover anyway. This node gives you a clean way to enforce that "never exceed N megapixels" rule without hand-computing sizes.

How the math works

The logic is straightforward, and the code spells it out in cases:

  • If the input is already over the megapixel cap and you didn't ask to scale down, it shrinks to the cap, preserving aspect ratio.
  • If the input is under the cap, it tries applying your scaling_factor - but if that would blow past the cap, it pulls back down.
  • If you set scaling_factor under 1.0, that's an explicit downscale, and it always wins - it applies to the original before any clamping.
  • Everything gets rounded to your multiple_of and clamped to your min/max resolution bounds.

It handles batches (it reads the tensor shape, so a whole video batch gets one consistent target size) and it'll print a Notice: line to your console when the cap silently trims your requested scale - which is genuinely helpful debugging, not noise.

The inputs that matter

You only really touch three of these:

  • max_megapixels - the hard ceiling in millions of pixels. The default 2.36 MP is 1536×1536, which is right at the top of where a lot of SDXL-era and current models stay coherent. This is the OOM guard.
  • scaling_factor - how much to scale relative to the current image (1.0 = no change, 2.0 = double, 0.5 = halve). The cap takes priority when the original is already too big.
  • multiple_of - rounds the result so dimensions land on 8 or 64, which your model's VAE and a lot of node packs want. Default 8 is usually fine; set 64 for Flux-style pipelines.

min_res and max_res are safety rails for extreme aspect ratios. The image input is just analyzed, never touched.

The outputs and how to wire them

Five outputs. image_passthrough is your original image, byte for byte. constrained_width and constrained_height are the numbers you actually want - wire those into an ImageScale (or a latent-scale / empty-latent-size node) to do the real work. constrained_aspect_ratio and original_aspect_ratio are informational; grab them if you want to compare how far the constraints pushed you.

Install

Clone it into custom_nodes:

cd ComfyUI/custom_nodes
git clone https://github.com/neonr-0/ComfyUI-PixelConstrainedScaler.git

Then restart ComfyUI. It's also on the Comfy registry, so ComfyUI Manager should find it by searching "ComfyUI-PixelConstrainedScaler" - the easy route. There are no dependencies, no model downloads, nothing heavy. The entire node is one file of pure Python math.

Gotchas

The classic miss is wiring image_passthrough straight into your KSampler and wondering why nothing changed. The node only computes - you have to wire the width/height into a resize. If you hit a ValueError, it's almost always a bad config: max_res must be greater than min_res, and multiple_of must be at least 2. And one real edge case from the code: if you set min_res so high that even the minimum dimensions exceed your megapixel cap, the min/max clamps take priority and the cap quietly loses - don't set min_res anywhere near the square root of your cap.

It's a small, single-purpose node, and that's fine. There's no AI in the "scaler" - no key, no API, no models - which makes it about as safe a custom node as this ecosystem offers.

Categoryimage/resolution

Inputs (6)

NameTypeDefaultDescription
imageIMAGEInput image to analyze for resolution constraints
min_resINT256Minimum allowed dimension (width/height) in pixels
max_resINT2048256–8192Maximum allowed dimension (width/height) in pixels
max_megapixelsFLOAT2.4Maximum allowed resolution in megapixels (e.g., 2.3 = 2.3 million pixels)
scaling_factorFLOAT1.50.1–4Additional scaling factor (1.0 = no change, 2.0 = double size). Megapixel limit takes priority when original image is larger than the cap.
multiple_ofINT8Ensure dimensions are multiples of this number (8, 64, etc)

Outputs (5)

NameTypeDescription
image_passthroughIMAGE
constrained_widthINT
constrained_heightINT
constrained_aspect_ratioFLOAT
original_aspect_ratioFLOAT