Nodes/ComfyUI-ResizeToCanvasSize/Load Image To Canvas
ComfyUI Node

Load Image To Canvas

A mini canvas editor that lives inside your workflow

By Carasibana·Created 5 months ago·Updated 5 months ago· 3
Load Image To Canvas
    • IMAGE
    • MASK
    • ORIGINAL IMAGE
    image
    canvas_width512
    canvas_height512
    padding_fillblack
    custom_color_hex#000000
    noise_seed0
    lock_aspect_ratiotrue
    locked_ratio1.0000
    zoom_x1.00
    zoom_y1.00
    offset_x0.500
    offset_y0.500
    flip_horizontalfalse
    flip_verticalfalse
    invert_maskfalse
    custom_color_hex_input

    Sometimes you don't want to compute crop coordinates - you want to look at the image and drag it into place. Load Image To Canvas is the hands-on member of the ComfyUI-ResizeToCanvasSize pack: it loads an image from disk and lets you composite it onto a canvas interactively, with a live preview, drag-to-reposition, scroll-to-zoom, flip controls, and all six padding fills. Where the other two nodes in the pack are automatic pipeline stages, this one is deliberately manual. User interaction is the point.

    It's the node you reach for when you're prepping a base image - say a real photo you're about to inpaint or a starting frame for a composition - and you want it on a specific canvas, positioned by eye rather than by math. The README frames it as a "manual, intentional starting node," and that's exactly what it is.

    How it works

    The transform order is right there in the source: load → apply flips → apply zoom_x / zoom_y → place the image centre at offset × canvas → composite over the padding_fill → compute the mask. A few details worth knowing:

    • EXIF orientation is applied on load, so your phone photos stop coming in sideways. Small touch, very welcome.
    • The aspect-ratio lock stores locked_ratio = zoom_x / zoom_y. When locked, zoom_y is derived from zoom_x and that ratio, so the proportions you set while unlocked are preserved.
    • The file list comes from ComfyUI's input/ folder - the node scans it for PNG/JPG/WebP/BMP/GIF. The node's IS_CHANGED uses the file's mtime, so re-running the queue picks up a changed file on disk.

    The interactive bits (rotary zoom dials, Fit Width/Height buttons, the Swap W↔H button, drag and scroll) all just drive the ordinary numeric fields underneath - zoom_x, zoom_y, offset_x, offset_y, lock_aspect_ratio, canvas_width, canvas_height.

    The inputs and outputs that matter

    • image - a file picker limited to what's in your input/ folder (or upload straight from the node).
    • canvas_width / canvas_height - target canvas, 1–8192 px. The Swap button toggles between portrait and landscape in one click.
    • offset_x / offset_y - position; 0.5 is centred. Drag the preview and these update live.
    • zoom_x / zoom_y - zoom multipliers, 1.0 = 100%. Independent when the lock is off, which is how you distort on purpose.
    • padding_fill and custom_color_hex / noise_seed - same six options as the rest of the pack.

    Three outputs: IMAGE (RGBA), MASK, and ORIGINAL IMAGE - a raw passthrough of the loaded file with zero transforms, which is handy if you want the untouched version further downstream.

    The subtle part: the mask changes meaning

    The MASK output is context-aware, and this is where people get confused. When the image doesn't fully cover the canvas, the mask is canvas-space - white where the image sits, black in the padding. When the image fully covers or crops into the canvas, the mask switches to source-image-space - white marking which source pixels were sampled. So the mask isn't always canvas-sized, and its interpretation flips depending on coverage. invert_mask flips white/black in both cases. If you're feeding this into an inpainting setup, check which state you're in before you trust the mask.

    Install and gotchas

    Same as the pack: ComfyUI Manager search "ComfyUI-ResizeToCanvasSize", or git clone into custom_nodes/ and restart. No requirements.txt, no model downloads, just Pillow/numpy/torch that ComfyUI already ships.

    Two gotchas worth remembering: the image picker only sees files in input/ (put your file there or upload through the node), and the earlier versions had a stuck-drag bug at high zoom that's fixed in 1.1.1 - if you're on an old install and panning feels broken, update. It's a fiddly node, but when you need to place an image by eye, it beats rebuilding that geometry with math nodes every single time.

    Categoryimage/transform

    Inputs (16)

    NameTypeDefaultDescription
    imageCOMBO1 options: example.png
    canvas_widthINT5121–8192
    canvas_heightINT5121–8192
    padding_fillCOMBOblack6 options: black, white, gray_50, transparent, custom, noise
    custom_color_hexSTRING#000000
    noise_seedINT00–18446744073709550000
    lock_aspect_ratioBOOLEANtrue
    locked_ratioFLOAT1.00000.0001–10000
    zoom_xFLOAT1.000.01–100
    zoom_yFLOAT1.000.01–100
    offset_xFLOAT0.500-1–2
    offset_yFLOAT0.500-1–2
    flip_horizontalBOOLEANfalse
    flip_verticalBOOLEANfalse
    invert_maskBOOLEANfalse
    custom_color_hex_inputoptSTRING

    Outputs (3)

    NameTypeDescription
    IMAGEIMAGE
    MASKMASK
    ORIGINAL IMAGEIMAGE