Make a sprite sheet from frames or a GIF without uploading the art
Sprite Tools packs PNG frames or a GIF into a sprite sheet in the browser. Preview the walk cycle, then download PNG plus TexturePacker or Phaser JSON.
5 min read
A sprite sheet is one PNG that holds every frame of a walk, idle, or attack cycle. The engine crops one cell per tick. That is cheaper than loading twenty separate files, and it is what Phaser, PixiJS, Unity, and Godot expect. The usual way to get that PNG is an upload packer: you send the frames to a site, it returns an atlas, and a copy of the character now sits on someone else’s disk. Game art is often unpublished. I do not send it to a packer cloud.
Sprite Tools on SW Images packs the sheet in the tab. Frames are decoded in memory. The PNG and the TexturePacker or Phaser JSON are built in the same tab. Download is a local file. There is no account. There is no sprite-upload API.
This is a packer, not a generator that draws a character for you. If you do not have frames yet, draw them in Aseprite or Piskel, or export them from the tool you already use. Then bring the files here.
When this packer is the right tool
Use it when you already have numbered PNGs, or one GIF, and you need a sheet the engine can slice. A walk cycle named walk_0.png through walk_7.png plus an idle named idle_0.png is the job I built the filename prefixes for. A looping GIF you were using in a mockup is the other job: drop the GIF, pack, preview at FPS, download.
I use a horizontal strip for a single walk cycle with even frame sizes. I use a uniform grid when Unity or Godot will import by cell size. I use packed atlas when frames are different sizes and the JSON will tell Phaser or PixiJS where each rect lives.
I do not use this page to invent a character. Sprite Tools does not run an image model. It lays out pixels you already have.
What “in the browser” means for this job
Client-side means the page sends the packer to your tab. Your browser decodes the PNG or GIF, trims transparent edges if you ask, and paints one atlas. JSON is a string built from the rectangle list. Download uses the browser download manager. We do not need your frames on a server to place them on a canvas.
You can test it. Load https://images.sw-commercial.com/sprite, go offline, drop a throwaway GIF, pack, download. If the PNG still appears, the art did not need our server. The first visit still loads the page HTML. That is not your sprites.
How I pack a walk cycle here
- Open https://images.sw-commercial.com/sprite.
- Drop the frames. Name them
walk_0.png,walk_1.png,idle_0.pngif you have more than one clip. A GIF has no prefixes, so it becomes one clip nameddefault. - Pick a layout. Horizontal strip for a cycle that will play left to right. Uniform grid when the engine wants a cell width and height. Packed atlas for mixed sizes.
- Keep padding at 2px unless the engine is bleeding neighbour pixels. Turn on trim if transparent margins make the character hop. Turn on power-of-two only if the engine or GPU path you use still wants 256, 512, 1024, or 2048 on a side.
- Pack. Play the clip at the FPS the game will use. If the feet slide, the frames are uneven or the trim cut too hard — fix the source, do not stretch the preview.
- Download the PNG plus TexturePacker JSON for Phaser or PixiJS, or the Phaser JSON array. Unity: Sprite Mode Multiple, Grid By Cell Size, using the cell size printed under the sheet. Godot 4: slice the atlas by the same cell.
You do not create an account. Free packing does not watermark the sheet.
GIF to sprite sheet
A GIF is already a stack of frames with a delay. The packer extracts those frames in the tab and treats them as one clip. I do this when a designer sent a GIF and the programmer needs an atlas. I do not do this when the GIF is a 400-frame film transfer — the free tier caps how many frames you can add, and a film is the wrong input anyway.
If the GIF is noisy or reversed, clean it in GIF Tools first. That page also stays on the device. Then pack the cleaned file here. Two jobs, two pages, still no upload.
Failure cases I hit while using it
Uneven frame sizes on a grid import. Unity and Godot slice by one cell. If frame 3 is 4 pixels taller than frame 0, the character hops. Export from Aseprite with a fixed canvas, or use packed atlas and JSON instead of a grid.
JPEG frames. JPEG smears transparent edges into grey. Pack PNG or WebP with a real alpha channel. If the only source is a JPEG on a white backdrop, cut the subject in Cutout and download a transparent PNG, then pack.
Too little padding. Some GPU filters sample a pixel into the next cell. Two pixels of padding is the default I leave on until I see bleed; then I raise it.
A GIF with a disposal method that expected the previous frame underneath. The extracted frames can look like holes. Re-export the GIF as full frames, or export PNG sequence from the editor that made it.
Power-of-two on a tiny cycle. Forcing 1024×1024 for eight 32×32 frames wastes VRAM. Leave it off unless the engine docs say you need it.
When not to use this page
Do not drop photographs of a person and expect a game character. Cutout can remove a backdrop. It cannot turn a selfie into pixel art.
Do not pack art you do not have the right to ship. Local packing does not change the licence on the frames.
Do not treat the preview FPS as a physics timestep. It is a playback hint. The engine still owns delta time.
Related jobs on the same image host
Cutout removes a backdrop before you pack. GIF Tools makes, compresses, or reverses a GIF when the input is still a GIF and not yet an atlas. Favicon, upscale, and restore live on SW Images for other picture jobs. This catalog only keeps how-tos whose destination returns HTTP 200. Sprite Tools on SW Images does.