Image Grid
Turn a pile of images into a tidy grid
- images
- grid_image
Reviewing a batch of generated images one at a time is a drag. "Image Grid" turns them into a single contact sheet - you feed it a stack of images, pick how many columns you want, and get one tidy grid image out the other end, all frames cropped to the same aspect ratio and resized to fit a resolution cap. It's the fastest way to eyeball a batch before you pick the winner.
What it is
NNImageGrid assembles multiple images into a grid layout. Per the README: "Creates a grid layout from multiple images," with automatic cropping to a target aspect ratio, configurable columns, and resolution limiting. It's the still-image cousin of the pack's NNVideoTimeline (which does the same thing for video frames with rows and columns).
How it works
The implementation is worth knowing because it makes decisions for you:
- It accepts a list of images (
is_input_listis on in the source), and flattens any batches inside it into individual frames - so a batch of 8 images, or 8 batches of 1, both work. - Every frame gets center-cropped to the target
aspect_ratio(default"1:1", and it accepts strings like"16:9"or"2:1"; if the string is unparseable it falls back to the first image's ratio). Crop is centered, so you keep the middle of each frame - which is exactly what you want when checking a batch of portraits. - Frames are laid out left-to-right,
columnsper row (rows are computed asceil(n / columns)), with a black background filling any partial last row. - The whole grid is scaled down if it exceeds
max_resolution(default 2048), and each cell is resized with bilinear interpolation.
Net effect: a clean, uniform grid where every cell is the same aspect ratio, no matter how ragged the inputs were.
The inputs
images- one or more images (a batch or a list of image tensors).columns- 1–99, default 4. Frames per row.aspect_ratio- a string like1:1,16:9,3:2; default1:1.max_resolution- 64–16384, default 2048. Cap on the grid's longest side.
Single grid_image output - one image, ready to preview or save.
When to reach for it
Any time the answer to "which of these is good?" is best served by seeing them all at once: batch generation review, comparing prompt variations, checking consistency across a character batch, or building a quick contact sheet to share. It's also a genuinely good debugging tool - before you wire a batch into something finicky, grid it and confirm every frame is actually present and sane.
Two honest limits. The aspect ratio cropping is lossy - if your input is 16:9 and you ask for a 1:1 grid, every frame gets its sides chopped to make it square, and that's the point (uniform cells) but you should expect it. And there's no per-image labeling or padding control - this is a plain contact sheet, not a layout designer; if you want captions or custom gutters, this isn't the node.
Installing
Part of bandifiu/ComfyUI-NN-custom-nodes:
cd ComfyUI/custom_nodes
git clone https://github.com/bandifiu/ComfyUI-NN-custom-nodes
Restart ComfyUI (or Manager → "NN-custom-nodes"). Deps: torch, numpy, pillow - no models. GPL-3.0, newer V3 backend API.
The practical gotcha is feeding it a list correctly - because the input is a list of images, some source nodes deliver a single batched tensor and others deliver an actual list; this node handles both, but if you wire it to something that produces a deeply nested list you may need to flatten upstream first. When in doubt, feed it one image batch and it'll flatten it for you.
Inputs (4)
| Name | Type | Default | Description |
|---|---|---|---|
| images | IMAGE | — | |
| columns | INT | 41–99 | — |
| aspect_ratio | STRING | 1:1 | — |
| max_resolution | INT | 204864–16384 | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| grid_image | IMAGE | — |