Nodes/Comfyui-reference-loader/Downscale Image to Megapixels
ComfyUI Node

Downscale Image to Megapixels

The downscaler that only ever shrinks (and why that's the point)

By sthao42·Created 4 days ago·Updated a day ago· 2
Downscale Image to Megapixels
  • image
  • image
megapixels1.00
methodlanczos

Feed it a 5000-pixel-wide phone photo and it quietly shrinks it to fit your budget. Feed it something small and it does nothing at all. That second half isn't a bug - it's the whole point of Downscale Image to Megapixels.

The name is doing a lot of work, so let's be precise about what it isn't. This node never upscales. It takes an IMAGE, checks whether the total pixel count already fits inside your megapixels budget, and if it does, hands the image straight through untouched. If it doesn't, it scales the whole thing down while preserving aspect ratio until it does. There's no fixed target resolution, no stretching, no letterboxing - just a ceiling you can park in the middle of a workflow and forget about.

It ships in the Comfyui-reference-loader pack as the standalone version of a trick that pack's big Load Image & Crop node does internally. The crop node lets you lock a crop to an aspect ratio and cap it to a megapixel budget before it leaves. This node is that same budget logic, pulled out so you can apply it to an image that didn't come from a crop box - a VAE decode, an img2img source, a ControlNet input, anything.

Why you'd actually add it to a graph

Diffusion models are trained on a megapixel band, and the community keeps rediscovering that feeding them a 12-megapixel DSLR shot is the wrong move: it costs you VRAM, slows the encode, and most models quietly recompress the image to their own native resolution anyway - badly, since they're guessing. Slamming a giant reference through a ControlNet preprocessor is even worse, because most preprocessors are resolution-sensitive. So the classic job is: cap the source before it ever reaches the sampler.

Honest note, because you deserve one: ComfyUI's built-in ImageScaleToTotalPixels does something very close. The real difference is behavioral. The core node normalizes - if your image is under the target it gets upscaled up to it. This node only caps: already-small images pass through at full quality, which makes it safe to drop inline as a guard. If you want "shrink the monsters, leave the good ones alone," this is the friendlier tool. If you genuinely need everything forced to exactly N megapixels, use the core node.

The corollary: this is a two-input utility, not a reason to install the pack. It's the node you reach for because you already have Comfyui-reference-loader for its crop/audio loaders. Don't download four nodes for one resizer.

The inputs that matter

  • megapixels (FLOAT, default 1.0) - your budget. 1.0 MP is 1024×1024 worth of pixels, the resolution band most current models are happiest eating. Dial it toward 0.5 for a cheap low-res first pass or image-to-video where you'll upscale after; the pack's own sibling nodes treat a megapixel budget the same way. Range is 0.01 to 128.
  • method (enum, default lanczos) - the resampling filter. Leave it on lanczos for quality. Switch to area if you're shrinking a lot and worried about moiré/shimmer, since area-averaging antialiases properly. nearest-exact is there for pixel art. The others are speed options.
  • image (optional IMAGE) - leave this unconnected and the node outputs None, which is a neat way to build an optional/reference branch that quietly mutes itself.

Output: one image (IMAGE). None if nothing was connected.

How to install it

Install the whole pack, then restart ComfyUI. Easiest path is ComfyUI Manager - search "Comfyui-reference-loader". Or:

cd ComfyUI/custom_nodes
git clone https://github.com/sthao42/Comfyui-reference-loader

Then restart. There are no model downloads and no keys. The pack declares torch/numpy/pillow/av as dependencies, but those already ship with ComfyUI, so the README's "no extra Python dependencies" claim holds up in practice.

Where people get tripped up

The trap is expecting it to do what the core node does. Set megapixels to 1.0, feed in a 512×512 image, and you'll get your 512×512 back with nothing changed - which looks like a silent failure if you assumed "scale to megapixels" meant "make it exactly that size." It's a cap. If you wanted a resize in the other direction, that's core's ImageScaleToTotalPixels or a plain ImageScale doing the work.

Mechanically it's dead simple under the hood: it computes target = megapixels × 1024 × 1024, scales by the square root of the ratio when you're over, and resizes the whole batch at once with ComfyUI's common_upscale. Aspect ratio never changes and the result is clamped back to a valid image range. That simplicity is the feature - it's the rare node that does exactly one thing and refuses to surprise you.

Categoryreference_loader/image

Inputs (3)

NameTypeDefaultDescription
megapixelsFLOAT1.000.01–128Maximum output size in megapixels (1.0 = 1024x1024 pixels). Larger images are scaled down to fit; smaller ones pass through untouched.
methodCOMBOlanczosResampling filter used when downscaling.
imageoptIMAGEThe image to downscale. Leave unconnected to output None (bypass).

Outputs (1)

NameTypeDescription
imageIMAGEThe image scaled down to the target megapixel budget (or None if unconnected).