From 0323dadc7f7bee26a971abd355b32aada6398402 Mon Sep 17 00:00:00 2001 From: tmorin Date: Sat, 11 Sep 2021 17:36:46 +0200 Subject: [PATCH] fix: icons with transparent background could not be properly generated to sprites --- Cargo.lock | 240 ++++++++++++++++-- Cargo.toml | 1 + .../generate/tasks/item/sprite_icon.rs | 95 ++++--- 3 files changed, 279 insertions(+), 57 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 21acd4c..38ed750 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,5 +1,7 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. +version = 3 + [[package]] name = "adler" version = "1.0.2" @@ -53,6 +55,12 @@ version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" +[[package]] +name = "bitflags" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aad18937a628ec6abcd26d1489012cc0e18c21798210f491af69ded9b881106d" + [[package]] name = "bitflags" version = "1.2.1" @@ -67,7 +75,7 @@ checksum = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b" dependencies = [ "block-padding", "byte-tools", - "byteorder", + "byteorder 1.4.3", "generic-array", ] @@ -107,6 +115,12 @@ version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9966d2ab714d0f785dbac0a0396251a35280aeb42413281617d0209ab4898435" +[[package]] +name = "byteorder" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fc10e8cc6b2580fda3f36eb6dc5316657f812a3df879a44a66fc9f0fdbc4855" + [[package]] name = "byteorder" version = "1.4.3" @@ -139,7 +153,7 @@ checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73" dependencies = [ "libc", "num-integer", - "num-traits", + "num-traits 0.2.14", "time", "winapi", ] @@ -162,7 +176,7 @@ checksum = "37e58ac78573c40708d45522f0d80fa2f01cc4f9b4e2bf749807255454312002" dependencies = [ "ansi_term", "atty", - "bitflags", + "bitflags 1.2.1", "strsim", "textwrap", "unicode-width", @@ -251,7 +265,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "73770f8e1fe7d64df17ca66ad28994a0a623ea497fa69486e14984e715c5d174" dependencies = [ "adler32", - "byteorder", + "byteorder 1.4.3", ] [[package]] @@ -290,6 +304,15 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "enum_primitive" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be4551092f4d519593039259a9ed8daedf0da12e5109c5280338073eaeb81180" +dependencies = [ + "num-traits 0.1.43", +] + [[package]] name = "env_logger" version = "0.8.4" @@ -305,6 +328,16 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" +[[package]] +name = "flate2" +version = "0.2.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6234dd4468ae5d1e2dbb06fe2b058696fdc50a339c68a393aefbf00bc81e423" +dependencies = [ + "libc", + "miniz-sys", +] + [[package]] name = "fnv" version = "1.0.7" @@ -336,6 +369,12 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "fuchsia-cprng" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" + [[package]] name = "futures-channel" version = "0.3.15" @@ -405,6 +444,16 @@ dependencies = [ "wasi", ] +[[package]] +name = "gif" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2e41945ba23db3bf51b24756d73d81acb4f28d85c3dccc32c6fae904438c25f" +dependencies = [ + "color_quant", + "lzw", +] + [[package]] name = "gif" version = "0.11.2" @@ -415,6 +464,12 @@ dependencies = [ "weezl", ] +[[package]] +name = "glob" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb" + [[package]] name = "glob" version = "0.3.0" @@ -440,7 +495,7 @@ version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "93e3af942408868f6934a7b85134a3230832b9977cf66125df2f9edcfce4ddcc" dependencies = [ - "bitflags", + "bitflags 1.2.1", "ignore", "walkdir", ] @@ -595,6 +650,21 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "image" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76df2dce95fef56fd35dbc41c36e37b19aede703c6be7739e8b65d5788ffc728" +dependencies = [ + "byteorder 0.5.3", + "enum_primitive", + "glob 0.2.11", + "jpeg-decoder", + "num-iter", + "num-rational 0.1.42", + "num-traits 0.1.43", +] + [[package]] name = "image" version = "0.23.14" @@ -602,14 +672,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24ffcb7e7244a9bf19d35bf2883b9c080c4ced3c07a9895572178cdb8f13f6a1" dependencies = [ "bytemuck", - "byteorder", + "byteorder 1.4.3", "color_quant", - "gif", + "gif 0.11.2", "jpeg-decoder", "num-iter", - "num-rational", - "num-traits", - "png", + "num-rational 0.3.2", + "num-traits 0.2.14", + "png 0.16.8", "scoped_threadpool", "tiff", ] @@ -624,6 +694,12 @@ dependencies = [ "hashbrown", ] +[[package]] +name = "inflate" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7e0062d2dc2f17d2f13750d95316ae8a2ff909af0fda957084f5defd87c43bb" + [[package]] name = "ipnet" version = "2.3.1" @@ -681,6 +757,12 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "lzw" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d947cbb889ed21c2a84be6ffbaebf5b4e0f4340638cba0444907e38b56be084" + [[package]] name = "maplit" version = "1.0.2" @@ -714,6 +796,16 @@ version = "0.3.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d" +[[package]] +name = "miniz-sys" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e9e3ae51cea1576ceba0dde3d484d30e6e5b86dee0b2d412fe3a16a15c98202" +dependencies = [ + "cc", + "libc", +] + [[package]] name = "miniz_oxide" version = "0.3.7" @@ -782,6 +874,18 @@ dependencies = [ "winapi", ] +[[package]] +name = "num-bigint" +version = "0.1.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e63899ad0da84ce718c14936262a41cee2c79c981fc0a0e7c7beb47d5a07e8c1" +dependencies = [ + "num-integer", + "num-traits 0.2.14", + "rand 0.4.6", + "rustc-serialize", +] + [[package]] name = "num-integer" version = "0.1.44" @@ -789,7 +893,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db" dependencies = [ "autocfg", - "num-traits", + "num-traits 0.2.14", ] [[package]] @@ -800,7 +904,19 @@ checksum = "b2021c8337a54d21aca0d59a92577a029af9431cb59b909b03252b9c164fad59" dependencies = [ "autocfg", "num-integer", - "num-traits", + "num-traits 0.2.14", +] + +[[package]] +name = "num-rational" +version = "0.1.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee314c74bd753fc86b4780aa9475da469155f3848473a261d2d18e35245a784e" +dependencies = [ + "num-bigint", + "num-integer", + "num-traits 0.2.14", + "rustc-serialize", ] [[package]] @@ -811,7 +927,16 @@ checksum = "12ac428b1cb17fce6f731001d307d351ec70a6d202fc2e60f7d4c5e42d8f4f07" dependencies = [ "autocfg", "num-integer", - "num-traits", + "num-traits 0.2.14", +] + +[[package]] +name = "num-traits" +version = "0.1.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92e5113e9fd4cc14ded8e499429f396a20f98c772a47cc8622a736e1ec843c31" +dependencies = [ + "num-traits 0.2.14", ] [[package]] @@ -851,7 +976,7 @@ version = "0.10.35" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "549430950c79ae24e6d02e0b7404534ecf311d94cc9f861e9e4020187d13d885" dependencies = [ - "bitflags", + "bitflags 1.2.1", "cfg-if", "foreign-types", "libc", @@ -971,25 +1096,38 @@ dependencies = [ "chrono", "clap", "env_logger", - "glob", + "glob 0.3.0", "heck", "hyper", - "image", + "image 0.23.14", "log", "openssl", + "raster", "reqwest", "serde", "serde_yaml", "tera", ] +[[package]] +name = "png" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06208e2ee243e3118a55dda9318f821f206d8563fb8d4df258767f8e62bb0997" +dependencies = [ + "bitflags 0.7.0", + "flate2", + "inflate", + "num-iter", +] + [[package]] name = "png" version = "0.16.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c3287920cb847dee3de33d301c463fba14dda99db24214ddf93f83d3021f4c6" dependencies = [ - "bitflags", + "bitflags 1.2.1", "crc32fast", "deflate", "miniz_oxide 0.3.7", @@ -1019,6 +1157,19 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "rand" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "552840b97013b1a26992c11eac34bdd778e464601a4c2054b5f0bff7c6761293" +dependencies = [ + "fuchsia-cprng", + "libc", + "rand_core 0.3.1", + "rdrand", + "winapi", +] + [[package]] name = "rand" version = "0.8.4" @@ -1027,7 +1178,7 @@ checksum = "2e7573632e6454cf6b99d7aac4ccca54be06da05aca2ef7423d22d27d4d4bcd8" dependencies = [ "libc", "rand_chacha", - "rand_core", + "rand_core 0.6.3", "rand_hc", ] @@ -1038,9 +1189,24 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" dependencies = [ "ppv-lite86", - "rand_core", + "rand_core 0.6.3", ] +[[package]] +name = "rand_core" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" +dependencies = [ + "rand_core 0.4.2", +] + +[[package]] +name = "rand_core" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc" + [[package]] name = "rand_core" version = "0.6.3" @@ -1056,7 +1222,18 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d51e9f596de227fda2ea6c84607f5558e196eeaf43c986b724ba4fb8fdf497e7" dependencies = [ - "rand_core", + "rand_core 0.6.3", +] + +[[package]] +name = "raster" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c3f9e9cfa4260e25ea0d3bc72f3724afbeb65a61f8cb4d38c1d4de5309cd7ef" +dependencies = [ + "gif 0.9.2", + "image 0.10.4", + "png 0.5.2", ] [[package]] @@ -1084,13 +1261,22 @@ dependencies = [ "num_cpus", ] +[[package]] +name = "rdrand" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" +dependencies = [ + "rand_core 0.3.1", +] + [[package]] name = "redox_syscall" version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5ab49abadf3f9e1c4bc499e8845e152ad87d2ad2d30371841171169e9d75feee" dependencies = [ - "bitflags", + "bitflags 1.2.1", ] [[package]] @@ -1153,6 +1339,12 @@ dependencies = [ "winreg", ] +[[package]] +name = "rustc-serialize" +version = "0.3.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda" + [[package]] name = "ryu" version = "1.0.5" @@ -1196,7 +1388,7 @@ version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "23a2ac85147a3a11d77ecf1bc7166ec0b92febfa4461c37944e180f319ece467" dependencies = [ - "bitflags", + "bitflags 1.2.1", "core-foundation", "core-foundation-sys", "libc", @@ -1330,7 +1522,7 @@ checksum = "dac1c663cfc93810f88aed9b8941d48cabf856a1b111c29a40439018d870eb22" dependencies = [ "cfg-if", "libc", - "rand", + "rand 0.8.4", "redox_syscall", "remove_dir_all", "winapi", @@ -1350,7 +1542,7 @@ dependencies = [ "percent-encoding", "pest", "pest_derive", - "rand", + "rand 0.8.4", "regex", "serde", "serde_json", diff --git a/Cargo.toml b/Cargo.toml index d40d5ee..105c733 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -34,6 +34,7 @@ hyper = { version = "0.14", features = ["client", "http1", "libc"] } image = { version = "0.23" } log = "0.4" openssl = { version = "0.10", optional = true } +raster = "0.2.0" reqwest = { version = "0.11", features = ["blocking"] } serde = { version = "1", features = ["derive"] } serde_yaml = "0.8" diff --git a/src/cmd/library/generate/tasks/item/sprite_icon.rs b/src/cmd/library/generate/tasks/item/sprite_icon.rs index 11b8cc0..b7bd09f 100644 --- a/src/cmd/library/generate/tasks/item/sprite_icon.rs +++ b/src/cmd/library/generate/tasks/item/sprite_icon.rs @@ -1,8 +1,6 @@ use std::path::Path; -use image::imageops::FilterType; -use image::io::Reader; -use image::GenericImageView; +use raster::{BlendMode, Color, Image, PositionMode, ResizeMode}; use serde::{Deserialize, Serialize}; use crate::cmd::library::generate::config::Config; @@ -87,40 +85,71 @@ impl Task for SpriteIconTask { // create the destination directory create_parent_directory(destination_icon_path)?; - // get an handler on the source icon - let image = Reader::open(&self.full_source_icon) - .map_err(|e| { - Error::Cause( - format!("unable to open {}", &self.full_source_icon), - Box::from(e), - ) - })? - .decode() - .map_err(|e| { - Error::Cause( - format!("unable to decode {}", &self.full_source_icon), - Box::from(e), - ) - })?; + // create the source image + let mut source_image = raster::open(&self.full_source_icon).map_err(|e| { + Error::Simple(format!( + "unable to open {}: {:?}", + &self.full_source_icon, e + )) + })?; // compute the width of the sprite icon - let (width, height) = image.dimensions(); - let destination_icon_width = self.destination_icon_height * width / height; + let destination_icon_width = self.destination_icon_height as i32 + * source_image.width as i32 + / source_image.height as i32; + + // resize source image + raster::editor::resize( + &mut source_image, + destination_icon_width as i32, + self.destination_icon_height as i32, + ResizeMode::ExactHeight, + ) + .map_err(|e| { + Error::Simple(format!( + "unable to resize {}: {:?}", + &self.full_source_icon, e + )) + })?; + + // create the destination image + let mut background_image = Image::blank( + destination_icon_width as i32, + self.destination_icon_height as i32, + ); + + // fill destination image with white + raster::editor::fill(&mut background_image, Color::white()).map_err(|e| { + Error::Simple(format!( + "unable to fill {}: {:?}", + &self.full_destination_icon, e + )) + })?; + + // blend resized source and destination + let destination_image = raster::editor::blend( + &background_image, + &source_image, + BlendMode::Normal, + 1.0, + PositionMode::Center, + 0, + 0, + ) + .map_err(|e| { + Error::Simple(format!( + "unable to blend {} in {}: {:?}", + &self.full_source_icon, &self.full_destination_icon, e + )) + })?; // generate the sprite icon - image - .resize( - destination_icon_width, - self.destination_icon_height, - FilterType::Triangle, - ) - .save(&self.full_destination_icon) - .map_err(|e| { - Error::Cause( - format!("unable to save {}", &self.full_destination_icon), - Box::from(e), - ) - })?; + raster::save(&destination_image, &self.full_destination_icon).map_err(|e| { + Error::Simple(format!( + "unable to save {}: {:?}", + &self.full_destination_icon, e + )) + })?; Ok(()) } }