Pixel Art Outline and Drop Shadow — 1 px, One Step
A clean 1 px outline around a sprite, and a 1 px drop shadow under it, as single commands on the canvas. On the head-to-head sprite the result was identical to Aseprite's outline, pixel for pixel, and the shadow that Aseprite 1.3.18 needs about six manual steps for is one command here.

- .asepriteVerified· Aseprite 1.3.18
- Palette filesMeasured· read back
- Engine bundlesVerified· Godot 4.7.2 · Unity 6000.5
- Frame PNG · .nerulioPlain files
What it does
- Pixel › Outline draws a 1 px ring outside the opaque pixels in the foreground colour, touching them by their edges (4-connected), the same shape as Aseprite's default outline. Originals stay unchanged.
- Pixel › Drop shadow places the silhouette one pixel down and to the right in the background colour, behind the art. Aseprite 1.3.18 has no shadow command; there it takes duplicating a layer, filling, offsetting, reordering and flattening.
- With a selection active, both commands act only on the selected pixels grown by one pixel, so an outline can go around one character on a crowded sheet or one part of a sprite.
- Canvas size (Ctrl+Alt+C) adds the border room first, so an outline around art that touches the edge is not cut off. Each command is one step in History, undone as a whole.
- For many frames at once, the Cleanup panel can add the outline and the shadow while it converts an upscaled picture, and the result becomes a new sprite with its frames, durations and tags.
How to do it
- Drop the sprite or its frames on this page; the Pixel workspace opens on the first frame.
- Press Ctrl+Alt+C and give the canvas one extra pixel on each side if the art touches the border.
- Set the foreground colour to the outline colour and run Pixel › Outline; set the background colour to the shadow colour and run Pixel › Drop shadow.
- Step through the frames with , and . to repeat it where needed, then save .aseprite or export the frames from Pack & Export.
The same outline and shadow task, measured
Sumo Hulk sheet by Eris (OpenGameArt, CC0), 96×144. docs/STUDIO-PIXEL.md §6, T8.
| Step | Nerulio Pixel | Aseprite 1.3.18 |
|---|---|---|
| Make room | Canvas size +1 (one command) | Canvas size +1 |
| 1 px outline | Pixel › Outline: 1846 px added | Edit › FX › Outline: 1846 px added, identical |
| Drop shadow | Pixel › Drop shadow: 705 px, identical to the manual result | No command: duplicate, fill, offset 1,1, move below, flatten (about 6 steps) |
| Undo | Each command is one History step | Each action is its own undo step |
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.
| Target | Files | Check |
|---|---|---|
| .aseprite | layers · blend · opacity · locked · indexed palette · frames · tags | Verified Aseprite 1.3.18The real Aseprite command line reopened the file as INDEXED with 2 layers, Multiply at opacity 160 and the locked layer not editable; the frames are pixel-identical. |
| Palette files | .gpl · .pal · .hex · .ase · .act · .json | Measured read backEach format was written and read back identical; Aseprite's own .gpl, .pal, .hex and .act and a real Adobe .ase (16 colours) were read. |
| Engine bundles | Godot 4 · Unity 6 · Phaser 3/4 · PixiJS 8 … through Pack & Export | Verified Godot 4.7.2 · Unity 6000.5The sprite you drew is packed in Pack & Export; those engine files were loaded in each engine on real CC0 assets (47 of 49 runs pass; the 2 failures are a Phaser 3.90 bug the Phaser 3 preset avoids). |
| Frame PNG · .nerulio | PNG-8 with the palette when an indexed frame fits it · project file | Plain filesPlain files for any tool; no engine run is claimed for them. |
Evidence
Cleanup benchmark, 69 CC0 cases with a known 1× original: the exact size found for 81 % (±1 px: 90 %) and 74.0 % of pixels exact with the background kept; the best competitor found 30 % of sizes (perfectPixel) and the best exact-pixel score was 44.6 % (unfake.js). An Aseprite-made ×4 nearest upscale came back 100 % exact and a ×3.78 bilinear resize 99.7 %, both with the size found automatically. A 1 px outline and a drop shadow matched Aseprite pixel for pixel (1846 and 705 px). .aseprite files written here reopen in Aseprite 1.3.18 as indexed, with their layers, blend mode and lock.
Limits
- Not in the Pixel workspace (Aseprite has them): layer groups, linked cels, tilemap layers, reference layers, RotSprite and free rotation or scaling of a selection (only flips and 90°), gradient, spray, contour and text tools, custom brushes (square or round, 1–16 px), tiled drawing, Lua scripting and a command line.
- The symmetry axis is typed, not dragged on the canvas. On touch there is no right button, so the background colour needs the swap button or X.
- Cleanup: JPEG input comes back close (84 % of pixels within ΔE 0.02 with the background kept) but rarely exact (12 %); simulated generated art gets the exact size 20 % of the time (±1 px: 80 %); none of 7 real generated images was snapped automatically — you type the pixel size the panel suggests.
- Indexed conversion picks the nearest colour in Oklab, not Aseprite's RGB distance: 68 % of the test sprite's pixels got a different (perceptually closer) pick. The Lospec search is the only network request and asks first.
Questions
Is the outline drawn inside or outside the sprite?
Outside: it only fills transparent pixels next to opaque ones, so the art itself is not overwritten. In the head-to-head it added 1846 pixels, exactly the 4-connected outline Aseprite's Edit › FX › Outline produced on the same sprite.
Can I outline all frames of an animation at once?
The command works on the current frame. For a whole animation, run it on each frame, or use the Cleanup panel's outline and drop-shadow options, which apply to the chosen scope (this frame, the tag or all frames) and make a new sprite.
Does it work in an indexed sprite?
Yes. The outline and shadow use the foreground and background colours from the palette, and the cels are stored as indexed PNG again, so the sprite stays indexed.
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).