Image Resize By Megapixels (Swwan)
Target megapixels, not random pixel sizes
- image
- mask
- IMAGE
- width
- height
- mask
- longest_edge
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.
0means "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:
cropcuts,padfills withpad_color,resizedistorts, andpillarbox_blurblurs 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).
Inputs (11)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | — | |
| megapixels | FLOAT | 1.000–100 | Target megapixels (1.0 = 1 million pixels). Use 0 to skip resize and keep the original size. |
| aspect_ratio | COMBO | default | Target aspect ratio. 'default' keeps original ratio. |
| keep_proportion | COMBO | crop | How to handle aspect ratio change when not using 'default'. |
| divisible_by | COMBO | 16 | Width and height will be divisible by this value. |
| default_divisible | BOOLEAN | false | When enabled, ensures final output dimensions strictly follow divisible_by constraint. |
| upscale_method | COMBO | bilinear | 6 options: nearest-exact, bilinear, area, bicubic, lanczos, nvidia_rtx_vsr |
| crop_position | COMBO | center | 5 options: center, top, bottom, left, right |
| pad_color | STRING | 0, 0, 0 | Color to use for padding. |
| maskopt | MASK | — | |
| deviceopt | COMBO | 2 options: cpu, gpu |
Outputs (5)
| Name | Type | Description |
|---|---|---|
| IMAGE | IMAGE | — |
| width | INT | — |
| height | INT | — |
| mask | MASK | — |
| longest_edge | INT | — |