D2 Grid Image
A contact sheet that waits for all its images first
- images
- count
- reset
- images
Image Concatenate and friends tile whatever images you hand them right now. D2 Grid Image is different in a way that matters: it collects images across multiple runs and only builds the grid once it has hit a trigger_count you set. So you can generate eight variations one by one - seeds, denoise, LoRA strength - and have the node hold onto each output, then assemble all of them into a single labeled contact sheet the moment the eighth arrives.
That accumulation behavior is the whole trick. Under the hood the pack stashes incoming images in a per-node image stocker keyed by the node's ID; each run appends, and when the count hits your trigger it flips them into a grid, resets its stock, and outputs the finished sheet. Before the trigger fires it returns an execution blocker - effectively a no-op that pauses downstream nodes. If you've ever tried to fake a batch comparison by hand-assembling images, this removes the fiddly part.
The inputs
images- incoming image (or batch) to accumulate.max_columns- images per row.grid_gap- spacing between cells, in pixels.swap_dimensions-truestacks vertically (max_columns becomes max rows).trigger_count- how many accumulated images before the grid builds. Default 1 (build immediately, no waiting).title_text- optional heading drawn across the top of the sheet;font_sizecontrols it (default 24).
It also shows a running count of accumulated images and has a reset button to throw away the stock and start over.
Output
images - the assembled grid as a single IMAGE (plus the title strip if you set one).
Installing it
ComfyUI Manager → search "D2-nodes-ComfyUI" → install, or:
cd ComfyUI/custom_nodes
git clone https://github.com/da2el-ai/D2-nodes-ComfyUI
Restart. No model downloads, deps are just piexif and charset-normalizer. Since v32.0.0 the pack needs ComfyUI's V3 schema; older builds should use a pre-32.0.0 version.
Where people get burned
The stock lives in process memory and is tied to the node ID. If you load a different workflow that happens to reuse the same node ID, or if ComfyUI restarts mid-batch, the accumulated images can vanish - and if you change trigger_count after images are already banked, the count check uses the current value. Also: for XY Plot runs the pack ships a dedicated D2 XY Grid Image that adds row/column labels; use that one there instead of this, or your grid cells won't know what they represent. For everything else - seed sweeps, style comparisons, "show me all four upscalers" - this is the node.
Inputs (9)
| Name | Type | Default | Description |
|---|---|---|---|
| images | IMAGE | — | |
| max_columns | INT | 3 | — |
| grid_gap | INT | 0 | — |
| swap_dimensions | BOOLEAN | false | — |
| trigger_count | INT | 1 | — |
| title_textopt | STRING | — | |
| font_sizeopt | INT | 24 | — |
| countopt | D2_SIMPLE_TEXT | — | |
| resetopt | D2_BUTTON | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| images | IMAGE | — |