2022-02-23 07:16:34 +11:00
|
|
|
use std::{
|
|
|
|
fs::File,
|
|
|
|
path::{Path, PathBuf},
|
|
|
|
process::Command,
|
|
|
|
str,
|
|
|
|
};
|
|
|
|
|
|
|
|
use image::DynamicImage;
|
2022-02-16 08:28:21 +11:00
|
|
|
use serde::Deserialize;
|
|
|
|
|
|
|
|
#[derive(Deserialize)]
|
|
|
|
pub struct Aseprite {
|
|
|
|
pub frames: Vec<Frame>,
|
|
|
|
pub meta: Meta,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Deserialize)]
|
|
|
|
pub struct Meta {
|
|
|
|
pub app: String,
|
|
|
|
pub version: String,
|
|
|
|
pub image: String,
|
|
|
|
pub format: String,
|
|
|
|
pub size: Size,
|
|
|
|
pub scale: String,
|
|
|
|
#[serde(rename = "frameTags")]
|
|
|
|
pub frame_tags: Vec<FrameTag>,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Deserialize)]
|
|
|
|
pub struct Size {
|
|
|
|
pub w: u32,
|
|
|
|
pub h: u32,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Deserialize, Clone, Copy)]
|
|
|
|
#[serde(rename_all = "lowercase")]
|
|
|
|
pub enum Direction {
|
|
|
|
Forward,
|
|
|
|
Backward,
|
|
|
|
Pingpong,
|
|
|
|
}
|
|
|
|
|
2022-02-23 07:16:34 +11:00
|
|
|
#[derive(Deserialize, Clone)]
|
2022-02-16 08:28:21 +11:00
|
|
|
pub struct FrameTag {
|
|
|
|
pub name: String,
|
|
|
|
pub from: u32,
|
|
|
|
pub to: u32,
|
|
|
|
pub direction: Direction,
|
|
|
|
}
|
|
|
|
|
2022-02-23 07:16:34 +11:00
|
|
|
#[derive(Deserialize, Clone)]
|
2022-02-16 08:28:21 +11:00
|
|
|
pub struct Frame {
|
|
|
|
pub frame: Frame2,
|
|
|
|
pub trimmed: bool,
|
|
|
|
}
|
|
|
|
|
2022-02-23 07:16:34 +11:00
|
|
|
#[derive(Deserialize, Clone)]
|
2022-02-16 08:28:21 +11:00
|
|
|
pub struct Frame2 {
|
|
|
|
pub x: u32,
|
|
|
|
pub y: u32,
|
|
|
|
pub w: u32,
|
|
|
|
pub h: u32,
|
|
|
|
}
|
2022-02-23 07:16:34 +11:00
|
|
|
|
2022-02-23 07:24:32 +11:00
|
|
|
pub fn generate_from_file(filename: &Path) -> (Aseprite, DynamicImage) {
|
2022-02-23 07:16:34 +11:00
|
|
|
let out_dir = std::env::var("OUT_DIR").expect("Expected OUT_DIR");
|
|
|
|
|
2022-02-23 07:24:32 +11:00
|
|
|
let output_filename = Path::new(&out_dir).join(filename.file_name().unwrap());
|
|
|
|
|
2022-02-23 07:16:34 +11:00
|
|
|
let image_output = output_filename.with_extension("png");
|
|
|
|
let json_output = output_filename.with_extension("json");
|
|
|
|
|
|
|
|
let command = Command::new("aseprite")
|
|
|
|
.args([
|
|
|
|
&PathBuf::from("-b"),
|
|
|
|
&PathBuf::from(filename),
|
|
|
|
&"--sheet".into(),
|
|
|
|
&image_output,
|
|
|
|
&"--format".into(),
|
|
|
|
&"json-array".into(),
|
|
|
|
&"--data".into(),
|
|
|
|
&json_output,
|
|
|
|
&"--list-tags".into(),
|
|
|
|
])
|
|
|
|
.output()
|
|
|
|
.expect("Could not run aseprite");
|
|
|
|
assert!(
|
|
|
|
command.status.success(),
|
|
|
|
"Aseprite did not complete successfully : {}",
|
|
|
|
str::from_utf8(&*command.stdout).unwrap_or("Output contains invalid string")
|
|
|
|
);
|
|
|
|
|
|
|
|
let json: Aseprite = serde_json::from_reader(
|
|
|
|
File::open(&json_output).expect("The json output from aseprite could not be openned"),
|
|
|
|
)
|
|
|
|
.expect("The output from aseprite could not be decoded");
|
|
|
|
|
|
|
|
(
|
|
|
|
json,
|
|
|
|
image::open(image_output).expect("Image should be readable"),
|
|
|
|
)
|
|
|
|
}
|