Sprite Sheet Cutter — Split a Sheet into Frames
Drop a sheet and the Studio measures the cell size, margin and spacing from the pixels — or cuts irregular sprites by their transparent gaps — and shows the cut with a confidence before anything changes.
Cutting a sprite sheet needs four numbers per axis: the cell width and height, the margin before the first cell and the spacing between cells. Drop the PNG here and Nerulio measures them from the transparent gaps in the art, previews the cut with a confidence, and cuts only when you press Apply; sheets without a grid are cut along their transparent gaps instead. The frames stay in one project for tags, timing and engine export; one PNG file per frame comes from the classic Sprite Lab.

- Godot 4Verified· Godot 4.7.2
- Unity 6Verified· Unity 6000.5.3f1
- Phaser 3 / 4Verified· Phaser 3.90 + 4.2
- PixiJS 8Verified· PixiJS 8.21
- Aseprite JSONVerified· Phaser load.aseprite · PixiJS 8.21
- .asepriteVerified· Aseprite 1.3.18
- Spine / libGDXVerified· spine-canvas 4.2
- Starling / Sparrow XMLVerified· Phaser 4.2
- LÖVEVerified· LÖVE 11.5
- DefoldBuilt· Defold bob.jar 1.13.1
- GameMakerUNVERIFIED
- CSS spritesVerified· Chromium
- GIF / APNGDecoded· Pillow
Cell, margin and spacing: how a grid sheet is laid out
A grid sheet is a table of equal cells. Column n starts at margin + n × (cell width + spacing), so one wrong number makes the cut drift, clip the first row or split sprites. The file size alone cannot tell you the grid: a 256 × 256 sheet divides evenly by 8, 16, 32, 64 and 128, and only the pixels show which one the artist used.
The importer scores candidate grids on evidence it can show you: rows and columns that are fully transparent where the grid puts a gap, art that repeats at the cell pitch, content that never crosses a cell border, and content bounds that look alike in every cell. It tries margins up to 64 px and gaps up to a quarter of the cell (16 px at most), then lists the winner and its alternatives with high, medium or low confidence and the reasons.
Two kinds of sheet need a different cut. Sprites of mixed sizes packed without a grid are cut as islands: each group of touching opaque pixels becomes a frame, and small pieces such as sparks are attached to the nearest sprite when that is unambiguous. Sheets drawn on flat magenta or another solid colour have no transparency to read, so the key colour is found on the border first and made transparent; the original stays in the project for undo.
- Cell
- One frame's rectangle on the sheet: width × height in pixels.
- Margin (Offset X / Y)
- Blank pixels before the first cell, from the left and from the top edge.
- Spacing (Gap X / Y)
- Blank pixels between two neighbouring cells.
- Islands
- Frames cut along transparent gaps instead of a grid, for sheets without one.
Example: a 136 × 68 sheet with a 1 px margin and 2 px gaps
Four columns and two rows of 32 × 32 frames. Where each cell starts, and what goes wrong without the margin and gap:
x of column n = 1 + n × (32 + 2) → 1, 35, 69, 103
y of row r = 1 + r × (32 + 2) → 1, 35
width used = 1 + 4 × 32 + 3 × 2 = 135 → 1 px left over (right margin)
height used = 1 + 2 × 32 + 1 × 2 = 67 → 1 px left over (bottom margin)
Custom grid W 32 H 32 Offset 1 Gap 2 → "4 × 2 = 8 whole cells fit"
typed as 32 × 32, no offset, no gap: column n starts at n × 32 → 0, 32, 64, 96
error per column → 1, 3, 5, 7 px (grows by the gap)The Custom grid panel does this arithmetic live and reports the pixels left over on the right and bottom. When the numbers are wrong the error grows column by column; slicing that drifts or clips walks through each case.
What it does
- Grid suggestions with margin and spacing, ranked by how well each explains the gaps in the art.
- Islands mode for irregular sheets: small effect pieces stay attached to their sprite; pieces that fit nowhere are shown in red.
- Magenta or flat-colour backgrounds are keyed to transparency (the original is kept for undo).
- One animation per row, with timing, as a decision you can change in one click.
How to do it
- Drop the sheet on this page (or choose it).
- Check the preview: frame count, grid, key colour and animations, each with its confidence.
- Press Apply — one undo step — then fix any frame region by dragging it.
- Open Pack & Export and export for your engine.
Check the result
- Before Apply, compare the preview's frame count with the frames you can see; empty cells at the end of a half-filled row are skipped, not counted.
- After Apply, switch to Sheet view (`): every region outline should run through the gaps, never through the art. Drag any region that is still off.
- Play one row with Enter. A frame that jumps by a whole gap width means the spacing is wrong; a one-pixel bob is usually drawn that way (align the frames if not).
- In Islands mode look for pieces drawn in red: they belong to no frame and are left out unless you drag a region over them.
Troubleshooting
| Symptom | Likely cause | How to check | Fix |
|---|---|---|---|
| Each column is a little further off than the last | Spacing between cells that the grid ignores | In Sheet view the error grows by the same amount per column | Set Gap X (and Gap Y), or pick the listed alternative that has the gap |
| The whole sheet becomes one frame | An opaque background: magenta, black or another flat colour leaves no transparency between frames | The import panel shows no key-colour decision, or a rejected one | Choose the key-colour alternative in the import panel; the untouched original stays for undo |
| Sprites are cut in half, or two sprites share a frame | The cell is half or double the real size | The frame count is double or half of what you see | Pick the other cell size from the list or type it; use Islands for sprites of different sizes |
| Sparks or dust vanish or become tiny frames | Islands mode treats detached pixels as pieces; pieces far from every sprite stay unassigned | Red pieces on the canvas in the preview | Drag the frame region over them, or cut by a grid instead of islands |
Other ways to do it
| Option | When it is the better choice |
|---|---|
| The engine's own slicer: Godot's SpriteFrames panel (Add frames from a Sprite Sheet) or Unity's Sprite Editor (Slice: Grid By Cell Size, Grid By Cell Count, Automatic) | You already know the cell size and want the frames inside the project. Unity's slicer also takes Offset and Padding. See sprite sheets in Godot and sprite sheets in Unity. |
| The classic Sprite Lab | You need one PNG file per frame in a ZIP: sprite sheet to PNG frames. |
| The atlas data that came with the sheet | A packed atlas has no grid at all; open the PNG together with its JSON or XML in the atlas viewer. |
Engine exports and how each was checked
"Verified" means the exported files were loaded by the real engine or tool on real CC0 assets and the result was compared with the source. Anything that was not loaded is labelled as such.
| Target | Files | Check |
|---|---|---|
| Godot 4 | .tres SpriteFrames · .tscn AnimatedSprite2D · .png.import | Verified Godot 4.7.2Loaded by Godot; every animation frame drawn and compared with the source file. The scene uses Nearest filtering; rotation is never used. |
| Unity 6 | .unity.json · Editor/NerulioSpriteImporter.cs · AnimationClip | Verified Unity 6000.5.3f1Batch mode: sprite rects, pivots, pixels, clip keys and durations checked. |
| Phaser 3 / 4 | atlas JSON (multiatlas) · .anims.json | Verified Phaser 3.90 + 4.2Frames and animations drawn by both versions. |
| PixiJS 8 | spritesheet JSON · animations · anchor · meta.scale | Verified PixiJS 8.21Rotated and multi-page atlases included. |
| Aseprite JSON | hash / array · frameTags · slices | Verified Phaser load.aseprite · PixiJS 8.21Tags keep their direction and repeat count. |
| .aseprite | layers · tags · durations · slices | Verified Aseprite 1.3.18Opened and rendered by the Aseprite command line. |
| Spine / libGDX | .atlas | Verified spine-canvas 4.2Every region drawn by the Spine runtime, rotated and trimmed; libGDX itself was not run. |
| Starling / Sparrow XML | XML per page | Verified Phaser 4.2Phaser 3.90 draws trimmed XML frames wrongly (its own bug); the "Sparrow XML (Phaser 3)" preset turns trim off and passes in 3.90 and 4.2. |
| LÖVE | Lua quads · nerulio_atlas.lua · main.lua | Verified LÖVE 11.5Every frame drawn and every animation stepped through the shipped helper. |
| Defold | .atlas · .tilesource | Built Defold bob.jar 1.13.1Built by Defold's command-line builder; the built texture's UVs were read back. |
| GameMaker | spr_<name>_stripN.png · gamemaker.json | UNVERIFIEDNot loaded in GameMaker (no headless GameMaker). The strips are cut the way its strip importer cuts them. |
| CSS sprites | .css · preview .html | Verified ChromiumEvery class drawn from the shipped stylesheet. |
| GIF / APNG | one file per animation | Decoded PillowEvery frame and delay decoded again after export; APNG is exact. |
Evidence
GIF decoder: 408 of 408 frames identical to Pillow on 29 real GIFs; APNG 132 of 132 on 16 files. .aseprite: 231 corpus files imported, re-written and reopened in Aseprite 1.3.18 with the same tags, durations and pixels (231/231). Exports: 49 runs in the real engines on real CC0 assets, 47 pass — the 2 failures are Phaser 3.90's trimmed-XML bug, which the Phaser 3 preset avoids.
Limits
- Automatic detection searches margins up to 64 px and gaps up to 16 px; a wider layout needs the Custom grid.
- A trimmed or rotated atlas cannot be recovered from the PNG alone; its data file holds the rectangles.
- Separate PNG files per frame are not a Studio export yet.
- A grid or island guess is a preview with a confidence; nothing is cut until you press Apply, and every choice has one-click alternatives.
- .aseprite files whose layers do not compose exactly (e.g. group opacity) are imported flattened, and the Import panel says why.
- Rotated frames in an imported atlas stay rotated; their export is UNVERIFIED.
- Images up to 32,768 px per side (268 million pixels), subject to your browser's memory.
Versions and sources
With the default choices the importer cut 16 of 16 real assets correctly (plain and colour-keyed sheets, a 4096² effect sheet, atlas data, frame files, GIFs and .aseprite files; 2026-09-23). The engine slicers named above are described from the Unity 6 manual and the Godot 4.7 documentation.
Official documentation used
Classic tool
Separate PNG files per frame (ZIP), outline and de-fringe are still in the classic Sprite Lab.
Open the classic tool →Questions
What if the grid guess is wrong?
Pick one of the listed alternatives or type the cell size, margin and spacing. The preview updates before anything is cut.
Can I get each frame as a separate PNG file?
Not from the Studio yet. The classic Sprite Lab linked below still downloads a ZIP of frame PNGs.
Is it free, and do I need an account?
Everything on these pages is free and works without an account. There is no watermark and no export that is held back.
Are my sprites uploaded?
No. The Studio decodes, packs and exports in this browser tab. Projects are autosaved in the browser (IndexedDB) and can be saved as a .nerulio file.
Does it need Aseprite or an engine plugin installed?
No. .aseprite files are read and written in the browser, and each engine bundle carries what that engine needs (for Godot, the import settings and scene; for Unity and the Godot TileSet, a small editor script).