Nodes/va1/Pad Image by Aspect for Outpaint
ComfyUI Node

Pad Image by Aspect for Outpaint

Pad the canvas, draw the mask, let the dice decide — outpainting prep in one node

By vaishnav-vn·Created about a year ago·Updated 7 months ago· 0
Pad Image by Aspect for Outpaint
  • image
  • Image
  • Mask
  • Params
aspect_ratio16:9
placementcenter
scale_pct100
rotation0
bg_colorwhite
seed0
feathering40

The first thing to know: this node never generates a single pixel. It's the stage-hand of a masked outpainting workflow. It builds the canvas, parks your image on it, and hands back a feathered mask that tells the sampler "keep this, regenerate that." If you've built an outpaint graph by hand before - pad image, make empty latent at the right size, wire up a noise mask - this collapses those first steps into one node. And it does it with dice, if you want.

Why bother with masked outpainting at all in 2026? The KB's inpainting essay makes the honest case: instruction-edit models like Flux Klein and Qwen-Image-Edit took over most canvas extension, and for a one-off "what's behind this wall" it's hard to beat prompting a solid-colored padding away. But masked outpainting still wins when the original must survive byte-for-byte, or when you're extending in several passes and don't want drift compounding. This node is squarely in that camp: the interior of your image stays untouched, and only the padded area (plus a feathered border) gets regenerated.

How it works

The math is simple and worth knowing because it explains the surprises. The node takes your image, computes what the target aspect ratio should be, then rounds the canvas to a multiple of 8 - ComfyUI latent territory. Rotation, if any, is applied before the canvas is sized, so the rotated bounding box is what gets padded. Then scale_pct shrinks the original image inside that fixed canvas. Order matters: canvas first, shrink second.

The mask is the part that makes or breaks the output. Padded area is 1 (regenerate), the interior of your original image is 0 (keep), and within feathering pixels of the border the mask ramps from 0 to 1 with a quadratic falloff. That ramp is your seam prevention - it forces the sampler to blend across the outer few pixels of your original instead of leaving a hard cut line. This is exactly the "generous mask overlap" advice in the KB's outpainting section, baked into a slider.

The inputs that matter

You don't need to touch all eight. The ones that earn your attention:

  • aspect_ratio - presets from 16:9 down to 1:1, or random, which picks a fresh ratio every run.
  • placement - center, the four directions, or the full 3x3 grid. Choose random for uniform placement anywhere on the canvas.
  • feathering (default 40) - mask softness. Higher = smoother blend into the padded area.
  • bg_color - white, black, or grey. For the modern "pad with a color, prompt it away" trick you'd want an arbitrary color, and this node doesn't offer one - pick the closest of the three.

Then the outputs. Image is the padded tensor; Mask is what you wire into Set Latent Noise Mask or an inpaint conditioning node; Params is a string like AR: 16:9, Placement: center, Scale: 100%, Rotation: 0°. That string is more useful than it looks - when you run random, it's the only record of what the node actually decided.

Installing it

No model downloads, no requirements.txt, no Python deps beyond the torch ComfyUI already ships. Either ComfyUI Manager → Install from URL → paste https://github.com/vaishnav-vn/va1, or:

cd ComfyUI/custom_nodes
git clone https://github.com/vaishnav-vn/va1.git

Then restart ComfyUI. It registers as Pad Image by Aspect for Outpaint under the va1 category.

Where people get burned

  • The seed input is a lie. It's accepted but never read by the code - it only exists so you can bump it and force a re-execution, which re-rolls the random choices. The picks use Python's global random, so you cannot lock a seed and reproduce a layout. It's a re-roll button, not a seed. Use Params to log what happened.
  • 1:1 quietly caps the scale. On 1:1 the node drops the top scale options, so the image always ends up smaller than the canvas - no "extend to exactly 1:1" with zero padding. By design, but surprising the first time.
  • Huge feathering does nothing. The falloff only runs while 2 * feathering is smaller than the scaled image's height and width. Crank feathering past that on a small image and you silently get a hard edge.
  • Directional placement falls back to center. Ask for left on a portrait target and the node quietly centers it. The orientation just doesn't permit it.

For a batch pass, set aspect_ratio, placement, and scale_pct to random, keep the seed moving, and let Params tell you what each frame got. That's where this node earns its keep - one deterministic canvas helper that turns into a composition dice roller.

Categoryva1

Inputs (8)

NameTypeDefaultDescription
imageIMAGE
aspect_ratioCOMBO16:98 options: random, 16:9, 9:16, 3:2, 2:3, 4:5, +2
placementCOMBOcenter14 options: center, random, left, right, up, down, +8
scale_pctCOMBO1007 options: random, 50, 60, 70, 80, 90, +1
rotationCOMBO013 options: random, 0, 30, 60, 90, 120, +7
bg_colorCOMBOwhite3 options: white, black, grey
seedINT00–2147483647
featheringINT400–1024

Outputs (3)

NameTypeDescription
ImageIMAGE
MaskMASK
ParamsSTRING