🔧 Advanced Tile Merger
Stitch tiled upscales back together without the grid lines
- tile_config
- processed_tiles_image
- processed_tiles_latent
- merged_image
- merged_latent
Tiling is easy. The hard part of a tiled upscale is putting the pieces back together so nobody can tell where the cuts were. That's the whole job of this node, and it's the reason a tiled 4K image either looks like one continuous picture or like a jigsaw puzzle someone left in the rain.
CustomTileMerger is the second half of the ComfyUI-Advanced-Tile-Processing pair: its sibling CustomTileSplitter cuts a big image or latent into overlapping tiles and hands this node a TILE_CONFIG describing every tile's position. You sample the tiles however you like - batch, loop, ControlNet Tile pass - then feed the processed tiles back here and get one clean merged image (or latent) out. It's the ComfyUI-native replacement for the seam-fixing stage that Ultimate SD Upscale runs silently in A1111.
How it works
The merger reads the TILE_CONFIG, unpacks your processed tiles into per-position slots, and then does the stitching in a few stages. First it compares each tile against its neighbors in the overlap region and computes a seam line: the default optimal mode runs a dynamic-programming minimum-energy path that ducks around high-detail areas, while middle just takes the overlap's centerline. That seam becomes a mask, and blend_strength controls how hard it's feathered - a Gaussian blur on the mask, so the transition fades instead of snapping. If you enable histogram_matching, it does a quick Reinhard-style per-channel mean/std color transfer on each tile against its left neighbor first, which kills the "each tile slightly different color" problem that makes upscales look blocky. There's also multi_band fusion - a Laplacian pyramid that blends high and low frequencies separately - for high-contrast content where a simple feather leaves ghosting.
One honest note from reading the source: in the shipped version, linear and gaussian run through the same code path. Both feather the seam mask with a Gaussian filter; the real quality levers are overlap (set on the splitter), multi_band, and histogram_matching. So don't sweat picking between them.
For latent input there's a separate, simpler path: each tile just takes the center slice of the overlap and pastes it on the canvas with no blending. The README is upfront that latent merging can show mild color differences after VAE decode, and the standing advice is to do the final merge in image space.
The inputs that matter
tile_config- the contract from the splitter. Required, and yes, it must actually be connected.processed_tiles_image/processed_tiles_latent- the tiles you sampled. This is where the wiring gotcha lives: the merger consumes a list of tiles, one per position. If you ran a KSampler over the splitter's batch output, split the batch back into a list first, or the merge comes out wrong.blend_strength- 0.25 default. Crank it when seams still ghost; 0 gives a hard cut.seam_search_radius- 0 means the optimal seam can wander anywhere. If it's carving through something important, raise this to pin it near the centerline.
Outputs are merged_image (IMAGE) and merged_latent (LATENT) - wire whichever matches what you processed, and feed the image through VAE Decode if you sampled latent space.
Installing it
Same pack as the splitter, one install gets both nodes:
cd ComfyUI/custom_nodes
git clone https://github.com/QL-boy/ComfyUI-Advanced-Tile-Processing
# restart ComfyUI
Or ComfyUI Manager → search "ComfyUI-Advanced-Tile-Processing". Requires ComfyUI 0.4.0+, Python 3.10+, PyTorch 2.0+; the only real extra dependency is scipy (used for the feathering blur). No models, no keys.
When it bites
The README's FAQ is unusually honest, and worth trusting: faint edge marks after merging usually mean overlap too small and denoise too high - if each tile is being redrawn heavily, no seam fix can save the seams. Multi-band fusion being glacial is expected (it builds 5-level pyramids); drop to gaussian for speed. And if your merge spits out multiple images, you've fed it a list it couldn't collapse - re-check that you're on this node, that tile_config is connected, and that nothing downstream is re-expanding the list.
Inputs (8)
| Name | Type | Default | Description |
|---|---|---|---|
| tile_config | TILE_CONFIG | — | |
| blend_mode | COMBO | gaussian | 4 options: linear, gaussian, multi_band, none |
| blend_strength | FLOAT | 0.250–1 | — |
| seam_mode | COMBO | optimal | 2 options: optimal, middle |
| histogram_matching | BOOLEAN | false | — |
| seam_search_radius | INT | 00–100 | — |
| processed_tiles_imageopt | IMAGE | — | |
| processed_tiles_latentopt | LATENT | — |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| merged_image | IMAGE | — |
| merged_latent | LATENT | — |