Sprite Sheet Generator
Upload any number of icons or animation frames and pack them into a single sprite sheet image, arranged in a uniform grid sized to your largest image so nothing gets cropped or stretched. Download the packed PNG along with matching CSS classes or a JSON atlas describing where each image landed — everything runs locally in your browser, nothing is uploaded anywhere.
Drop icons or frames here or click to browse
PNG, JPG, WebP, or GIF — up to 200 images
Images (0)
Use ▲ / ▼ to reorder. The sheet fills left-to-right, top-to-bottom.
Only 200 images are supported at once — extra files were ignored.
JPG doesn't support transparency, so the background was switched to a solid color.
Preview
About Sprite Sheets and Why Developers Use Them
A sprite sheet (also called a texture atlas) is a single image file that packs together many smaller images — icons, UI elements, or animation frames — into one grid. Instead of a browser or game engine loading dozens or hundreds of individual image files, it loads one combined image and then displays just the rectangular slice it needs at any given moment. This matters for two very different reasons depending on what you're building. For websites, fewer separate image files means fewer HTTP requests, which speeds up page loads even with modern HTTP/2 multiplexing — a handful of icons combined into one sprite sheet is still typically faster and easier to cache than dozens of tiny files. For games and interactive animations, a sprite sheet lets you load one texture into memory and flip through frames by shifting which region of it is displayed, which is how classic 2D character walk-cycles, explosions, and UI animations are built.
This tool packs your uploaded images into a simple, uniform grid: every cell in the grid is sized to match your largest uploaded image, so smaller images are never cropped, stretched, or distorted to fit — they're simply placed in the top-left corner of their cell with a bit of extra space around them. This is a deliberate trade-off. A fully optimized bin-packing algorithm could produce a smaller output file by fitting irregularly-sized images together more tightly, but it also makes the math needed to look up each frame's position significantly more complex. A uniform grid keeps both the packing logic and the resulting coordinates simple and predictable, which is exactly what most icon sets and simple animation sequences need.
How to Use This Tool
Start by dragging your image files into the upload area, or click it to browse your computer — you can add as many as you like in one go, and use the "+ Add more" button afterward to bring in additional files. Each uploaded image appears in the list on the left, where you can reorder it with the ▲ / ▼ buttons or remove it with the × button; the sheet fills left-to-right, top-to-bottom in the order shown, so reordering the list directly changes where each image lands in the grid.
Next, adjust the packing settings. Padding adds empty space between cells, which is useful if your sprites will be rendered slightly larger than their exact pixel dimensions (padding helps prevent neighboring frames from bleeding into view at the edges). Columns can be left on Auto, which arranges your images into a roughly square grid automatically, or set manually if you want a specific number of columns — for example, a walk-cycle animation might read more naturally as a single row or a fixed number of columns per row. Background can be left Transparent (the default, ideal for icons that need to sit on top of other content) or set to a solid color if you'd rather have an opaque background — note that a transparent background requires the PNG output format, so switching to JPG will automatically switch the background to a solid color for you.
Once you're happy with the preview, click Download Sprite Sheet to save the packed image at full resolution — the on-screen preview is scaled down to fit your browser window, but the downloaded file always matches your source images' native pixel dimensions with no upscaling or downscaling. Alongside the image, use the Copy or Download buttons to grab the generated CSS or JSON output described below. If your source images vary a lot in size, it's worth trimming them to a consistent size first with the image cropper — since this tool sizes every cell to your largest image, a single oversized frame will make every other cell in the sheet carry that same amount of empty space. And if your icons started out as vector graphics (SVG), convert them to PNG first with the SVG to PNG converter, since this tool packs raster images rather than reading vector source files directly.
Using the CSS Output
The generated CSS gives you one shared .sprite base class that points at your downloaded sprite sheet image, plus one additional class per uploaded image containing just the background-position, width, and height needed to show that one frame. To use a sprite in your HTML, apply both the base class and the specific image's class to the same element:
<span class="sprite sprite-icon-name"></span>
Because the class name is derived from your original filename (lowercased, with anything that isn't a letter or number replaced by a hyphen), a file named icon-name.png becomes the class sprite-icon-name. Make sure the sprite sheet PNG is saved in the same folder your CSS file expects, or update the url() path in the .sprite rule to match wherever you host it.
Using the JSON Atlas
Most game engines and canvas-based rendering code don't use CSS at all — instead, they need to know the exact pixel rectangle to read out of a loaded texture. The JSON atlas gives you exactly that: an object keyed by each image's sanitized name, with an {x, y, width, height} rectangle describing where that image's actual pixels sit in the sheet (using the image's own real dimensions, not the padded cell size, since images of different sizes share the same cell width and height but occupy different amounts of it). You can load this JSON alongside the sprite sheet image in a canvas-based game, a WebGL renderer, or any custom drawing code, and use each entry's coordinates directly with a call like drawImage(sheet, x, y, width, height, ...) to render just that one frame.
Frequently Asked Questions
Is my image uploaded anywhere while I use this tool?
No. Every image you add is read directly in your browser using the File and Canvas APIs and drawn onto an on-page canvas element. Nothing is sent to a server — the packing, previewing, and final download all happen locally on your device.
Why are some cells bigger than they need to be?
This tool uses a uniform grid, where every cell is sized to match your largest uploaded image's width and height. That's what keeps smaller images from being cropped or stretched to fit — they're simply placed in the top-left corner of their cell, leaving empty space around them. If your images are wildly different sizes, consider cropping or resizing them to a more consistent size first for a tighter result.
Can I control exact packing positions myself?
Not in this version. Packing is fully automatic within a uniform grid — you can influence the layout indirectly by reordering images, changing the column count, or adjusting padding, but placing individual images at custom coordinates or using an optimized (non-uniform) bin-packing algorithm is outside the scope of this tool.
Does this work for game engines other than ones that read CSS?
Yes — that's exactly what the JSON atlas output is for. Most game engines and canvas-based renderers don't use CSS at all; they read a rectangle of pixel coordinates out of a loaded texture, which is precisely the format the JSON atlas provides for every image in your sheet.
Is there a limit on file count or size?
A soft cap of 200 images is enforced to keep your browser responsive while packing and previewing the sheet. You can still work with very large sheets beyond that, but rendering may be slower depending on your device, especially with very large source images.