What This Tool Does
Drop a sheet with sprites scattered anywhere on it. Each sprite is traced on its own, the set is put into reading order, every one of them is seated in a single uniform box, and the result downloads as a packed PNG, with a matching atlas JSON that names it a click away. It is the same studio the splitter uses, opened on the sheet export instead of the ZIP.
How Scattered Sprites Are Found
Detection works on the sheet's opacity, one byte per pixel, and grows a region outward from every content pixel it has not already claimed. Neighbours are counted in all eight directions, so two pixels that touch only at a corner belong to the same sprite — counting only the four orthogonal neighbours would split a single diagonal stroke of pixel art into a row of separate boxes.
Three numbers govern the result. The first decides what tracing is allowed to see in the first place; the other two are filters over what it found, and they run in this order:
| Control | What it does | Starts at |
|---|---|---|
| Alpha threshold | Opacity at which a pixel counts as content | 1 |
| Minimum area | Drops a box whose width times height is below this | 4 |
| Merge gap | Rejoins boxes closer than this on both axes at once | 2 |
The area filter runs before the merge pass on purpose. A stray speck that was going to be discarded anyway must not first drag a neighbouring sprite's box outward on its way to being dropped.
Which slicer a sheet opens in is decided the same way every time. A lattice measured from the sheet's own gutters wins outright. Failing that, more than one traced sprite whose widths or heights differ by more than 10 percent of the largest means the sprites are separate objects and each is kept on its own. Failing that too, the grid slicer stays in force with numbers you type. The status line states which happened and why, and one button switches.
Sheets With No Transparency
A JPEG has no alpha channel, so what looks like empty space around the sprites is made of real opaque pixels — and both detectors would see one enormous blob covering the whole image. The tool therefore reads the colour that dominates the sheet's outer border, keys it out before tracing runs, and says so. The starting tolerance is 16: a pixel within 16 units of the key colour in RGB counts as background, which is wide enough for the ringing that JPEG compression leaves around a hard magenta edge and narrow enough to leave a saturated sprite colour alone. Both the colour and the tolerance are editable, and the tolerance runs up to 128.
Reading Order, Not Raster Order
Tracing emits sprites in the order their first pixel is met, scanning the sheet top to bottom. That is not the order a person reads a sprite sheet in. A short sprite whose top edge happens to sit above its taller neighbour's would come out first under a plain sort by vertical position, even though the two plainly sit in the same row.
So sprites are grouped into horizontal bands instead. A sprite joins the current band when its vertical span overlaps the band's by at least half of whichever of the two spans is shorter, and the band's span grows as sprites join it — which is what lets one band follow a row of sprites that drifts gradually down the sheet. Only then is each band sorted left to right.
One Box For Every Sprite
Every sprite is seated in the same box, which is what makes the packed sheet a grid a game engine can index. Automatic sizing takes the largest selected sprite on each axis independently — a wide sprite and a tall one together give a box big enough for both — adds the padding on both sides, and rounds up to the next even number, or to the next power of two if you ask for that instead. Manual sizing takes a typed width and height, or one of the presets: 32, 64, 128, 256 and 512.
Padding insets all four sides of the box, and the anchor decides where the sprite sits in whatever room is left. The default is the bottom centre, because feet stay planted: anchoring a taller jump frame at the centre would push the character's feet upward relative to the shorter frames beside it, and the whole character would appear to slide up and down as the animation plays. All nine anchors are one click away.
A sprite too big for the box is reported rather than silently resized. The default names the frames that do not fit in a red badge, spelling out the first six and counting the rest, and then places each of them at its full size anyway — from a negative offset inside its own cell, which on the packed sheet means the sprite runs under its neighbour or off the edge. That is the deliberate half of "warn": nothing is resized behind your back, and the badge names exactly which frames to do something about. Raising the box size, deselecting the frame, or switching to scale-down all resolve it; scale-down shrinks those sprites by the same factor on both axes so their proportions survive. Every placement the tool computes is a whole number of pixels, so the rectangle drawn into the PNG and the rectangle written into the JSON are the same rectangle — including when that rectangle sits outside its own cell.
The Packed Sheet And Its Atlas
The sheet lays the boxes out as a nearly square grid by default, or as a single horizontal strip, or across a column count you choose. A margin is applied to all four edges of the sheet; spacing is applied only between neighbouring cells, never past the last one.
The atlas ships as TexturePacker JSON, in the hash flavour keyed by file name or the array flavour with a file name inside each entry. Each entry states where the sprite's pixels sit on the packed sheet, where those same pixels sit inside their own declared box, how big that box is, and whether the sprite was trimmed or offset within it — the last three are how an engine restores a sprite's original placement after trimming, and getting them wrong shows up far away, inside your game. The metadata names the exact PNG the sheet export writes, so the pair always describes itself.
"Download sheet, atlas and GIF" wraps all three into one ZIP under a shared name. The ZIP of individual frames is still there too, two tabs to the left, and on this page it starts with every frame seated in the shared box — so its PNGs all come out at the box size, each sprite sitting exactly where it sits in the corresponding cell of the packed sheet. A switch on that tab gives one PNG at each frame's own size as sliced instead — that setting takes the frame rect itself, so with trimming on it still ships the full untrimmed slice.