Skip to content

Sprite Sheet Frame Size — Measure Cell, Margin and Spacing

Phaser, Godot, Unity and Defold all ask the same four questions before they cut a sheet: how wide one frame is, how tall, how far the first frame sits from the edge, and how many pixels lie between frames. The Sprite workspace measures those numbers from the pixels and shows them with a confidence, so you stop trying 32, then 48, then 64.

Drop a sprite sheet, numbered frames, a GIF / APNG or an .aseprite file
Runs in your browser. Files are not uploaded.
Studio Sprite workspace: a 48 px samurai sheet with the detected grid, 60 frames in 10 animations, before Apply
The real Studio with a CC0 asset (OpenGameArt).
Exports to
  • 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

What it does

  • Cell size, margin and spacing are measured from the pixels — transparent separator lines, the repeat pitch of the art, content crossing a cell edge — and each candidate grid carries a high, medium or low confidence with its reasons.
  • The best grid is drawn over the sheet as a preview; nothing is cut until Apply, and another candidate is one click away.
  • For a sheet no measurement can read, the custom grid takes cell width and height, offset X/Y (the margin) and gap X/Y (the spacing) — the same four numbers engines ask for.
  • Uneven sheets can be cut by islands instead of a grid; such a sheet has no single frame size, and an atlas export is the way into the engine.
  • Or skip the typing: Pack & Export writes atlas data with every frame's exact rectangle, which Godot 4.7.2, Unity 6 and Phaser 3.90 / 4.2 loaded in the verification runs.

How to do it

  1. Drop the sheet on the Sprite workspace.
  2. Read the grid decision in the Import panel: cell size, offset and gap, with the confidence.
  3. If it is off, choose an alternative or type the custom grid, then press Apply.
  4. Copy the numbers into your engine using the table below, or open Pack & Export and export for that engine.

Where the measured numbers go

EngineField namesMeasured value to enter
Phaser 3 / 4 · this.load.spritesheetframeWidth, frameHeight, margin, spacingCell width, cell height, offset (one value), gap (one value)
Godot 4 · Sprite2Dhframes, vframesColumns and rows — only when offset and gap are both 0
Godot 4 · SpriteFramesAn AtlasTexture region per frameWritten for you by the Godot 4 export (verified in 4.7.2)
Unity · Sprite Editor › Slice › Grid By Cell SizePixel Size, Offset, PaddingCell size, offset X/Y, gap X/Y
Defold · tile sourcetile_width, tile_height, tile_margin, tile_spacingCell size; the Studio's .tilesource re-lays the frames with margin and spacing 0 (built with bob.jar 1.13.1)

Field names are the engines' own. We did not run these hand-typed settings in the engines; the checked route is exporting an atlas from Pack & Export.

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.

TargetFilesCheck
Godot 4.tres SpriteFrames · .tscn AnimatedSprite2D · .png.importVerified 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 · AnimationClipVerified Unity 6000.5.3f1Batch mode: sprite rects, pivots, pixels, clip keys and durations checked.
Phaser 3 / 4atlas JSON (multiatlas) · .anims.jsonVerified Phaser 3.90 + 4.2Frames and animations drawn by both versions.
PixiJS 8spritesheet JSON · animations · anchor · meta.scaleVerified PixiJS 8.21Rotated and multi-page atlases included.
Aseprite JSONhash / array · frameTags · slicesVerified Phaser load.aseprite · PixiJS 8.21Tags keep their direction and repeat count.
.asepritelayers · tags · durations · slicesVerified Aseprite 1.3.18Opened and rendered by the Aseprite command line.
Spine / libGDX.atlasVerified spine-canvas 4.2Every region drawn by the Spine runtime, rotated and trimmed; libGDX itself was not run.
Starling / Sparrow XMLXML per pageVerified 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ÖVELua quads · nerulio_atlas.lua · main.luaVerified LÖVE 11.5Every frame drawn and every animation stepped through the shipped helper.
Defold.atlas · .tilesourceBuilt Defold bob.jar 1.13.1Built by Defold's command-line builder; the built texture's UVs were read back.
GameMakerspr_<name>_stripN.png · gamemaker.jsonUNVERIFIEDNot loaded in GameMaker (no headless GameMaker). The strips are cut the way its strip importer cuts them.
CSS sprites.css · preview .htmlVerified ChromiumEvery class drawn from the shipped stylesheet.
GIF / APNGone file per animationDecoded 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

  • 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.

Questions

My frames drift further off with every column. What is wrong?

The sheet has spacing between frames and the engine was told 0, or it got a frame width that includes the gap. Give the measured gap to Phaser as spacing or to Unity as Padding, and the measured cell size as the frame size.

Godot's hframes and vframes cut my sheet wrong.

hframes and vframes split the whole texture into equal parts, with no margin and no spacing, so they fit only a sheet that is exactly columns × frame width wide. For any other sheet, export a SpriteFrames resource from Pack & Export: its AtlasTexture regions carry each frame's exact pixel rectangle.

The margin is different on the left and on the top.

The Studio measures X and Y separately. Unity's Offset takes both. Phaser's load.spritesheet has a single margin and a single spacing value for both axes, so for such a sheet use the Phaser atlas export instead.

Can the measured size be wrong?

Yes, which is why it comes with a confidence and alternatives rather than a silent cut. On 16 real assets imported through the UI, the default choices gave the right frames 16 times out of 16.

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).