Nodes/ComfyUI-ReiyaNodes/Rei-ImageStitch
ComfyUI Node

Rei-ImageStitch

Stitch images in ComfyUI with Rei-ImageStitch

By FemReiyaDev·Created 8 months ago·Updated 7 months ago· 0
Rei-ImageStitch
  • image_1
  • image_2
  • image_3
  • image_4
  • image_5
  • image_6
  • image_7
  • image_8
  • image_9
  • image_10
  • IMAGE
num_images3
match_image_sizetrue

You know the workflow: you've generated four takes of the same prompt, or you want a clean before/after, or you're comparing two upscalers on the same crop. ComfyUI has no built-in "put these images side by side" node, so you either drag them out of the graph and glue them in an editor, or you bolt on a heavy grid/contact-sheet pack. Rei-ImageStitch is the third option: a single node from the small ComfyUI-ReiyaNodes pack that takes 2–10 images and lays them out horizontally.

The name is honest - that's the whole job. It stitches left-to-right only, one row, no rows-and-columns grid magic. If you want an actual contact sheet you should look elsewhere; if you want a comparison strip in seconds without leaving the graph, this is the one.

How it actually works

The Python side is refreshingly small. You feed in image_1 plus as many of image_2 through image_10 as you need, and the node does four things before the final torch.cat along the width:

  1. Batch matching. Images come in as tensors shaped B, H, W, C, where B is the batch size. If your inputs have different batch counts, it pads the smaller ones by repeating the last frame until every batch matches the largest.
  2. Size matching (only when match_image_size is on). Everything is resized to the height of the first image, preserving aspect ratio, using Lanczos resampling - the same non-generative, no-hallucination pixel path the upscaling docs call the honest cheap rung.
  3. Channel padding. If one image is RGB and another RGBA, the RGB one gets an alpha channel (padded with 1.0, so fully opaque) rather than a crash.
  4. Concatenation. Straight across the width: image_1 | image_2 | image_3 | ....

All of that happens on the same device as the input tensors, so there's no GPU/CPU copying drama.

The inputs that matter

You'll touch three things and ignore the rest:

  • num_images (INT, default 3, range 2–10) - how many slots to show. This one's a widget, and the frontend JS adds or removes input sockets to match, right on the graph. No digging through a config.
  • match_image_size (BOOLEAN, default true) - keep it on unless you've already normalized heights yourself.
  • image_1 (required) plus the optional image_2image_10 sockets. The node expects them filled contiguously: if you leave image_3 dangling but connect image_4, it stops collecting at the first gap. Set num_images to what you're actually feeding, not what you plan to.

The single output is one IMAGE tensor, ready to wire into a VAE Decode → Save/Preview chain or straight into any other image-processing node. It's not an output node, so it does nothing until you connect it to something that saves or displays.

Installing it

It's a two-file pack with zero Python dependencies beyond ComfyUI and PyTorch - no requirements.txt, no model downloads, nothing to fetch. The whole pack is one tiny node plus a UI-only variable node.

cd ComfyUI/custom_nodes
git clone https://github.com/FemReiyaDev/ComfyUI-ReiyaNodes.git

Restart ComfyUI. Or, if you use ComfyUI Manager, just search "ReiyaNodes" and install it there. Either way you're done in under a minute.

Where people get burned

A few real quirks from the code, so you don't discover them the slow way:

  • Change num_images and your wiring dies. When the JS removes an input socket, it also disconnects anything plugged into it. Crank the value up to add slots, or down to clean up, and be ready to re-plug your image sources.
  • match_image_size off is a footgun. With it disabled, the node does no resizing - so any height mismatch makes the width concatenation throw a tensor-size error. Turn it off only when every input is already the same height.
  • Fewer than two images is a silent passthrough. If only image_1 gets connected, the node just hands it back unstitched. That's by design, but it means a broken workflow won't necessarily error - you get one image instead of two.
  • It only speaks IMAGE. Masks and latents won't plug in; decode to pixels first.

Is this the most glamorous node in your graph? No. But for "I need this comparison strip before my coffee finishes brewing," it does exactly one thing and does it without a 200MB dependency. Sometimes the right tool is the boring one.

CategoryReiyaNodes/image

Inputs (12)

NameTypeDefaultDescription
num_imagesINT32–10
match_image_sizeBOOLEANtrue
image_1IMAGE
image_2optIMAGE
image_3optIMAGE
image_4optIMAGE
image_5optIMAGE
image_6optIMAGE
image_7optIMAGE
image_8optIMAGE
image_9optIMAGE
image_10optIMAGE

Outputs (1)

NameTypeDescription
IMAGEIMAGE