1 unstable release
0.3.9 | May 27, 2024 |
---|
#2194 in Parser implementations
Used in mabel
5MB
4K
SLoC
Utilities for loading Aseprite files. This library directly reads the binary Aseprite files (file format specification) and does not require you to export files to JSON. This should make it fast enough to load your assets when the game boots up. You can also use it to build your own asset pipelines.
Note that this library can be rather slow when compiled without optimizations.
We recommend that you override the optimization settings for this dependency
in dev mode by adding the following to your Cargo.toml
:
[profile.dev.package.asefile]
opt-level = 2 # or 3
This is not necessary if you already have a wildcard override. See Cargo profile overrides for more info.
Basic Usage
Load file
The easiest way is to use AsepriteFile::read_file to load a file.
use asefile::AsepriteFile;
let ase = AsepriteFile::read_file(&path).unwrap();
println!("Size: {}x{}", ase.width(), ase.height());
println!("Frames: {}", ase.num_frames());
println!("Layers: {}", ase.num_layers());
Save frame as image
Aseprite files consist of multiple layers. Usually you just want the final
image. You can do this by using Frame::image. This will return an
image::RgbaImage
from the image library.
let image = ase.frame(0).image();
let output_path = output_dir.join("example.png");
image.save(&output_path).unwrap();
This blends together all visible layers the same way Aseprite would.
Layers
You can access a [Layer] by name or by ID.
let layer = ase.layer(0);
println!("Name of layer 0: {}", layer.name());
let layer = ase.layer_by_name("Layer 1").unwrap();
println!("Layer 1 is visible? {}", layer.is_visible());
Cels
A cel is the intersection of a frame and a layer. Because of this there are multiple ways to access a cel:
let layer0 = ase.layer(0);
// These are all the same cel
let cel1 = layer0.frame(1);
let cel2 = ase.frame(1).layer(0);
let cel3 = ase.cel(1, 0); // or directly, which can avoid some borrowing issues
let image = cel1.image();
Tilesets
Since Aseprite 1.3 you can also create tilesets and tilemaps layers.
You access each tile separately, or export them all as one image which is one tile wide.
let num_tilesets = ase.tilesets().len();
let tileset = ase.tilesets().get(0).unwrap();
let all_tiles: RgbaImage = tileset.image();
let single_tile: RgbaImage = tileset.tile_image(1);
// Note: tile 0 is the empty tile
assert_eq!(
all_tiles.dimensions().0,
tileset.tile_size().width() as u32
);
assert_eq!(
all_tiles.dimensions().1,
tileset.tile_size().height() as u32 * tileset.tile_count()
)
Tilemaps
Aseprite also supports tilemaps which are layers that are composed entirely out of tiles from a tileset.
You can export those layers as a single large image or you can do some custom processing by looking at the tile indexes in the layer.
let layer = ase.layer_by_name("Tilemap 1").unwrap().id();
let tilemap = ase.tilemap(layer, 0).unwrap();
// This is the same as getting the image for the cel.
let tilemap_image = tilemap.image();
let num_tiles_x = tilemap.width();
let num_tiles_y = tilemap.height();
let (tile_width, tile_height) = tilemap.tile_size();
// Get a specific tile. Always succeeds. If the tile is out of bounds returns
// the empty tile (id 0).
let tile = tilemap.tile(0, 1);
println!("tile at (0, 1) references tile from tileset: {}", tile.id());
// You can access the tileset right through the tilemap.
let image = tilemap.tileset().tile_image(tile.id());
User data
Aseprite gives you the option to annotate certain entities with custom data.
Usually, that's a color and a text field. Each of those entities has a
user_data()
method.