Fast Bottom Fit Overlay (Packed)
Auto-fit a foreground to the background width and pin it to the bottom
- background_image
- layer_image
- layer_mask
- image
- mask
- packed_image
Fast Bottom Fit Overlay solves the single most repetitive compositing chore in gift-animation and livestream layout work: you have a foreground layer - a character, an atmosphere plate, a gift effect - and you need it scaled to the background's width, aspect ratio preserved, sitting at the bottom of the frame. Doing that by hand per frame is exactly the kind of fiddly, repeatable work that should be one node. This is that node.
It's deliberately opinionated. It scales the layer to match the background width exactly, keeps the original aspect ratio, and bottom-aligns it. No alignment modes, no nine-slice anchors, no edge cases you get to configure - width-fit and bottom-pin, batch-friendly across whole frame sequences. That narrowness is the appeal: it's the one compositing operation you'll do a hundred times in a livestream overlay pipeline, compressed into a single node.
How it works
The mechanism is straightforward tensor math with a few thoughtful touches. The foreground is resized with bilinear interpolation to the background's width (height following the aspect ratio), then an alpha is built from your optional layer_mask (or full opacity if you don't pass one). Optionally, a top feather fade is multiplied into that alpha - a soft gradient from the top edge - which is the author's answer to a real problem: a character taller than the frame gets clipped, and a hard clip line looks terrible. The layer is then composited onto the bottom of the background.
The "Packed" in the display name refers to the third output, and it's the quirk worth understanding. Alongside the normal composite, the node can emit a packed image: the left half is the final mask shown as RGB, the right half is the masked foreground on black - at the resized layer's own aspect ratio, not padded to the background. It's a compact carrier format for downstream processing: if you need the isolated, pre-matted layer (say, to run an UnMult-style pass on it), it's already separated, no cropping needed.
The inputs that matter
background_image/layer_image- the canvas and the thing being fitted.opacity- 0–1 overall layer opacity.clip_if_too_tall- when the width-fit makes the layer taller than the background, this crops from the top. Turn it off and the node throws an error instead of silently cutting - useful when you'd rather know than wonder.enable_top_fade/top_fade_ratio- the soft top-edge fade described above;top_fade_ratiois how much of the layer height the fade spans (default 0.08, capped at 0.5).enable_packed_output- toggles that third packed output.layer_mask(optional) - a MASK input; batch 1 or matching the image batch.
The three outputs
image is the full composited result on the background. mask is the final alpha as a full-background-sized mask. packed_image is the packed mask+foreground pair. For most jobs you wire image into your Save/Preview and ignore the rest; the packed output earns its keep when you're building a reusable layer pipeline.
Install
It's part of lingziwyh/ComfyUI-GiftHelperSuite, a pure-PyTorch pack - no requirements.txt, no models, nothing extra to fetch. ComfyUI Manager: search ComfyUI-GiftHelperSuite, or:
cd ComfyUI/custom_nodes
git clone https://github.com/lingziwyh/ComfyUI-GiftHelperSuite
then restart ComfyUI. The usual pack gotchas apply: keep your input sequences at consistent resolution, restart after updates, and if you ever installed the old standalone ComfyUI_Unmult_AE pack, delete it so duplicate node names don't collide.
Inputs (12)
| Name | Type | Default | Description |
|---|---|---|---|
| background_image | IMAGE | — | |
| layer_image | IMAGE | — | |
| opacity | FLOAT | 1.000–1 | — |
| clip_if_too_tall | BOOLEAN | true | — |
| enable_top_fade | BOOLEAN | false | — |
| top_fade_ratio | FLOAT | 0.0800–0.5 | — |
| enable_packed_output | BOOLEAN | true | — |
| layer_maskopt | MASK | — | |
| packed_size_modeopt | COMBO | Fit Content (Dynamic Height) | 2 options: Fit Content (Dynamic Height), Fixed Canvas (1440x1280) |
| enable_rounded_rect_fadeopt | BOOLEAN | false | — |
| rounded_rect_fade_ratioopt | FLOAT | 0.1600–0.5 | Inward feather width; 0.16 is about 8% of the layer's full width and height. |
| rounded_corner_radiusopt | FLOAT | 0.300–1 | 0 is a rectangle; 1 becomes an ellipse fitted to all four layer edges. |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| image | IMAGE | — |
| mask | MASK | — |
| packed_image | IMAGE | — |