Image Untile (Seam Mask) (Yogurt Nodes)
Sew your tiles back together without the seam lines
- tiles
- masks
- tile_info
- image
Tiling is easy. The part that makes or breaks a crop-and-stitch workflow is the untile - because if you just paste tiles side by side, you get a quilt, with hard lines wherever two independently-generated tiles meet. Image Untile (Seam Mask) is the part that doesn't. It takes the tiles, masks, and tile_info from its sibling Image Tile (Seam Mask) and merges everything back into one image with feathered, overlap-aware seams.
It's an image node in the YogurtNodes pack (yogurt7771/ComfyUI-YogurtNodes), and it's the second half of the pack's answer to high-res generation: tile → regenerate each tile at native quality → untile with smooth transitions.
How it works
The mechanism is weighted accumulation. Each tile gets laid onto a blank canvas at the position recorded in tile_info, but instead of overwriting, the node accumulates pixels and a weight map. In the overlap regions, tiles blend according to a seam-feather weight that fades each tile's contribution toward its edges - so where two tiles overlap, the transition is a gradual crossfade, not a hard cut. The final image is accumulated_pixels / accumulated_weights, a proper normalized blend.
The masks aren't ignored either: they influence tile priority, so a tile that was actually regenerated (white = inpaint) contributes more strongly where it should, while reference regions (black) keep the original pixels stable. The comment in the source is worth quoting in spirit: the seam feather is always in effect, and the mask only increases a tile's priority. That means even if you feed masks that are off, you still get smooth seams.
Inputs that matter
tiles- the tile batch from Image Tile (Seam Mask).masks- the matching mask batch (white = inpaint, black = reference).tile_info- the dict from the tile node. This is the one you must not lose; it carries tile positions, the original canvas size, and the feather settings. Losing it is the #1 way to break this node.
Output: a single image, back at the original size.
Install
One clone, whole pack:
cd ComfyUI/custom_nodes
git clone https://github.com/yogurt7771/ComfyUI-YogurtNodes.git
cd ComfyUI-YogurtNodes
pip install -r requirements.txt
Or ComfyUI Manager → "YogurtNodes". Find it under Yogurt Nodes / Image. No models, no downloads.
Troubleshooting
- "Tiles must be square" / "tile_size mismatch." The node requires square tiles whose edge matches
tile_info.tile_size. If you resized the tiles between tile and untile (say, to speed up the inpaint), that's the error - resize back totile_sizebefore merging, or re-tile. - "Batch size not divisible by tile_count." The
tilesbatch has to be an exact multiple of the tile count fromtile_info. A dropped tile somewhere in your graph breaks the arithmetic. Check that no tile got filtered out between the two nodes. masksbatch mismatch. If your masks don't match the tiles batch, the node tries to broadcast a single mask - fine if you have one, an error if the counts disagree.- Single tile? If
tile_infosays one tile, it returns the tiles as-is. Good for testing.
The workflow to remember: Tile → inpaint/regenerate each tile (respecting the masks - white gets redrawn, black is context) → Untile with the same tile_info. Keep the tile/mask/untile trio bundled and the seams just disappear. It's the closest thing to a plug-and-play high-res pipeline in the pack.
Inputs (3)
| Name | Type | Default | Description |
|---|---|---|---|
| tiles | IMAGE | Tiled images batch. | |
| masks | MASK | Masks batch (white=inpaint, black=reference). | |
| tile_info | DICT | Tile info dict from Image Tile (Seam Mask). |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| image | IMAGE | — |