Parse Aseprite files with Node.js, no external dependencies.
To install for use:
You'll probably want to get the Buffer of the Aseprite file in whatever way you feel like. For the example, we'll just use fs.readFileSync()
. But you can get it from a network request, etc.
const Aseprite = require('ase-parser');
const fs = require('fs');
const buff = fs.readFileSync('./somefile.aseprite');
const aseFile = new Aseprite(buff, 'somefile.aseprite');
aseFile.parse();
console.log(aseFile.numFrames);
After parsing, you can get the data and do something like generate an image with the sharp
npm lib, which accepts raw pixel data and supports image composition.
Here is a more advanced example generating a png
image of the first frame using the sharp
lib.
const Aseprite = require('ase-parser');
const fs = require('fs');
const sharp = require('sharp');
async function makePNG() {
const buff = fs.readFileSync('./my_chocobo.aseprite');
const ase = new Aseprite(buff, 'my_chocobo.aseprite');
ase.parse();
// Create a blank png image buffer that's the same size as the Aseprite sprite (only make the promise because we'll use Promise.all a little later)
const bgPromise = sharp({create: {
width: ase.width,
height: ase.height,
channels: 4,
background: {r: 0, g: 0, b: 0, alpha: 0}
}}).png().toBuffer();
// Get the cels for the first frame
const cels = ase.frames[0].cels
// copy the array
.map(a => a)
.sort((a, b) => {
const orderA = a.layerIndex + a.zIndex;
const orderB = b.layerIndex + b.zIndex;
// sort by order, then by zIndex
return orderA - orderB || a.zIndex - b.zIndex;
})
// Create png image buffers per cel to create an image of the first frame (creating the Promises to be used)
const otherPromises = cels.map(cel => {
return sharp(cel.rawCelData, {raw: {width: cel.w, height: cel.h, channels: 4}}).png().toBuffer();
});
// Run the promises all at once to get the buffers for the base image and the cels to combine
const [ bg, ...others ] = await Promise.all([bgPromise, ...otherPromises]).catch(console.log);
// take the first image and add on the png buffers on top of it (the cels should be in order from bottom to top from the parse)
const finalBuff = await sharp(bg)
.composite(others.map((img, index) => ({
input: img,
top: cels[index].ypos,
left: cels[index].xpos
})))
.png()
.toBuffer();
// saves the file as a png with the buffer from sharp.composite
fs.writeFileSync(ase.name.replace('.aseprite', '.png'), finalBuff);
}
makePNG();
Parameters:
-
buffer
: Expects a Node.js Buffer of the Aseprite
file.
-
name
: Expects a string that's the name of the Aseprite
file, including the extension.
Returns:
Example:
const Aseprite = require('ase-parser');
const fs = require('fs');
const buff = fs.readFileSync('./somefile.aseprite');
const aseFile = new Aseprite(buff, 'somefile.aseprite');
Description:
Parses the Aseprite file and populates the Aseprite
class with the information from the file.
Parameters:
Returns:
Example:
const Aseprite = require('ase-parser');
const fs = require('fs');
const buff = fs.readFileSync('./somefile.aseprite');
const aseFile = new Aseprite(buff, 'somefile.aseprite');
aseFile.parse();
Field |
Type |
Description |
frames |
array of frame objects |
frames |
layers |
array of layer objects |
layers |
fileSize |
integer |
size of the file (in bytes) |
numFrames |
integer |
number of frames the Aseprite file has |
width |
integer |
width (in pixels) |
height |
integer |
height (in pixels) |
colorDepth |
integer |
color depth (in bits per pixel) |
paletteIndex |
integer |
position of the indexed color based on the palette |
numColors |
integer |
number of colors |
pixelRatio |
string |
width:height |
name |
string |
name of the file |
tags |
arry of tag objects |
tags |
colorProfile |
colorProfile object |
Color profile |
palette |
palette object |
Palette |
tilesets |
array of tileset objects |
Tileset |
slices |
array of slice objects |
Info on slices |
Field |
Type |
Description |
bytesInFrame |
integer |
size (in bytes) |
frameDuration |
integer |
duration (in ms) |
cels |
array of cel objects |
cels |
Field |
Type |
Description |
flags |
layer flags |
flags for the layer translated into a map |
type |
integer |
type |
layerChildLevel |
integer |
layer child level |
opacity |
integer |
opacity (0-255) |
tilesetIndex? |
integer |
the tileset id, if applicable |
name |
string |
name of layer |
Field |
Type |
Description |
from |
integer |
first frame index |
to |
integer |
last frame index |
animDirection |
string |
Forward , Reverse , Ping-pong or Ping-pong Reverse
|
repeat |
integer |
repeat animation N times |
color |
string |
hex color of the tag (no # included) |
name |
string |
name |
Field |
Type |
Description |
type |
string |
None , sRGB or ICC
|
flag |
integer |
fixed gamma flag |
fGamma |
integer |
fixed gamma |
icc? |
buffer |
ICC profile data |
Field |
Type |
Description |
paletteSize |
integer |
number of colors |
firstColor |
integer |
index of the first color |
lastColor |
integer |
index of the last color |
colors |
array of color objects |
colors |
index? |
integer |
position of the indexed color based on the palette |
Field |
Type |
Description |
id |
integer |
tileset id number |
tileCount |
integer |
number of tiles |
tileWidth |
integer |
pixel width of each tile |
tileHeight |
integer |
pixel height ofeach tile |
name |
string |
name |
externalFile? |
tileset external file object |
external file linkage info, if applicable |
rawTilesetData? |
Buffer |
raw pixel data for tiles, if applicable |
Field |
Type |
Description |
id |
integer |
id of the external file |
tilesetId |
integer |
id of the tileset in the external file |
Field |
Type |
Description |
layerIndex |
integer |
index of the layer associated |
xpos |
integer |
x position of the cel compared to the sprite |
ypos |
integer |
y position of the cel compared to the sprite |
opacity |
integer |
opacity (0-255) |
celType |
integer |
internally used |
zIndex |
integer |
show this cel N layers later/back |
w |
integer |
width (in pixels) |
h |
integer |
height (in pixels) |
tilemapMetadata? |
tilemap metadata object |
tilemap metadata, if applicable |
rawCelData |
Buffer |
raw cel pixel data |
Field |
Type |
Description |
bitsPerTile |
integer |
number of bits used to represent each tile (usually 32) |
bitmaskForTileId |
integer |
which bit(s) represent the tile ID |
bitmaskForXFlip |
integer |
which bit(s) indicate X-axis flip |
bitmaskForYFlip |
integer |
which bit(s) indicate Y-axis flip |
bitmaskFor90CWRotation |
integer |
which bit(s) indicate 90-degree clockwise rotation flip |
Field |
Type |
Description |
red |
integer |
red value (0-255) |
green |
integer |
green value (0-255) |
blue |
integer |
blue value (0-255) |
alpha |
integer |
alpha value (0-255) |
name |
string |
'none' or the actual color name if it has one |
Field |
Type |
Description |
flags |
integer |
Flags set |
keys |
array of SliceKey objects |
Array of keys and their values |
name |
string |
Name of the slice |
Field |
Type |
Description |
frameNumber |
integer |
Frame number that the slice is from |
x |
integer |
X position of the slice |
y |
integer |
Y position of the slice |
width |
integer |
Width of the slice |
height |
integer |
Height of the slice |
patch? |
patch object |
Patch info on the slice |
pivot? |
pivot object |
Pivot info on the slice |
Field |
Type |
Description |
x |
integer |
X postion of the patch |
y |
integer |
Y position of the patch |
width |
integer |
Width of the patch |
height |
integer |
Height of the patch |
Field |
Type |
Description |
x |
integer |
X position of the pivot |
y |
integer |
Y position of the pivot |
This object is a utility object that will have ALL fields present. If a field is "on" it will be true
, if the field is "off" it will be false
.
Field |
Description |
visible |
Whether or not the layer is visible |
editable |
Whether or not the layer is editable |
lockMovement |
Whether or not the layer is a background layer |
preferLinkedCels |
Whether or not the layer prefers linked cels |
collapsedGroup |
Whether or not the layer group should be displayed collapsed |
reference |
Whether or not the layer is a reference layer |
If you would like to read up on the Aseprite file spec: Spec