Nodes/ComfyUI-ResizeToCanvasSize/Resize To Canvas Size
ComfyUI Node

Resize To Canvas Size

Hit an exact canvas without doing the crop math in your head

By Carasibana·Created 6 months ago·Updated 5 months ago· 3
Resize To Canvas Size
  • image
  • IMAGE
  • padding_mask
width512
height512
anchorcenter
scale_methodFit to Canvas short edge
fill_methodcrop
padding_fillblack
custom_color_hex#000000
noise_seed0
custom_color_hex_input

You know the drill: your checkpoint wants exactly 1024×1024, but your source render is 832×1216, and suddenly you're mentally computing aspect ratios and wondering whether to crop, pad, or just let the thing distort. ComfyUI's built-in resizers either scale by a factor or force a target size and pray. Resize To Canvas Size is the one-node answer: it takes any image, gets it onto an exact target canvas, and lets you decide precisely which part of the image survives.

The selling point is the Photoshop-style 3×3 anchor grid at the top of the node. Click a cell and you're telling the node "keep this corner/edge of the image, crop or pad everything on the other side." Clicking top_left pins the image's top-left to the canvas corner; center keeps the middle and crops both edges evenly. It's a small thing, but it replaces a whole chain of crop/paste geometry nodes.

How it works

Under the hood it's three steps, all in the node's nodes.py:

  1. Scale - pick one of five scale_methods. "Fit to Canvas short edge" scales so the image's shortest edge matches the canvas's shortest edge (the one you want for a centered crop); "Fit to Canvas long edge" scales so the longest edge fits (the one you want for letterboxing); "Fit to Canvas height/width" match one axis exactly; "None" leaves the image at original resolution, so the canvas acts as a crop window.
  2. Fill - with fill_method: crop, the scaled image is pasted at the anchor position, overflow is trimmed, and any gaps get filled with your padding_fill. With stretch, it just distorts to fill the canvas and ignores the anchor entirely. Stretch is rarely the answer - if the aspect mismatch is severe it looks like a funhouse mirror.
  3. Mask - the padding_mask output is 1.0 where padding was added and 0.0 where original pixels landed. All zeros when nothing got padded.

The inputs that matter

  • width / height - target canvas in pixels (1–8192). These are the only numbers you should ever have to care about.
  • anchor - the 9-value grid (top_left, center, … ). The node's custom widget turns this into clickable cells.
  • scale_method and fill_method - the two choices above that decide whether you crop or letterbox.
  • padding_fill - black, white, gray_50, transparent, custom, or noise. custom reveals custom_color_hex (native colour picker) plus the optional custom_color_hex_input STRING connector, which overrides the picker with any #RRGGBB / #RRGGBBAA string - handy if another node is computing the colour for you. Invalid values silently fall back to the picker. noise reveals noise_seed and fills gaps with reproducible random noise.

Outputs: IMAGE (always RGBA) and padding_mask.

Install

ComfyUI Manager: search "ComfyUI-ResizeToCanvasSize". Or the manual route:

cd ComfyUI/custom_nodes
git clone https://github.com/Carasibana/ComfyUI-ResizeToCanvasSize.git

Then restart ComfyUI. That's it - there's no requirements.txt and no model download; it runs on the Pillow/numpy/torch ComfyUI already ships. Refreshingly rare.

Where people get burned

  • The padding mask is 1 = padding. If you're used to masks where white = the subject, this is backwards - but it's backwards on purpose. Wire padding_mask into an inpainting setup and white is exactly the region you want regenerated, so you get fill-in-the-blanks for free instead of having to invert anything.
  • Output is always RGBA. If a downstream node chokes on four channels, throw in a Convert Image node.
  • The custom hex input must be #RRGGBB or #RRGGBBAA. Anything else is ignored, not an error.

Recipes that actually work

  • Square crop, keep centre: Fit to Canvas short edge + crop + center.
  • Letterbox/pillarbox: Fit to Canvas long edge + crop + black.
  • Cookie-cutter crop at original res: None + crop - the canvas dims are your crop window, the anchor picks what survives.

It's a simple node with a thankless job, but it does that job exactly. If you chain it into a KSampler with padding_mask as your inpaint region, you've got a repeatable "fit my content to the canvas, regenerate the gaps" pipeline that needs zero hand-computed coordinates.

Categoryimage/transform

Inputs (10)

NameTypeDefaultDescription
imageIMAGE
widthINT5121–8192
heightINT5121–8192
anchorCOMBOcenter9 options: top_left, top_center, top_right, middle_left, center, middle_right, +3
scale_methodCOMBOFit to Canvas short edge5 options: None – use original size, Fit to Canvas short edge, Fit to Canvas long edge, Fit to Canvas height, Fit to Canvas width
fill_methodCOMBOcrop2 options: crop, stretch
padding_fillCOMBOblack6 options: black, white, gray_50, transparent, custom, noise
custom_color_hexSTRING#000000
noise_seedINT00–18446744073709550000
custom_color_hex_inputoptSTRING

Outputs (2)

NameTypeDescription
IMAGEIMAGE
padding_maskMASK