GithubHelp home page GithubHelp logo

alpine-alpaca / asefile Goto Github PK

View Code? Open in Web Editor NEW
41.0 1.0 15.0 6.56 MB

Library for loading Aseprite files. Directly reads binary Aseprite files and does not require you to export files to JSON.

License: MIT License

Rust 91.07% Shell 0.33% C++ 8.60%
rust pixel-art gamedev-library

asefile's Introduction

asefile

Build status crates.io Documentation

Utilities for loading Aseprite files. This library directly reads the binary Aseprite files (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 (during development). You can also use it to build your own asset pipelines.

Documentation | Changelog

Example

use std::path::Path;

use asefile::AsepriteFile;
use image::{self, ImageFormat};

fn main() {
    let file = Path::new("input.aseprite");
    // Read file into memory
    let ase = AsepriteFile::read_file(&file).unwrap();
    // Write one output image for each frame in the Aseprite file.
    for frame in 0..ase.num_frames() {
        let output = format!("output_{}.png", frame);
        // Create image in memory, then write it to disk as PNG.
        let img = ase.frame(frame).image();
        img.save_with_format(output, ImageFormat::Png).unwrap();
    }
}

Unsupported Features

The following features of Aseprite 1.2.25 are currently not supported:

  • color profiles

Bug compatibility

  • For indexed color files Aseprite supports blend modes, but ignores them when exporting the image. The images constructed by asefile currently match the in-editor preview.

  • Aseprite has a bug in its luminance and color blend modes. Since this is the same in editor and in exported files, asefile reproduces this bug. (If Aseprite fixes this, asefile will fix this bug based on the version that the file was generated with.)

asefile's People

Contributors

alpine-alpaca avatar b-reif avatar coevolutions avatar feelingsonice avatar gwilymk avatar keyboarddanni avatar lucas-miranda avatar martinezjavier avatar sanbox-irl avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar

asefile's Issues

Refactoring types and invariants

I'm opening this issue to explore how we can encode some existing panic/assert invariants in static typing. This is one design I'm considering:

pub enum ImageContent {
    Rgba {
        palette: Option<ColorPalette>,
        cels: CelsData<pixel::Rgba>,
        tilesets: TilesetsById<pixel::Rgba>,
    },
    Grayscale {
        palette: Option<ColorPalette>,
        cels: CelsData<pixel::Grayscale>,
        tilesets: TilesetsById<pixel::Grayscale>,
    },
    Indexed {
        palette: ColorPalette,
        transparent_color_index: u8,
        cels: CelsData<pixel::Indexed>,
        tilesets: TilesetsById<pixel::Indexed>,
    },
}

Any invariant behavior around the pixel format (a palette must be present, etc) would be encoded in this single ImageContent enum. This would replace the PixelFormat and Pixels enums, and additionally contain the dependent data. Cels and Tilesets would become generic over a pixel type.

Cels and Tilesets also contain a lot of non-pixel metadata. Making these types generic would make it harder to work with all of the non-image content. I also considered a design where the pixel data would live in a separate map from the non-pixel metadata:

// Only these pixel tables are generic.
// The rest of the data remains non-generic, in the existing top-level maps.
// This would prevent the generic types from "leaking" into other code that touches cels or tilesets.
pub struct CelPixelsById<T>(HashMap<CelId, Vec<T>>);
pub struct TilesetPixelsById<T>(HashMap<TilesetId, Vec<T>>);

pub enum ImagePixelContent {
    Rgba {
        palette: Option<ColorPalette>,
        cels: CelPixelsById<pixel::Rgba>,
        tilesets: TilesetPixelsById<pixel::Rgba>,
    },
    // etc
}

This indirection would allow users to use Tilesets and Cels from multiple files without regard for their pixel format.

TilesetsById iterator

The map function for TilesetsById has been commented out. Without it, it's impossible to iterate over entries within the inner HashMap. It would be nice to either reinstate the method (rust naming conventions suggest this method be called .inner()), or implement other access methods like a custom iterator.

Indexed color pixel access

Hi, thanks for making this library!

Right now the only way to get the image contents is in already-processed RGBA pixels (via the 'image' crate, which isn't exactly a lightweight dependency). Since Aseprite is a pixel art editor, and it already exports indexed-color PNGs, it would be nice to be able to get the indexed color pixels in this library too.

This is going to be used for an asset pipeline to an engine that knows how to load indexed-color images (and may do more with them in the future).

At the very least I'd like to have access to the raw source image data (width, height, color format, palette, pixel data as array of bytes). Unfortunately the raw form is currently not exposed to consumers of the library as it's marked with pub(crate). Could this be opened up? Not everyone wants to use the high-level image-driven interface.

Thanks in advance!

Layer opacity ignored when constructing image

When constructing an image::RgbaImage through AsepriteFile::frame_image(&self, frame: u16), layer's opacity is completely ignored, which leaves to a wrong image result (comparing with aseprite itself)

Combine forces with ggez/aseprite crate

Since yesterday I've become a maintainer for the ggez/aseprite crate.

Since the aseprite crate is purely focused on parsing exported JSON, and this crate is focussed on parsing .aseprite files, I think it would be nice to somehow combine them or at least collaborate.

From a user's perspective, I think a workflow where you can work with the .aseprite files directly, ideally with hot reloading, and during a release build the JSON with a sprite sheet can be exported and bundled. I'm not sure how exactly this would look.

What are your thoughts on this?

Public-facing constructors

Currently, most asefile structs hide their fields and expose immutable access methods. To support use cases around testing and actually manipulating Aseprite files from code, we'll need to allow some level of public-facing constructor and/or mutation support.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.