KoO Tile Splitter
Cut the Image Up So You Can Put It Back Together Cleanly
- image
- tiles
- metadata
Tiled diffusion exists for one reason: you want more pixels than your card will sample in a single pass. So you cut the picture into overlapping squares, run each through the model at the resolution it was trained for, and reassemble. Every part of that plan is decided at split time - tile size, overlap, how the ragged edge gets filled, how wide the blend will be.
KoOTileSplitter is the front half of the KoO tiling pair, sitting in KoO/Magnific beside KoO Tile Merger. It hands you a batch of tiles and a metadata string that the merger needs to rebuild the original: positions, padding, feather, everything. Lose that string and you're re-splitting.
What it is, and what it isn't
This is the "arbitrary output size on limited VRAM" branch of upscaling - the same idea as Ultimate SD Upscale and MultiDiffusion. Each tile is generated at a sane resolution, which is exactly what stops a 4K pass from melting down. What it doesn't do is think for you: no auto-scale, no ControlNet Tile conditioning, no sampling loop. It cuts and it records.
The blunt version - cut into squares, paste back - looks bad because it has no overlap and no weight ramp. Generous overlap plus enough steps per tile is still the whole fix, and has been since the A1111 days.
How it splits
Stride is tile_size - overlap, and positions step along by that stride from zero. The count per axis is ceil((length - tile_size) / stride) + 1, so the last tile is flush with the far edge instead of hanging off it. The padded canvas covers that final tile exactly, with padding added on the right and bottom only.
padding_mode decides how that edge is filled. reflect mirrors the image back on itself, so the model sees plausible continuation rather than a black wall. edge extends the last row and column. black fills with zeros - the model will cheerfully read a hard black border as a frame and paint inside it.
Each window is sliced from the padded canvas and stacked into one IMAGE batch, clamped to 0–1. The metadata JSON carries original and padded dimensions, tile size, overlap, stride, feather, per-tile x/y and crop coordinates, tile count, and a quiet confession: if the input IMAGE had a batch, only the first image was tiled.
Inputs and outputs
image is the picture to cut - one image, and only the first frame of a batch.
tile_size defaults to 512 and steps in 64s, 128 to 2048. Match your model - 512 for SD1.5-class, 1024 for SDXL-class. Twenty 1024 tiles is a real VRAM and time load.
overlap defaults to 96 and is the most consequential setting here. Too little and the cross-fade has nothing to work with; too much and you pay for the same pixels repeatedly. Keep it at least as wide as your feather, and roughly 2× is comfortable.
padding_mode is reflect, edge or black.
feather defaults to 48. It isn't applied here - it's a promise the merger keeps - and it gets silently clamped to tile_size // 2.
Outputs are tiles, an IMAGE batch in reading order, and metadata, a STRING. Send tiles through VAE Encode and your sampler into the merger's tiles input, and metadata straight into the merger's metadata input. Both halves have to arrive; the merger won't guess.
Install
Manager, searching koo-nodes-pack (publisher KoO.Ai; registry availability depends on moderation approval). Or by hand:
cd ComfyUI/custom_nodes
git clone https://github.com/kevintronchin-blip/koo-nodes-pack
Restart and refresh the browser. No models, nothing beyond the torch/numpy/Pillow/aiohttp ComfyUI already has, and no runtime pip installs.
Where it bites
"overlap must be smaller than tile_size." The node refuses rather than dividing by a zero stride, which is what you'd get with tile_size 128 and overlap 128. Drop one.
Reflected padding duplicates features. The far-right tile's fabricated region is a mirror of the pixels beside it. If the model latches onto that motif you get a repeated window frame or roof line nowhere near your prompt - and the merger can't remove it, because those pixels were generated. More overlap (so the edge tile holds less invented content) or edge padding helps more than fiddling with the blend.
Feather wider than overlap. Nothing crashes, since weights still normalize - you just get a cross-fade that doesn't really cross, because each ramp runs out before the next begins.
A big tile count is a batch, and batches are slow. 2048 at 512 with 96 overlap is 25 tiles; 4096 is 100. Fine for RAM, painful for the clock.
Inputs (5)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | — | |
| tile_size | INT | 512128–2048 | — |
| overlap | INT | 960–512 | — |
| padding_mode | COMBO | 3 options: reflect, edge, black | |
| feather | INT | 480–256 | — |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| tiles | IMAGE | — |
| metadata | STRING | — |