Nodes/ComfyUI_Swwan/Image Resize By Megapixels (Swwan)
ComfyUI Node

Image Resize By Megapixels (Swwan)

Target megapixels, not random pixel sizes

By aining2022·Created 9 months ago·Updated 11 days ago· 33
Image Resize By Megapixels (Swwan)
  • image
  • mask
  • IMAGE
  • width
  • height
  • mask
  • longest_edge
megapixels1.00
aspect_ratiodefault
keep_proportioncrop
divisible_by16
default_divisiblefalse
upscale_methodbilinear
crop_positioncenter
pad_color0, 0, 0
device

Every model has a resolution it likes. SD 1.5 is happiest around 512, SDXL around 1024, Flux a bit bigger - and the usual way to get there is a resize node where you type the exact width and height, or you do the square-root math in your head. ImageResizeByMegapixels from the ComfyUI_Swwan pack does the math for you: you say "I want about a megapixel," and it figures out the dimensions that get you there while keeping the aspect ratio.

It's part of a growing habit in ComfyUI of thinking in total pixels instead of WxH. When a workflow asks for a "1.0 MP" input, or you're standardizing a dataset so every image has roughly the same information content, this is the node. A 512x512 and a 1024x512 are the same total pixels but wildly different crops; targeting megapixels is the honest way to compare them.

How it works

The math is simple: target pixels = megapixels × 1,000,000, then it works out a scale factor so width × height lands near that total while keeping your chosen ratio. Then it floors the dimensions to divisible_by (16 by default), which is the part that actually matters to diffusion models - most latent spaces want multiples of 8 or 16 to avoid VAE tiling artifacts.

Under the hood it has two paths. If you keep aspect_ratio on "default" and leave it on CPU, it uses a fast direct torch resize that matches the "resize" mode of the pack's ImageResizeKJ v2 node. If you're forcing a new aspect ratio or passing a mask, it hands off to that same node and lets keep_proportion decide how to handle the mismatch.

The inputs that matter

  • megapixels - target total pixels. 0 means "skip, return the image untouched," which is handy for a pass-through in a workflow you don't want to disable.
  • aspect_ratio - "default" keeps the source ratio; otherwise pick 1:1, 16:9, 4:3, etc.
  • keep_proportion - what to do when the new ratio doesn't match: crop cuts, pad fills with pad_color, resize distorts, and pillarbox_blur blurs the background bars.
  • divisible_by - floor the output to a multiple. Default 16 is the right call for most pipelines.
  • upscale_method - bilinear default is fine; lanczos if you're enlarging and want it sharp.

You also get mask and device as optional inputs. Outputs are the resized IMAGE plus width, height, longest_edge (all INT, handy for feeding other nodes) and a resized mask if one came in.

Installing it

It ships inside the ComfyUI_Swwan pack, which bundles a grab-bag of nodes migrated from LayerStyle, rgthree and KJNodes. Either search "ComfyUI_Swwan" in ComfyUI Manager, or:

cd ComfyUI/custom_nodes
git clone https://github.com/aining2022/ComfyUI_Swwan
pip install -r ComfyUI_Swwan/requirements.txt

The requirements are heavy (torch, opencv, scipy, scikit-image, onnxruntime) but you'll already have most of them.

Where people get burned

The "target" megapixels is a floor-and-round, not an exact value - after the divisible-by rounding you can land a few percent under. That's usually fine, but if you genuinely need exact dimensions, this isn't the node. And the pad modes only matter when you're forcing a ratio; with "default" they never fire. The one thing to check: when you enlarge a lot, bilinear gets soft - bump to lanczos or resize in two steps with an upscaler model in between (that's a different job, covered in the KB's upscaling essay).

CategorySwwan/image

Inputs (11)

NameTypeDefaultDescription
imageIMAGE
megapixelsFLOAT1.000–100Target megapixels (1.0 = 1 million pixels). Use 0 to skip resize and keep the original size.
aspect_ratioCOMBOdefaultTarget aspect ratio. 'default' keeps original ratio.
keep_proportionCOMBOcropHow to handle aspect ratio change when not using 'default'.
divisible_byCOMBO16Width and height will be divisible by this value.
default_divisibleBOOLEANfalseWhen enabled, ensures final output dimensions strictly follow divisible_by constraint.
upscale_methodCOMBObilinear6 options: nearest-exact, bilinear, area, bicubic, lanczos, nvidia_rtx_vsr
crop_positionCOMBOcenter5 options: center, top, bottom, left, right
pad_colorSTRING0, 0, 0Color to use for padding.
maskoptMASK
deviceoptCOMBO2 options: cpu, gpu

Outputs (5)

NameTypeDescription
IMAGEIMAGE
widthINT
heightINT
maskMASK
longest_edgeINT