Image Untile Batch
Stitching Tiles Without the Grid Showing
- tiles
- layout
- image
Everyone who has pushed a tiled upscale past 2x knows what a badly stitched tile grid looks like: faint rectangular bands where the blending was insufficient, or a set of soft smeared patches where it was too aggressive. Both are the same underlying problem - the tiles disagree with each other in the overlap, and the merge decides how visible that disagreement is. This node does the merge, with three different policies, using the layout the tiling step produced.
How it works
It takes the tiles batch and the layout from Image Tile Batch, validates the two against each other, and reconstructs the full image.
Validation is thorough, and deliberately so: the tile count must equal the layout's required count (source batch × spatial tiles), the tile tensor height, width and channel count must match the layout's, and the tiles must be floating point. A mismatch here is almost always an upstream change - a sampler that returned one image instead of the batch you sent - and being told that frees you from guessing.
Then the merge, by merge_mode:
- linear (default). Every tile gets a weight map: a linear ramp across each overlapping edge, 1.0 in the middle. Tiles are accumulated weighted, the weights are summed per pixel, and the result is divided by that sum - so the blend is normalized and needs no tuning. Accumulation runs in fp32 even if your tiles are fp16/bf16, then converts back. This is the mode that kills seams when the tiles broadly agree.
- hard_cut. Each pixel is owned by exactly one tile, decided by the midpoint of the overlap between neighbours. Sharp, cheap, no ghosting - and a visible line wherever the two tiles disagree, because there is no transition at all.
- limited_linear. A ramp only inside a band
blend_widthpixels wide around each seam; the rest of each tile is copied verbatim. This is the compromise you want most of the time: you keep the tile you generated, and you only pay for a narrow transition where the two meet.blend_widthdoes nothing in the other two modes.
Inputs and outputs
tiles, layout, merge_mode, blend_width in; one image out. Nothing about the output is a list or a per-item thing - you get a single batch matching the source batch size, ready for a save node or a VAE decode.
Two usage notes. blend_width of 0 in limited_linear degenerates to a hard cut, which is a useful way to A/B whether a seam you are seeing is a blending artifact or a genuine difference between the tiles' content. And if your source was a batch, everything above still applies: tiles of image 2 are accumulated into image 2 of the output, because the layout carries the batch size.
Install
Part of ComfyUI-Utility-Suite: ComfyUI Manager → search ComfyUI-Utility-Suite → install → restart. Or:
cd ComfyUI/custom_nodes
git clone https://github.com/tom-m-2020/ComfyUI-Utility-Suite
Restart ComfyUI. No models and no downloads; the pack's only declared dependency is opencv-python-headless, and this node does not even need that. It requires a recent ComfyUI because it is written against the V3 node API. Note that the pack's README is bare - the info panel is the only documentation, so read the field descriptions there if you are unsure which mode you want.
Traps
The layout is not optional and not re-derivable. It is the only thing that knows the batch size, the grid, the requested parameters and the per-tile valid rectangles. Pass the exact layout object from the tiling node; a layout from a different run, a different image size, or a different mode will fail validation or blend the wrong geometry.
Linear blending turns disagreement into mush. Average two tiles that invented different content in the overlap and you get the average of two inventions - a soft, low-detail band. That is not a bug in the merge, it is information the tiles did not agree on. The fix is upstream: condition each tile on the source region (ControlNet Tile or a reference latent) so the tiles are saying the same thing before you blend them. For stubborn edges, drop to limited_linear with a narrow blend_width, or hard_cut if a straight line is less objectionable than a smear.
The tile count error is the important one. "Tile count mismatch: layout requires 9, got 3" means your sampling branch collapsed a batch into a single image, usually because one node in it was not list-aware. Fix the branch, not the merge.
Cropped output sizes cause errors, not auto-fits. If a node in your tile branch returns tiles of a slightly different size - a resize, a crop, a model that pads to its own multiple - this node rejects them rather than letterboxing. Keep tile sizes intact through the branch.
Inputs (4)
| Name | Type | Default | Description |
|---|---|---|---|
| tiles | IMAGE | — | |
| layout | TILE_LAYOUT | — | |
| merge_mode | COMBO | linear | 3 options: linear, hard_cut, limited_linear |
| blend_width | INT | 320–32768 | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| image | IMAGE | — |