Skip to content

Carasibana/ComfyUI-ResizeToCanvasSize

Repository files navigation

ComfyUI-ResizeToCanvasSize

A ComfyUI custom node pack that resizes images to an exact target canvas size with full control over scaling, cropping, and placement.


Version License

Nodes

Node Description
Resize To Canvas Size Resize an image to a canvas using a 9-point anchor grid (flush edge/corner placement)
Resize To Canvas Size (COI) Resize with mask-driven Centre of Interest placement — a 7×7 target grid controls where the detected subject lands on the canvas
Load Image To Canvas Load an image from disk and interactively composite it onto a canvas — live preview, rotary zoom dials, drag-to-reposition, flip controls, and a context-aware mask

Resize To Canvas Size

Resize To Canvas Size node

Features

  • Photoshop-style anchor grid — 3×3 button grid at the top of the node; click any cell to set the anchor point. The selected cell shows a dot, directly adjacent cells show arrows pointing away from the anchor, and non-adjacent cells are blank
  • 5 scale methods — choose how the image is scaled before the final fit step
  • 2 fill methods — crop (trim overflow, optionally pad gaps) or stretch (distort to fill)
  • 6 padding fill options — black, white, 50% gray, transparent, custom colour (native colour picker), or random noise with a seed
  • Outputs RGBA image + padding mask — the padding_mask output is 1 where padding was added and 0 where original image pixels are, making it easy to pipe into an inpainting workflow

Inputs

Input Type Description
image IMAGE Source image (batch supported)
width INT Target canvas width in pixels
height INT Target canvas height in pixels
anchor Anchor Grid 3×3 click grid — sets the anchor point for crop/pad positioning
scale_method Dropdown How to scale the image before filling (see below)
fill_method Dropdown crop or stretch
padding_fill Dropdown How to fill any gaps (see below)
custom_color_hex Colour picker Only shown when padding_fill is custom
custom_color_hex_input STRING (optional connector) Only visible when padding_fill is custom. Connect any node that outputs a #RRGGBB / #RRGGBBAA string to override the colour picker. Invalid values fall back to the picker value.
noise_seed INT Seed for noise generation — only shown when padding_fill is noise

Custom colour fill with input connector

Outputs

Output Type Description
IMAGE IMAGE (RGBA) The resized image
padding_mask MASK 1.0 where padding was added, 0.0 where original image pixels are. All zeros when no padding occurred.

Basic resize workflow — noise-padded portrait crop result


Resize To Canvas Size (COI)

Manual mode Mask mode (mask_weighted_centre)
COI node — manual mode COI node — mask weighted centre mode

Places the image on the canvas by first computing a Centre of Interest (COI) from an optional mask, then using a 7×7 target grid to control exactly where that COI lands on the canvas.

Core concept

The anchor grid in this node always means: "place the COI at this point on the canvas."

Mode COI used for placement
manual Image centre (src_w/2, src_h/2)
mask_bbox_centre Centre of the bounding box of non-zero mask pixels
mask_weighted_centre Weighted centroid (centre of mass) — large contiguous masked areas dominate; stray pixels have negligible pull

If no mask is connected, or anchor_mode is manual, the image centre is used regardless of mode.

The 7×7 grid

A 7×7 lattice of 49 selectable target points is drawn over a 3×3 nonant background. The 7 positions per axis sit at multiples of 1/6 of the canvas dimension:

  • Even indices (0, 2, 4, 6) — nonant boundaries (0, W/3, 2W/3, W)
  • Odd indices (1, 3, 5) — nonant midpoints and centres (W/6, W/2, 5W/6)

Click any dot to set the canvas target for the COI. The default (3,3) places the COI at canvas centre. Boundary dots are displayed slightly larger; the selected dot is highlighted in blue.

Inputs

Input Type Description
image IMAGE Source image (batch supported)
width INT Target canvas width in pixels
height INT Target canvas height in pixels
anchor_grid 7×7 COI Grid Click grid — selects where on the canvas the Centre of Interest is placed
anchor_mode Dropdown manual, mask_bbox_centre, or mask_weighted_centre
scale_method Dropdown How to scale the image before filling
fill_method Dropdown crop or stretch
padding_fill Dropdown How to fill any gaps
custom_color_hex Colour picker Only shown when padding_fill is custom
custom_color_hex_input STRING (optional connector) Overrides the colour picker when connected
noise_seed INT Only shown when padding_fill is noise
mask MASK (optional) Mask used to compute the COI when anchor_mode is not manual. If the mask size differs from the image, it is resized automatically.

Outputs

Output Type Description
IMAGE IMAGE (RGBA) The resized image
padding_mask MASK 1.0 where padding was added, 0.0 where original image pixels are

Scale Methods

Method Behaviour
None – use original size No scaling — use the image at its original resolution
Fit to Canvas short edge Scale so the image's shortest edge matches the canvas's shortest edge
Fit to Canvas long edge Scale so the image's longest edge matches the canvas's longest edge
Fit to Canvas height Scale to match the canvas height exactly
Fit to Canvas width Scale to match the canvas width exactly

After scaling, the image may be larger than the canvas (overflow → crop) or smaller (gap → filled with padding_fill).


Padding Fill Options

Option Behaviour
black Fill gaps with solid black
white Fill gaps with solid white
gray_50 Fill gaps with 50% gray
transparent Fill gaps with transparency (alpha = 0)
custom Fill gaps with a colour chosen via the colour picker
noise Fill gaps with random per-pixel noise — a noise_seed field appears to control reproducibility

Fill Methods

Method Behaviour
crop Place the scaled image using the anchor position, trim any overflow, fill any gaps with the padding colour. Anchor determines which part of the image is kept.
stretch Distort/resize the scaled image to exactly fill the canvas. Anchor is not used.

Common Recipes

Crop to square, keep the centre:

  • scale_method: Fit to Canvas short edge · fill_method: crop · anchor: center

Letterbox / pillarbox (fit within canvas, pad the rest):

  • scale_method: Fit to Canvas long edge · fill_method: crop · padding_fill: black

Distort to fill (ignore aspect ratio):

  • scale_method: None – use original size · fill_method: stretch

Cookie-cutter crop at original resolution:

  • scale_method: None – use original size · fill_method: crop — canvas dimensions act as a crop window at the anchor position

Inpaint the padded region:

  • Connect padding_mask to a KSampler inpainting setup to fill padding areas with generated content

Face-centred portrait crop (COI node):

  • Feed a face detection mask (e.g. UltralyticsDetectorProviderBboxDetectorSEGSSAMDetectorCombined) into the mask input
  • Set anchor_mode: mask_bbox_centre · grid: (3,3) (canvas centre)
  • Set scale_method: Fit to Canvas width — the detected face will be centred on the canvas regardless of where it appears in the source image

Face-centred portrait crop — single subject, mask_bbox_centre

With multiple subjects, mask_weighted_centre finds the centre of gravity across all detected regions, automatically framing everyone together:

Two-subject crop — both faces detected, mask_weighted_centre centres between them



Load Image To Canvas

Load Image To Canvas — demo

Locked aspect ratio Unlocked aspect ratio
Load Image To Canvas — locked aspect ratio mode Load Image To Canvas — unlocked aspect ratio mode

Loads an image from disk and composites it onto a user-defined canvas with full interactive control over scaling, zoom, positioning, and padding. Designed as a manual, intentional starting node — user interaction is the point.

Load Image To Canvas — full workflow

Features

  • Live preview — canvas-aspect-ratio preview embedded in the node, updates reactively as every parameter changes. A resolution label (W × H) sits just below the preview and stays accurate when canvas dimensions change
  • Drag to reposition — click and drag anywhere on the preview to move the image; the offset_x / offset_y values update live
  • Scroll to zoom — scroll the mouse wheel over the preview or the dials; velocity-sensitive steps (rapid scroll = coarser, slow = finer). Shift+scroll for large jumps
  • Shift+drag crop box — draw an aspect-ratio-locked region on the preview; releasing snaps zoom and offset so that region fills the canvas exactly
  • Rotary zoom dials — canvas-based knobs for zoom. Drag diagonally to change value; click the numeric readout to type an exact value
  • Aspect ratio lock (🔒 Aspect Ratio Locked / 🔓 Aspect Ratio Unlocked) — single unified dial when locked; independent Width and Height dials when unlocked. Locking preserves the x:y ratio you set while unlocked
  • Fit Width / Fit Height buttons — one-shot snap buttons flanking the dial(s); scale the image to fill the chosen canvas axis and centre the offset on that axis
  • = (Equalize) button — appears between the Width and Height dials in unlocked mode; copies the Width zoom value to Height, restoring the image's natural (undistorted) aspect ratio
  • ⇄ Swap W↔H button — swaps canvas_width and canvas_height with each other; useful for quickly toggling between portrait and landscape canvas orientations
  • Flip controls — horizontal and vertical flip
  • 6 padding fill options — black, white, 50% gray, transparent, custom colour, or noise (same options as the rest of the pack)
  • Context-aware mask output — canvas-space (white = image, black = padding) when padding is present; source-image-space (white = sampled pixels) when fully covered
  • Original image passthroughORIGINAL IMAGE output carries the raw unmodified loaded image with no transforms applied

Inputs

Input Type Description
image File picker Source image loaded from ComfyUI's input/ folder
canvas_width INT Target canvas width in pixels
canvas_height INT Target canvas height in pixels
padding_fill Dropdown How to fill any uncovered canvas area
custom_color_hex Colour picker Only shown when padding_fill is custom
custom_color_hex_input STRING (optional connector) Overrides the picker when connected
noise_seed INT Only shown when padding_fill is noise
lock_aspect_ratio BOOLEAN Controlled via the lock toggle button in the Zoom section
zoom_x FLOAT Horizontal zoom multiplier (1.0 = 100%) — set via dial or readout
zoom_y FLOAT Vertical zoom multiplier — independent when unlocked
offset_x FLOAT Horizontal position (0.5 = centred) — set via drag or manual input
offset_y FLOAT Vertical position (0.5 = centred)
flip_horizontal BOOLEAN Mirror left/right
flip_vertical BOOLEAN Mirror top/bottom
invert_mask BOOLEAN Flip white/black on the mask output

Outputs

Output Type Description
IMAGE IMAGE (RGBA) Composited canvas result
MASK MASK Context-aware mask — canvas-space when padding present; source-image-space when no padding
ORIGINAL IMAGE IMAGE (RGBA) Raw unmodified loaded image, no transforms applied

Mask detail

State Mask space Mask content
Image has padding Canvas space (canvas W × H) White = where image sits, black = padding
No padding (fully covered/cropped) Source image space (original W × H) White = which source pixels were sampled

invert_mask flips this in all cases.

Transform order

  1. Load image
  2. Apply flip_horizontal / flip_vertical
  3. Apply zoom_x / zoom_y
  4. Apply offset_x / offset_y (image centre placed at offset × canvas)
  5. Composite onto canvas with padding_fill
  6. Compute mask

Installation

Clone this repository into your ComfyUI custom_nodes folder:

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

Then restart ComfyUI.

No additional Python packages are required beyond those already included with ComfyUI (Pillow, NumPy, PyTorch).


File Structure

ComfyUI-ResizeToCanvasSize/
├── __init__.py               # Registers nodes and web directory
├── nodes.py                  # Python node logic
├── js/
│   └── anchor_widget.js      # Custom anchor grid and COI grid UI widgets
└── examples/
    └── ResizeToCanvasSize_Example_Workflow.json
                              # Example workflow: basic resize (top) + face-COI resize (bottom)

About

A ComfyUI custom node pack that resizes images to an exact target canvas size with full control over scaling, cropping, and placement.

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors