1 | # ase-parser
|
2 | Parse Aseprite files with Node.js, no external dependencies.
|
3 |
|
4 | ### Install
|
5 | To install for use:
|
6 | ```
|
7 | npm i ase-parse
|
8 | ```
|
9 |
|
10 | ## Instructions
|
11 | 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.
|
12 |
|
13 | ```js
|
14 | const Aseprite = require('ase-parser');
|
15 | const fs = require('fs');
|
16 |
|
17 | const buff = fs.readFileSync('./somefile.aseprite');
|
18 | const aseFile = new Aseprite(buff, 'somefile.aseprite');
|
19 |
|
20 | aseFile.parse();
|
21 | console.log(aseFile.numFrames);
|
22 | ```
|
23 |
|
24 | After parsing, you can get the data and do something like generate an image with the [`sharp`](https://www.npmjs.com/package/sharp) npm lib, which accepts raw pixel data and supports image composition.
|
25 |
|
26 | Here is a more advanced example generating a `png` image of the first frame using the [`sharp`](https://www.npmjs.com/package/sharp) lib.
|
27 |
|
28 | ```js
|
29 | const Aseprite = require('ase-parser');
|
30 | const fs = require('fs');
|
31 | const sharp = require('sharp');
|
32 |
|
33 | async function makePNG() {
|
34 | const buff = fs.readFileSync('./my_chocobo.aseprite');
|
35 | const ase = new Aseprite(buff, 'my_chocobo.aseprite');
|
36 |
|
37 | ase.parse();
|
38 | // 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)
|
39 | const bgPromise = sharp({create: {
|
40 | width: ase.width,
|
41 | height: ase.height,
|
42 | channels: 4,
|
43 | background: {r: 0, g: 0, b: 0, alpha: 0}
|
44 | }}).png().toBuffer();
|
45 |
|
46 | // Get the cels for the first frame
|
47 | const cels = ase.frames[0].cels
|
48 | // copy the array
|
49 | .map(a => a)
|
50 | .sort((a, b) => {
|
51 | const orderA = a.layerIndex + a.zIndex;
|
52 | const orderB = b.layerIndex + b.zIndex;
|
53 | // sort by order, then by zIndex
|
54 | return orderA - orderB || a.zIndex - b.zIndex;
|
55 | })
|
56 |
|
57 | // Create png image buffers per cel to create an image of the first frame (creating the Promises to be used)
|
58 | const otherPromises = cels.map(cel => {
|
59 | return sharp(cel.rawCelData, {raw: {width: cel.w, height: cel.h, channels: 4}}).png().toBuffer();
|
60 | });
|
61 |
|
62 | // Run the promises all at once to get the buffers for the base image and the cels to combine
|
63 | const [ bg, ...others ] = await Promise.all([bgPromise, ...otherPromises]).catch(console.log);
|
64 |
|
65 | // 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)
|
66 | const finalBuff = await sharp(bg)
|
67 | .composite(others.map((img, index) => ({
|
68 | input: img,
|
69 | top: cels[index].ypos,
|
70 | left: cels[index].xpos
|
71 | })))
|
72 | .png()
|
73 | .toBuffer();
|
74 | // saves the file as a png with the buffer from sharp.composite
|
75 | fs.writeFileSync(ase.name.replace('.aseprite', '.png'), finalBuff);
|
76 | }
|
77 |
|
78 | makePNG();
|
79 |
|
80 | ```
|
81 |
|
82 | ## Aseprite Functions
|
83 |
|
84 | ### `constructor`
|
85 | Parameters:
|
86 | * `buffer`: Expects a Node.js Buffer of the `Aseprite` file.
|
87 | * `name`: Expects a string that's the name of the `Aseprite` file, including the extension.
|
88 |
|
89 | Returns:
|
90 | * `Aseprite`: Returns [Aseprite](#aseprite-object).
|
91 |
|
92 | Example:
|
93 | ```js
|
94 | const Aseprite = require('ase-parser');
|
95 | const fs = require('fs');
|
96 |
|
97 | const buff = fs.readFileSync('./somefile.aseprite');
|
98 | const aseFile = new Aseprite(buff, 'somefile.aseprite');
|
99 | ```
|
100 |
|
101 | ### `parse`
|
102 | Description:
|
103 | Parses the Aseprite file and populates the `Aseprite` class with the information from the file.
|
104 |
|
105 | Parameters:
|
106 | * none
|
107 |
|
108 | Returns:
|
109 | * none
|
110 |
|
111 | Example:
|
112 | ```js
|
113 | const Aseprite = require('ase-parser');
|
114 | const fs = require('fs');
|
115 |
|
116 | const buff = fs.readFileSync('./somefile.aseprite');
|
117 | const aseFile = new Aseprite(buff, 'somefile.aseprite');
|
118 |
|
119 | aseFile.parse();
|
120 | ```
|
121 |
|
122 |
|
123 |
|
124 | ## Aseprite Object
|
125 | | Field | Type | Description |
|
126 | |--------------|------------------------|----------------------------------------|
|
127 | | frames | array of [frame](#frame-object) objects | frames |
|
128 | | layers | array of [layer](#layer-object) objects | layers |
|
129 | | fileSize | integer | size of the file (in bytes) |
|
130 | | numFrames | integer | number of frames the Aseprite file has |
|
131 | | width | integer | width (in pixels) |
|
132 | | height | integer | height (in pixels) |
|
133 | | colorDepth | integer | color depth (in bits per pixel) |
|
134 | | paletteIndex | integer | position of the indexed color based on the palette |
|
135 | | numColors | integer | number of colors |
|
136 | | pixelRatio | string | width:height |
|
137 | | name | string | name of the file |
|
138 | | tags | arry of [tag](#tag-object) objects | tags |
|
139 | | colorProfile | [colorProfile](#color-profile-object) object | Color profile |
|
140 | | palette | [palette](#palette-object) object | Palette |
|
141 | | tilesets | array of [tileset](#tileset-object) objects | Tileset |
|
142 | | slices | array of [slice](#slice-object) objects | Info on slices |
|
143 |
|
144 | ## Frame Object
|
145 | | Field | Type | Description |
|
146 | |---------------|-----------------------|------------------|
|
147 | | bytesInFrame | integer | size (in bytes) |
|
148 | | frameDuration | integer | duration (in ms) |
|
149 | | cels | array of [cel](#cel-object) objects | cels |
|
150 |
|
151 | ## Layer Object
|
152 | | Field | Type | Description |
|
153 | |-----------------|---------|-------------------------------|
|
154 | | flags | integer | flags for the layer |
|
155 | | type | integer | type |
|
156 | | layerChildLevel | integer | layer child level |
|
157 | | opacity | integer | opacity (0-255) |
|
158 | | tilesetIndex? | integer | the tileset id, if applicable |
|
159 | | name | string | name of layer |
|
160 |
|
161 |
|
162 | ## Tag Object
|
163 | | Field | Type | Description |
|
164 | |---------------|---------|----------------------------------------|
|
165 | | from | integer | first frame index |
|
166 | | to | integer | last frame index |
|
167 | | animDirection | string | `Forward`, `Reverse`, `Ping-pong` or `Ping-pong Reverse` |
|
168 | | repeat | integer | repeat animation N times |
|
169 | | color | string | hex color of the tag (no `#` included) |
|
170 | | name | string | name |
|
171 |
|
172 | ## Color Profile Object
|
173 | | Field | Type | Description |
|
174 | |--------|---------|-------------------------|
|
175 | | type | string | `None`, `sRGB` or `ICC` |
|
176 | | flag | integer | fixed gamma flag |
|
177 | | fGamma | integer | fixed gamma |
|
178 | | icc? | buffer | ICC profile data |
|
179 |
|
180 | ## Palette Object
|
181 | | Field | Type | Description |
|
182 | |-------------|------------------------|--------------------------|
|
183 | | paletteSize | integer | number of colors |
|
184 | | firstColor | integer | index of the first color |
|
185 | | lastColor | integer | index of the last color |
|
186 | | colors | array of [color](#color-object) objects | colors |
|
187 | | index? | integer | position of the indexed color based on the palette |
|
188 |
|
189 | ## Tileset Object
|
190 | | Field | Type | Description |
|
191 | |-----------------|------------------------|----------------------------|
|
192 | | id | integer | tileset id number |
|
193 | | tileCount | integer | number of tiles |
|
194 | | tileWidth | integer | pixel width of each tile |
|
195 | | tileHeight | integer | pixel height ofeach tile |
|
196 | | name | string | name |
|
197 | | externalFile? | [tileset external file](#tileset-external-file-object) object | external file linkage info, if applicable |
|
198 | | rawTilesetData? | Buffer | raw pixel data for tiles, if applicable |
|
199 |
|
200 | ## Tileset External File Object
|
201 | | Field | Type | Description |
|
202 | |-----------|---------|-------------------------------------------|
|
203 | | id | integer | id of the external file |
|
204 | | tilesetId | integer | id of the tileset in the external file |
|
205 |
|
206 | ## Cel Object
|
207 | | Field | Type | Description |
|
208 | |------------------|---------|----------------------------------------------|
|
209 | | layerIndex | integer | index of the layer associated |
|
210 | | xpos | integer | x position of the cel compared to the sprite |
|
211 | | ypos | integer | y position of the cel compared to the sprite |
|
212 | | opacity | integer | opacity (0-255) |
|
213 | | celType | integer | internally used |
|
214 | | zIndex | integer | show this cel N layers later/back |
|
215 | | w | integer | width (in pixels) |
|
216 | | h | integer | height (in pixels) |
|
217 | | tilemapMetadata? | [tilemap metadata](#tileset-external-file-object) object | tilemap metadata, if applicable |
|
218 | | rawCelData | Buffer | raw cel pixel data |
|
219 |
|
220 | ## Tilemap Metadata Object
|
221 | | Field | Type | Description |
|
222 | |------------------------|---------|---------------------------------------------------------|
|
223 | | bitsPerTile | integer | number of bits used to represent each tile (usually 32) |
|
224 | | bitmaskForTileId | integer | which bit(s) represent the tile ID |
|
225 | | bitmaskForXFlip | integer | which bit(s) indicate X-axis flip |
|
226 | | bitmaskForYFlip | integer | which bit(s) indicate Y-axis flip |
|
227 | | bitmaskFor90CWRotation | integer | which bit(s) indicate 90-degree clockwise rotation flip |
|
228 |
|
229 | ## Color Object
|
230 | | Field | Type | Description |
|
231 | |-------|---------|-----------------------------------------------|
|
232 | | red | integer | red value (0-255) |
|
233 | | green | integer | green value (0-255) |
|
234 | | blue | integer | blue value (0-255) |
|
235 | | alpha | integer | alpha value (0-255) |
|
236 | | name | string | 'none' or the actual color name if it has one |
|
237 |
|
238 | ## Slice Object
|
239 | | Field | Type | Description |
|
240 | |-------|---------|-----------------------|
|
241 | | flags | integer | Flags set |
|
242 | | keys | array of [SliceKey](#slicekey-object) objects | Array of keys and their values |
|
243 | | name | string | Name of the slice |
|
244 |
|
245 | ## SliceKey Object
|
246 | | Field | Type | Description |
|
247 | |-------|---------|-------------------|
|
248 | | frameNumber | integer | Frame number that the slice is from |
|
249 | | x | integer | X position of the slice |
|
250 | | y | integer | Y position of the slice |
|
251 | | width | integer | Width of the slice |
|
252 | | height | integer | Height of the slice |
|
253 | | patch? | [patch](#patch-object) object | Patch info on the slice |
|
254 | | pivot? | [pivot](#pivot-object) object | Pivot info on the slice |
|
255 |
|
256 | ## Patch Object
|
257 | | Field | Type | Description |
|
258 | |-------|---------|-------------------|
|
259 | | x | integer | X postion of the patch |
|
260 | | y | integer | Y position of the patch |
|
261 | | width | integer | Width of the patch |
|
262 | | height | integer | Height of the patch |
|
263 |
|
264 | ## Pivot Object
|
265 | | Field | Type | Description |
|
266 | |-------|---------|-----------------|
|
267 | | x | integer | X position of the pivot |
|
268 | | y | integer | Y position of the pivot |
|
269 |
|
270 | # Further Info
|
271 |
|
272 | If you would like to read up on the Aseprite file spec: [Spec](https://github.com/aseprite/aseprite/blob/master/docs/ase-file-specs.md) |
\ | No newline at end of file |