mirror of https://github.com/Leinnan/rpack.git
Frames JSON
This commit is contained in:
parent
7e62334e54
commit
8b51af05cd
|
|
@ -885,6 +885,16 @@ dependencies = [
|
|||
"web-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "egui_json_tree"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b6c549dbaae5f70f0d4a9ec068617d24051a4e74f8611298e484bf76a09f06d0"
|
||||
dependencies = [
|
||||
"egui",
|
||||
"serde_json",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ehttp"
|
||||
version = "0.3.1"
|
||||
|
|
@ -1423,6 +1433,12 @@ dependencies = [
|
|||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "1.0.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38"
|
||||
|
||||
[[package]]
|
||||
name = "jni"
|
||||
version = "0.21.1"
|
||||
|
|
@ -2173,11 +2189,13 @@ dependencies = [
|
|||
"eframe",
|
||||
"egui",
|
||||
"egui_extras",
|
||||
"egui_json_tree",
|
||||
"env_logger",
|
||||
"image",
|
||||
"js-sys",
|
||||
"log",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"texture_packer",
|
||||
"wasm-bindgen",
|
||||
"wasm-bindgen-futures",
|
||||
|
|
@ -2220,6 +2238,12 @@ dependencies = [
|
|||
"untrusted",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741"
|
||||
|
||||
[[package]]
|
||||
name = "same-file"
|
||||
version = "1.0.6"
|
||||
|
|
@ -2253,24 +2277,35 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.163"
|
||||
version = "1.0.193"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2113ab51b87a539ae008b5c6c02dc020ffa39afd2d83cffcb3f4eb2722cebec2"
|
||||
checksum = "25dd9975e68d0cb5aa1120c288333fc98731bd1dd12f561e468ea4728c042b89"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.163"
|
||||
version = "1.0.193"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8c805777e3930c8883389c602315a24224bcc738b63905ef87cd1420353ea93e"
|
||||
checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.39",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.108"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3d1c7e3eac408d115102c4c24ad393e0821bb3a5df4d506a80f85f7a742a526b"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"ryu",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_repr"
|
||||
version = "0.1.12"
|
||||
|
|
|
|||
|
|
@ -17,6 +17,8 @@ eframe = { version = "0.24.1", default-features = false, features = [
|
|||
"persistence", # Enable restoring app state when restarting the app.
|
||||
] }
|
||||
log = "0.4"
|
||||
serde_json = "1"
|
||||
egui_json_tree = "0.2"
|
||||
|
||||
# You only need serde if you want app persistence:
|
||||
serde = { version = "1", features = ["derive"] }
|
||||
|
|
|
|||
104
src/app.rs
104
src/app.rs
|
|
@ -3,9 +3,8 @@ use std::{collections::HashMap, io::Cursor};
|
|||
use egui::{CollapsingHeader, Color32, DroppedFile, FontFamily, FontId, Image, RichText};
|
||||
use image::DynamicImage;
|
||||
|
||||
use texture_packer::{
|
||||
importer::ImageImporter, texture::Texture, TexturePacker, TexturePackerConfig,
|
||||
};
|
||||
use serde_json::Value;
|
||||
use texture_packer::{importer::ImageImporter, TexturePacker, TexturePackerConfig};
|
||||
pub const MY_ACCENT_COLOR32: Color32 = Color32::from_rgb(230, 102, 1);
|
||||
pub const TOP_SIDE_MARGIN: f32 = 10.0;
|
||||
pub const HEADER_HEIGHT: f32 = 45.0;
|
||||
|
|
@ -16,9 +15,77 @@ pub const GIT_HASH: &str = env!("GIT_HASH");
|
|||
pub struct Spritesheet {
|
||||
pub data: Vec<u8>,
|
||||
pub frames: HashMap<String, texture_packer::Frame<String>>,
|
||||
pub frames_json: Value,
|
||||
pub size: (u32, u32),
|
||||
}
|
||||
|
||||
/// Boundaries and properties of a packed texture.
|
||||
#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
|
||||
pub struct SerializableFrame {
|
||||
/// Key used to uniquely identify this frame.
|
||||
pub key: String,
|
||||
/// Rectangle describing the texture coordinates and size.
|
||||
pub frame: SerializableRect,
|
||||
/// True if the texture was rotated during packing.
|
||||
/// If it was rotated, it was rotated 90 degrees clockwise.
|
||||
pub rotated: bool,
|
||||
/// True if the texture was trimmed during packing.
|
||||
pub trimmed: bool,
|
||||
|
||||
// (x, y) is the trimmed frame position at original image
|
||||
// (w, h) is original image size
|
||||
//
|
||||
// w
|
||||
// +--------------+
|
||||
// | (x, y) |
|
||||
// | ^ |
|
||||
// | | |
|
||||
// | ********* |
|
||||
// | * * | h
|
||||
// | * * |
|
||||
// | ********* |
|
||||
// | |
|
||||
// +--------------+
|
||||
/// Source texture size before any trimming.
|
||||
pub source: SerializableRect,
|
||||
}
|
||||
|
||||
impl From<texture_packer::Frame<String>> for SerializableFrame {
|
||||
fn from(value: texture_packer::Frame<String>) -> Self {
|
||||
SerializableFrame {
|
||||
key: value.key,
|
||||
frame: value.frame.into(),
|
||||
rotated: value.rotated,
|
||||
trimmed: value.trimmed,
|
||||
source: value.source.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Defines a rectangle in pixels with the origin at the top-left of the texture atlas.
|
||||
#[derive(Copy, Clone, Debug, serde::Deserialize, serde::Serialize)]
|
||||
pub struct SerializableRect {
|
||||
/// Horizontal position the rectangle begins at.
|
||||
pub x: u32,
|
||||
/// Vertical position the rectangle begins at.
|
||||
pub y: u32,
|
||||
/// Width of the rectangle.
|
||||
pub w: u32,
|
||||
/// Height of the rectangle.
|
||||
pub h: u32,
|
||||
}
|
||||
|
||||
impl From<texture_packer::Rect> for SerializableRect {
|
||||
fn from(value: texture_packer::Rect) -> Self {
|
||||
SerializableRect {
|
||||
h: value.h,
|
||||
w: value.w,
|
||||
x: value.x,
|
||||
y: value.y,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// We derive Deserialize/Serialize so we can persist app state on shutdown.
|
||||
#[derive(serde::Deserialize, serde::Serialize)]
|
||||
#[serde(default)] // if we add new fields, give them default values when deserializing old state
|
||||
|
|
@ -105,15 +172,25 @@ impl TemplateApp {
|
|||
println!(" {:7} : {:?}", name, frame.frame);
|
||||
}
|
||||
let mut out_vec = vec![];
|
||||
let exporter = texture_packer::exporter::ImageExporter::export(&packer).unwrap();
|
||||
exporter
|
||||
.write_to(&mut Cursor::new(&mut out_vec), image::ImageFormat::Png)
|
||||
let exported_image = texture_packer::exporter::ImageExporter::export(&packer).unwrap();
|
||||
let mut img = image::DynamicImage::new_rgba8(self.config.max_width, self.config.max_height);
|
||||
image::imageops::overlay(&mut img, &exported_image, 0, 0);
|
||||
|
||||
img.write_to(&mut Cursor::new(&mut out_vec), image::ImageFormat::Png)
|
||||
.unwrap();
|
||||
|
||||
let frames_info: Vec<SerializableFrame> = packer
|
||||
.get_frames()
|
||||
.values()
|
||||
.map(|v| -> SerializableFrame { (*v).clone().into() })
|
||||
.collect();
|
||||
let frames_string = serde_json::to_string_pretty(&frames_info).unwrap();
|
||||
let frames_json = serde_json::from_str(&frames_string).unwrap();
|
||||
self.data = Some(Spritesheet {
|
||||
data: out_vec.clone(),
|
||||
frames: packer.get_frames().clone(),
|
||||
size: (packer.width(), packer.height()),
|
||||
size: (img.width(), img.height()),
|
||||
frames_json,
|
||||
});
|
||||
let id = format!("bytes://output_{}.png", self.counter);
|
||||
self.image = None;
|
||||
|
|
@ -300,19 +377,22 @@ impl eframe::App for TemplateApp {
|
|||
});
|
||||
ui.with_layout(egui::Layout::top_down_justified(egui::Align::Min), |ui|{
|
||||
|
||||
egui::ScrollArea::vertical().auto_shrink(false).show(ui, |ui| {
|
||||
if let Some(image) = &self.image {
|
||||
ui.horizontal_top(|ui|{
|
||||
let data = &self.data.clone().unwrap();
|
||||
ui.label(format!("{} frames, size: {}x{}",data.frames.len(),data.size.0,data.size.1));
|
||||
});
|
||||
CollapsingHeader::new("Preview")
|
||||
.default_open(true)
|
||||
.show(ui, |ui| {
|
||||
ui.add(image.clone());
|
||||
CollapsingHeader::new("Preview")
|
||||
.default_open(true)
|
||||
.show(ui, |ui| {
|
||||
ui.label(RichText::new("Frames JSON").strong());
|
||||
egui_json_tree::JsonTree::new("simple-tree", &self.data.clone().unwrap().frames_json).show(ui);
|
||||
ui.label(RichText::new("Spritesheet").strong());
|
||||
ui.add(image.clone());
|
||||
});
|
||||
}
|
||||
ui.separator();
|
||||
egui::ScrollArea::vertical().auto_shrink(false).show(ui, |ui| {
|
||||
let mut index_to_remove : Option<usize> = None;
|
||||
for (i, file) in self.dropped_files.iter().enumerate() {
|
||||
let mut info = if let Some(path) = &file.path {
|
||||
|
|
|
|||
Loading…
Reference in New Issue