Grid Maker (Dynamic)
A contact sheet without the export detour
- img_0_0
- img_0_1
- img_0_2
- img_0_3
- img_0_4
- img_0_5
- img_0_6
- img_0_7
- img_0_8
- img_0_9
- img_1_0
- img_1_1
- img_1_2
- img_1_3
- img_1_4
- img_1_5
- img_1_6
- img_1_7
- img_1_8
- img_1_9
- img_2_0
- img_2_1
- img_2_2
- img_2_3
- img_2_4
- img_2_5
- img_2_6
- img_2_7
- img_2_8
- img_2_9
- img_3_0
- img_3_1
- img_3_2
- img_3_3
- img_3_4
- img_3_5
- img_3_6
- img_3_7
- img_3_8
- img_3_9
- img_4_0
- img_4_1
- img_4_2
- img_4_3
- img_4_4
- img_4_5
- img_4_6
- img_4_7
- img_4_8
- img_4_9
- img_5_0
- img_5_1
- img_5_2
- img_5_3
- img_5_4
- img_5_5
- img_5_6
- img_5_7
- img_5_8
- img_5_9
- img_6_0
- img_6_1
- img_6_2
- img_6_3
- img_6_4
- img_6_5
- img_6_6
- img_6_7
- img_6_8
- img_6_9
- img_7_0
- img_7_1
- img_7_2
- img_7_3
- img_7_4
- img_7_5
- img_7_6
- img_7_7
- img_7_8
- img_7_9
- img_8_0
- img_8_1
- img_8_2
- img_8_3
- img_8_4
- img_8_5
- img_8_6
- img_8_7
- img_8_8
- img_8_9
- img_9_0
- img_9_1
- img_9_2
- img_9_3
- img_9_4
- img_9_5
- img_9_6
- img_9_7
- img_9_8
- img_9_9
- grid_image
- cell_width
- cell_height
You've generated a batch of variants and now you want to see them all at once - side by side, same size, in a grid you can actually compare. The lazy way is saving everything and stitching in an external editor. Grid Maker (Dynamic) is the in-graph way: it takes up to 100 individual image inputs, arranges them into a clean rows×cols grid, and hands you a single composite image plus the cell dimensions.
The "Dynamic" in the name is the point. Instead of a fixed 2×2 or 3×3 layout, you tell it how many rows and columns you want (up to 10×10) and it fills the grid from a bank of optional image inputs named img_0_0, img_0_1, and so on. Set rows=3, cols=3 and it reads img_0_0 through img_2_2. Bump it to 4×4 and more of those inputs come into play. Same node, no rebuilding.
How it works
The node sizes each cell from the first image it receives - img_0_0 if it's connected, otherwise the first filled slot. Every other image is then fitted into that cell canvas: larger images get cropped to the cell, smaller ones sit in the top-left corner of a zero-filled canvas. Then it tiles them: images concatenate horizontally per row, rows stack vertically, and out comes one grid_image tensor plus cell_width and cell_height so downstream nodes know what they're dealing with.
The inputs that matter:
- rows and cols (INT, 1–10, default 2) - the grid layout. These decide which
img_r_cslots are read. - img_0_0 through img_9_9 (optional IMAGE) - the 100 candidate slots. Connect only the ones your current grid uses; the rest stay empty.
The outputs are grid_image (the composite), plus cell_width and cell_height (the size each tile was fitted to).
Installing it
Grid Maker (Dynamic) is part of ComfyUI-TinyBee, a small MIT-licensed utility pack with no model downloads. Via Manager:
- ComfyUI Manager → Custom Nodes Manager.
- Search "ComfyUI-TinyBee" and install.
- Restart ComfyUI.
Or clone:
cd ComfyUI/custom_nodes
git clone https://github.com/TinyBeeman/ComfyUI-TinyBee
Restart and it's under 🐝TinyBee/Images. No special dependencies - the pack's jsonata requirement only affects its JSON Parser node.
Gotchas
The big one: images are not resized to fit the cell. Fit means "copy the top-left region that fits and pad the rest" - so a 1024×1024 image next to a 512×512 one will be cropped to the smaller cell, not scaled down. If you're gridding images of different sizes, normalize them (resize) before they hit this node, or you'll get surprising crops. Also, all images in a grid must share the same channel count and dtype, which they will if they come from one pipeline. The output grid is a single image, so wire it into a preview or a Save Image node - and if you want to shuffle which images land in which cell, run your batch through Randomize Image Batch first and split it out.
Inputs (102)
| Name | Type | Default | Description |
|---|---|---|---|
| rows | INT | 21–10 | — |
| cols | INT | 21–10 | — |
| img_0_0opt | IMAGE | — | |
| img_0_1opt | IMAGE | — | |
| img_0_2opt | IMAGE | — | |
| img_0_3opt | IMAGE | — | |
| img_0_4opt | IMAGE | — | |
| img_0_5opt | IMAGE | — | |
| img_0_6opt | IMAGE | — | |
| img_0_7opt | IMAGE | — | |
| img_0_8opt | IMAGE | — | |
| img_0_9opt | IMAGE | — | |
| img_1_0opt | IMAGE | — | |
| img_1_1opt | IMAGE | — | |
| img_1_2opt | IMAGE | — | |
| img_1_3opt | IMAGE | — | |
| img_1_4opt | IMAGE | — | |
| img_1_5opt | IMAGE | — | |
| img_1_6opt | IMAGE | — | |
| img_1_7opt | IMAGE | — | |
| img_1_8opt | IMAGE | — | |
| img_1_9opt | IMAGE | — | |
| img_2_0opt | IMAGE | — | |
| img_2_1opt | IMAGE | — | |
| img_2_2opt | IMAGE | — | |
| img_2_3opt | IMAGE | — | |
| img_2_4opt | IMAGE | — | |
| img_2_5opt | IMAGE | — | |
| img_2_6opt | IMAGE | — | |
| img_2_7opt | IMAGE | — | |
| img_2_8opt | IMAGE | — | |
| img_2_9opt | IMAGE | — | |
| img_3_0opt | IMAGE | — | |
| img_3_1opt | IMAGE | — | |
| img_3_2opt | IMAGE | — | |
| img_3_3opt | IMAGE | — | |
| img_3_4opt | IMAGE | — | |
| img_3_5opt | IMAGE | — | |
| img_3_6opt | IMAGE | — | |
| img_3_7opt | IMAGE | — | |
| img_3_8opt | IMAGE | — | |
| img_3_9opt | IMAGE | — | |
| img_4_0opt | IMAGE | — | |
| img_4_1opt | IMAGE | — | |
| img_4_2opt | IMAGE | — | |
| img_4_3opt | IMAGE | — | |
| img_4_4opt | IMAGE | — | |
| img_4_5opt | IMAGE | — | |
| img_4_6opt | IMAGE | — | |
| img_4_7opt | IMAGE | — | |
| img_4_8opt | IMAGE | — | |
| img_4_9opt | IMAGE | — | |
| img_5_0opt | IMAGE | — | |
| img_5_1opt | IMAGE | — | |
| img_5_2opt | IMAGE | — | |
| img_5_3opt | IMAGE | — | |
| img_5_4opt | IMAGE | — | |
| img_5_5opt | IMAGE | — | |
| img_5_6opt | IMAGE | — | |
| img_5_7opt | IMAGE | — | |
| img_5_8opt | IMAGE | — | |
| img_5_9opt | IMAGE | — | |
| img_6_0opt | IMAGE | — | |
| img_6_1opt | IMAGE | — | |
| img_6_2opt | IMAGE | — | |
| img_6_3opt | IMAGE | — | |
| img_6_4opt | IMAGE | — | |
| img_6_5opt | IMAGE | — | |
| img_6_6opt | IMAGE | — | |
| img_6_7opt | IMAGE | — | |
| img_6_8opt | IMAGE | — | |
| img_6_9opt | IMAGE | — | |
| img_7_0opt | IMAGE | — | |
| img_7_1opt | IMAGE | — | |
| img_7_2opt | IMAGE | — | |
| img_7_3opt | IMAGE | — | |
| img_7_4opt | IMAGE | — | |
| img_7_5opt | IMAGE | — | |
| img_7_6opt | IMAGE | — | |
| img_7_7opt | IMAGE | — | |
| img_7_8opt | IMAGE | — | |
| img_7_9opt | IMAGE | — | |
| img_8_0opt | IMAGE | — | |
| img_8_1opt | IMAGE | — | |
| img_8_2opt | IMAGE | — | |
| img_8_3opt | IMAGE | — | |
| img_8_4opt | IMAGE | — | |
| img_8_5opt | IMAGE | — | |
| img_8_6opt | IMAGE | — | |
| img_8_7opt | IMAGE | — | |
| img_8_8opt | IMAGE | — | |
| img_8_9opt | IMAGE | — | |
| img_9_0opt | IMAGE | — | |
| img_9_1opt | IMAGE | — | |
| img_9_2opt | IMAGE | — | |
| img_9_3opt | IMAGE | — | |
| img_9_4opt | IMAGE | — | |
| img_9_5opt | IMAGE | — | |
| img_9_6opt | IMAGE | — | |
| img_9_7opt | IMAGE | — | |
| img_9_8opt | IMAGE | — | |
| img_9_9opt | IMAGE | — |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| grid_image | IMAGE | — |
| cell_width | INT | — |
| cell_height | INT | — |