How to split a sprite sheet into frames
Split a sprite sheet by cell size, not by row and column count. Open the sprite sheet splitter, load the sheet, enter the width and height of one frame, add any offset at the edges and spacing between cells, and download the frames as numbered PNGs. Getting the cell size right is the whole job.
Why cell size, not rows and columns
A general image splitter asks how many pieces you want. That is the wrong question for a sprite sheet, because a sprite sheet is a grid of fixed-size cells and the row and column count is a consequence, not an input.
Get the cell size right and every frame is aligned. Get it wrong by one pixel and every frame after the first drifts, so by the end of a row you are seeing a sliver of the next character’s arm. The drift is cumulative, which is why the first frame usually looks fine and the last one looks broken.
Sprite sheets are also frequently not square-ish grids. A 1024 × 64 strip of sixteen 64 × 64 frames is a perfectly normal sheet. Asking “how many rows and columns” for that is more work than typing 64 and 64.
The four numbers
Every sprite sheet grid is defined by four things. Engines use different words for them, which is the main source of confusion.
Cell size. The width and height of a single frame, in pixels. Almost always the same for every frame in the sheet.
Offset. The gap between the top-left corner of the image and the top-left corner of the first cell. Some sheets have a border. Unity calls this Offset in its Sprite Editor; Phaser calls it margin and defines it as “the space around the edge of the frames”.
Spacing. The gap between neighbouring cells. Sheet authors add it so that texture filtering does not bleed one frame into the next. Unity has no separate field for this under Grid By Cell Size; Phaser calls it spacing, “the spacing between each frame in the image”.
Padding. An inset applied inside each cell, pulling the extracted rectangle in from the grid line. Unity’s Sprite Editor exposes this as Padding, which insets the sprite rectangles slightly from the grid. It solves the same bleeding problem from the other direction.
Watch the vocabulary clash: Unity’s “Padding” is an inward inset, while Phaser’s “margin” is the outer border that Unity calls “Offset”. If you copy numbers between an engine and a splitter without checking which is which, everything shifts.
How to find the cell size
If the sheet came with a data file, read that first. A .json next to a .png from TexturePacker, a .plist from a Cocos pipeline, or a .tres from Godot all contain the frame rectangles outright. That is the answer, no arithmetic needed.
Without one, work it out.
Divide. Count the frames across one row, then divide the image width by that number. A 512 px wide sheet with eight frames across gives 64 px cells. Do the same vertically. If either division leaves a remainder, there is an offset or spacing you have not accounted for.
Guess a power of two. Most hand-made sheets use 8, 16, 24, 32, 48, 64, or 96 px cells. Try the one nearest your estimate. Load it into the splitter, look at the preview grid, and adjust. This takes about fifteen seconds and beats counting pixels in an image editor.
Use the greatest common divisor. If a sheet is 384 × 256, the cell size divides both. 128 × 128 gives a 3 × 2 grid, 64 × 64 gives 6 × 4. Compare each against the visible frames and pick the one that matches.
Zoom in on a seam. Open the sheet at 800% and find the boundary between two frames. If there is a gap of transparent or coloured pixels between them, that gap is your spacing, and it must be subtracted before the division works out.
The preview grid on the splitter is the fastest check. Type a number, look at whether the lines land in the gaps, adjust. You will know within two attempts.
Trimming transparent pixels
Frames are usually drawn inside a cell larger than the artwork, so each exported PNG carries a border of transparent pixels. Whether that is a problem depends on what you do next.
Keep the transparency if you are feeding the frames back into an engine as a flipbook animation. Every frame having identical dimensions is what keeps the character’s feet on the ground between frames. Trim them individually and a character with a raised arm in frame three suddenly jumps, because the engine anchors to the trimmed rectangle instead of the cell.
Trim if you are re-packing the frames into a new atlas, or shipping them as individual assets where file size matters. A packer will re-trim anyway, and trimmed PNGs are considerably smaller. Trim also helps when you want to measure a sprite’s true bounding box.
The splitter’s trim option removes fully transparent rows and columns from each frame’s edges. It records nothing about how much it removed, so if you need the original offsets back, keep an untrimmed copy.
Naming frames for game engines
The naming scheme decides how much manual work comes next.
Unity. Unity’s own Sprite Editor slices a sheet with Grid By Cell Size and names the results after the sheet file with _0, _1, _2 appended, running left to right and top to bottom. Match that convention with your exported frames and Unity’s animation workflow behaves as expected. If you are exporting frames as separate PNGs rather than slicing inside Unity, walk_0.png through walk_7.png is the shape to aim for. Unity’s Grid By Cell Count option exists too, for when you know the rows and columns rather than the pixel size.
Godot. Godot prefers the sheet itself. In the SpriteFrames editor, “Add frames from sprite sheet” takes the PNG and asks for the number of horizontal and vertical frames, then lets you select which cells to include in the animation. If your sheet is a clean grid, you do not need to split it at all: hand Godot the whole sheet. Split it only if you need individual files for something else, and use zero-padded names (run_00.png) so file listings sort correctly.
Phaser. Phaser loads a sheet directly with load.spritesheet(), taking frameWidth, frameHeight, margin, and spacing in a config object, and names the frames as integers starting from 0. As with Godot, the sheet is the preferred input. Phaser draws a clear line between a sprite sheet, which has uniform cells addressed by number, and a texture atlas loaded with load.atlas(), which holds frames of any size and position addressed by name.
The general rule across all three: zero-pad your numbers, start at 0 or 1 and stay consistent, and use the animation name as the prefix. idle_00 through idle_03 beats sprite1 through sprite4 the moment you have more than one animation.
If the difference between a grid sheet and an atlas is not clear yet, what is a sprite sheet covers it.
FAQ
How do I know the cell size of a sprite sheet?
Divide the sheet’s width by the number of frames across one row, and its height by the number of rows. If the division is not exact, the sheet has an offset at the edges or spacing between cells. Powers of two like 16, 32, and 64 are the most common cell sizes in hand-made sheets.
What is the difference between spacing and padding?
Spacing is the gap between neighbouring cells in the sheet. Padding is an inset applied inside each cell, pulling the extracted rectangle away from the grid line. Both exist to stop texture filtering blending one frame into the next, and engines name them inconsistently, so check which one a field means.
Should I trim transparent pixels from sprite frames?
Keep them if the frames go straight back into an engine as an animation, because equal frame dimensions are what stop a character jumping between frames. Trim them if you are re-packing into an atlas or shipping individual assets, where the smaller files matter and the packer recalculates offsets anyway.
Can I split a sprite sheet without installing anything?
Yes. The sprite sheet splitter runs in your browser, takes the cell size, offset, and spacing, and gives you numbered PNG frames in a ZIP. Nothing is uploaded, which matters if the artwork is unreleased or licensed. PNG output keeps transparency intact.
Does splitting a sprite sheet lose transparency?
Not if you export PNG, which stores an alpha channel and is lossless. JPG has no alpha channel at all and will replace transparent areas with a solid colour, usually black or white. Always export sprite frames as PNG, and check the first frame before downloading the set.