Toolkitly

Sprite Sheet Cutter

Split a sprite sheet into individual PNG frames — by grid or by automatic frame detection — then download them one at a time or as a ZIP. Free, no sign-up, and every pixel stays in your browser.

Nothing is uploaded — the image is decoded and cut inside your browser.

How to use the sprite sheet cutter

Four steps from a packed sheet to a folder of numbered PNG frames.

  1. 1Load your sheetDrag a PNG, WebP, GIF or JPEG onto the drop area, pick a file, or paste an image straight from the clipboard. If the sheet came with a .json, drop that in at the same time.
  2. 2Set the gridThe grid is guessed on load. Correct the columns and rows if needed, or switch to fixed cell size when you know the frame is 32×32, and add offset and spacing for sheets with margins between cells.
  3. 3Or let it detect framesFor packed atlases with irregular frames, switch to auto-detect. It finds islands of non-transparent pixels and merges parts that sit close together, so a character and their weapon stay in one frame. With a JSON imported there is nothing to detect — the file already says where every frame is.
  4. 4ExportDeselect any frames you don't want by clicking them in the preview or the frame list, choose a file-name pattern and a manifest format, and download the selection as a ZIP. Pick Godot 4 (SpriteFrames) and you get a .tres instead — regions of the original sheet rather than loose files, so the sheet travels with it.

Supported formats

Input: PNG, WebP, GIF and JPEG — anything your browser can decode. PNG and WebP are the sensible choices for sprite work because they carry an alpha channel; a JPEG sheet has no transparency, so auto-detect and trimming will not find frame boundaries in it.

Output: one lossless PNG per frame, at the frame's exact pixel size, plus a manifest in whichever format you pick — TexturePacker JSON in either layout, a Godot 4 SpriteFrames .tres, or a plain x / y / w / h list. All of them describe positions in the original sheet.

Importing an Aseprite JSON

A sheet exported with its JSON does not need a grid worked out. The file already says where every frame is.

In Aseprite, File → Export Sprite Sheet, and on the Output tab tick JSON Data. Either layout works — Array or Hash. Drop the resulting PNG and .json in together and a From the imported JSON mode appears, cutting on the exact rectangles the file lists.

This matters most for the sheets the other modes struggle with. A grid needs every frame the same size; auto-detect has to guess whether a detached sword glint belongs to the frame beside it. A JSON has no guesswork in it at all, so frames of different sizes, irregular spacing and trimmed exports all stop being special cases.

Frame tags become an animation picker. If the sheet holds idle, walk and attack as tagged ranges, you can cut only the walk cycle instead of exporting 40 frames and deleting 32 of them. Ping-pong and reverse tags are read as well, and the direction is shown next to the tag.

Names come from the file. The pattern field gains {name}, which is what Aseprite called the frame with the document extension removed, and {tag} for the selected animation — so {tag}_{i0} gives you walk_00, walk_01.

TexturePacker's JSON is the same format without the durations and tags, so it imports too — including the manifest exported by the Sprite Sheet Generator. If the JSON and the PNG turn out to be from different exports, frames that fall off the edge of the sheet are counted and reported rather than silently cut as blanks.

When you need this

Importing an asset pack

Marketplace packs ship as one big sheet. Most engines animate more comfortably from separate frames — cut once, import the folder.

Rebuilding a lost source

You have the exported atlas but not the individual frames. Auto-detect recovers them without redrawing anything.

Editing a single frame

Pull one frame out, fix it in your pixel editor, and pack it back in — no need to open the whole sheet.

Checking frame alignment

The overlay shows exactly where each cut lands, which is the fastest way to spot a sheet whose spacing is off by a pixel.

Using the frames in your engine

What to do with the ZIP once it lands in your project.

Godot

Choose the Godot 4 (SpriteFrames) manifest and the .tres arrives built — drop it and the sheet into res:// and assign it to an AnimatedSprite2D. Set the import filter to Nearest so pixel art stays crisp.

Unity

Import the folder, set Texture Type to Sprite (2D and UI), Filter Mode to Point (no filter) and Compression to None, then drag the frames onto the scene to generate an animation clip.

Phaser

Load the frames individually with this.load.image(), or keep the original sheet and use frames.json with this.load.atlas().

Frequently asked questions

How do I split a sprite sheet into individual images?

Drop the sheet in, set the number of columns and rows (or switch to auto-detect), then download every frame as a ZIP. The tool guesses the grid for you on load, so most uniform sheets are already cut correctly before you touch a setting.

Are my files uploaded to a server?

No. The image is decoded and cut with the Canvas API inside your browser. Nothing leaves your machine, which also means the tool keeps working offline once the page has loaded.

What is the difference between grid mode and auto-detect?

Grid mode cuts on fixed cell boundaries — right for sheets exported by an animation tool, where every frame occupies the same cell. Auto-detect finds islands of non-transparent pixels instead, which is what you want for a packed atlas where frames have different sizes and irregular spacing.

My frames come out with extra padding. How do I remove it?

Turn on “Trim transparent pixels”. Each frame is then shrunk to the bounding box of its visible pixels. Keep it off when your engine relies on every frame sharing the same dimensions — trimming changes each frame's size and shifts the pivot.

Why are some cells exported as blank images?

A sheet padded out to a full grid usually ends with unused cells. “Skip empty frames” is on by default and drops them. If frames are being dropped that should not be, raise the alpha threshold — a sheet with a faint semi-transparent background reads as “not empty” at threshold 0.

What size should a sprite sheet be?

Keep the sheet dimensions to powers of two (512, 1024, 2048) where the target platform still cares about texture sizes, and keep every frame on a consistent cell size. Both make the sheet cheaper to upload to the GPU and far easier to cut back apart later.

Can I use the frames in Godot, Unity or Phaser?

Yes. The ZIP contains plain PNG files, which Godot's AnimatedSprite2D and Unity's Sprite Editor both take directly. For Godot there is a shortcut: pick the SpriteFrames manifest format and you get a .tres that already has every frame as a region of the original sheet, so there is nothing to assemble by hand. The JSON formats describe the same positions for Phaser and PixiJS.

Can I import an Aseprite JSON file?

Yes. Export the sheet from Aseprite with JSON Array or JSON Hash data, then drop the PNG and the .json in together. Every frame is cut exactly where the file says, so there is no grid to work out and frames of different sizes stop being a special case. Frame tags become an animation picker, so you can export just the walk cycle, and {name} in the file name pattern uses the names from the JSON. TexturePacker JSON works too — it is the same format without the durations and tags.

Related guides

Related tools