mirror of
https://github.com/tauri-apps/tauri.git
synced 2024-12-20 00:52:41 +03:00
Co-authored-by: Fetzer <fetz@fetzverse.com> Co-authored-by: Lucas Nogueira <lucas@tauri.studio> Co-authored-by: FabianLars <fabianlars@fabianlars.de>
This commit is contained in:
parent
fd532da899
commit
50f7ccbbf3
6
.changes/icon-svg.md
Normal file
6
.changes/icon-svg.md
Normal file
@ -0,0 +1,6 @@
|
||||
---
|
||||
"tauri-cli": patch:feat
|
||||
"@tauri-apps/cli": patch:feat
|
||||
---
|
||||
|
||||
Add suport to SVG input image for the `tauri icon` command.
|
307
tooling/cli/Cargo.lock
generated
307
tooling/cli/Cargo.lock
generated
@ -155,6 +155,18 @@ version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d67af77d68a931ecd5cbd8a3b5987d63a1d1d1278f7f6a60ae33db485cdebb69"
|
||||
|
||||
[[package]]
|
||||
name = "arrayref"
|
||||
version = "0.3.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6b4930d2cb77ce62f89ee5d5289b4ac049559b1c45539271f5ed4fdc7db34545"
|
||||
|
||||
[[package]]
|
||||
name = "arrayvec"
|
||||
version = "0.7.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711"
|
||||
|
||||
[[package]]
|
||||
name = "async-lock"
|
||||
version = "2.8.0"
|
||||
@ -850,6 +862,12 @@ version = "2.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308"
|
||||
|
||||
[[package]]
|
||||
name = "data-url"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "41b319d1b62ffbd002e057f36bebd1f42b9f97927c9577461d855f3513c4289f"
|
||||
|
||||
[[package]]
|
||||
name = "deranged"
|
||||
version = "0.3.9"
|
||||
@ -1183,6 +1201,12 @@ dependencies = [
|
||||
"miniz_oxide",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "float-cmp"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "98de4bbd547a563b716d8dfa9aad1cb19bfab00f4fa09a6a4ed21dbcf44ce9c4"
|
||||
|
||||
[[package]]
|
||||
name = "flume"
|
||||
version = "0.11.0"
|
||||
@ -1198,6 +1222,29 @@ version = "1.0.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
|
||||
|
||||
[[package]]
|
||||
name = "fontconfig-parser"
|
||||
version = "0.5.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "674e258f4b5d2dcd63888c01c68413c51f565e8af99d2f7701c7b81d79ef41c4"
|
||||
dependencies = [
|
||||
"roxmltree",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fontdb"
|
||||
version = "0.15.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "020e203f177c0fb250fb19455a252e838d2bbbce1f80f25ecc42402aafa8cd38"
|
||||
dependencies = [
|
||||
"fontconfig-parser",
|
||||
"log",
|
||||
"memmap2",
|
||||
"slotmap",
|
||||
"tinyvec",
|
||||
"ttf-parser",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "foreign-types"
|
||||
version = "0.3.2"
|
||||
@ -1687,6 +1734,12 @@ dependencies = [
|
||||
"tiff",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "imagesize"
|
||||
version = "0.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "029d73f573d8e8d63e6d5020011d3255b28c3ba85d6cf870a07184ed23de9284"
|
||||
|
||||
[[package]]
|
||||
name = "include_dir"
|
||||
version = "0.7.3"
|
||||
@ -2042,6 +2095,15 @@ dependencies = [
|
||||
"selectors",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "kurbo"
|
||||
version = "0.9.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bd85a5776cd9500c2e2059c8c76c3b01528566b7fcbaf8098b55a33fc298849b"
|
||||
dependencies = [
|
||||
"arrayvec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "1.4.0"
|
||||
@ -2257,6 +2319,15 @@ version = "2.6.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167"
|
||||
|
||||
[[package]]
|
||||
name = "memmap2"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "43a5a03cefb0d953ec0be133036f14e109412fa594edc2f77227249db66cc3ed"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "memoffset"
|
||||
version = "0.9.0"
|
||||
@ -2945,6 +3016,12 @@ dependencies = [
|
||||
"siphasher",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pico-args"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5be167a7af36ee22fe3115051bc51f6e6c7054c9348e28deb4f49bd6f705a315"
|
||||
|
||||
[[package]]
|
||||
name = "pin-project"
|
||||
version = "1.1.3"
|
||||
@ -3183,6 +3260,12 @@ dependencies = [
|
||||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rctree"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3b42e27ef78c35d3998403c1d26f3efd9e135d3e5121b0a4845cc5cc27547f4f"
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.2.16"
|
||||
@ -3285,6 +3368,32 @@ dependencies = [
|
||||
"winreg 0.50.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "resvg"
|
||||
version = "0.36.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cc7980f653f9a7db31acff916a262c3b78c562919263edea29bf41a056e20497"
|
||||
dependencies = [
|
||||
"gif",
|
||||
"jpeg-decoder",
|
||||
"log",
|
||||
"pico-args",
|
||||
"png",
|
||||
"rgb",
|
||||
"svgtypes",
|
||||
"tiny-skia",
|
||||
"usvg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rgb"
|
||||
version = "0.8.37"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "05aaa8004b64fd573fc9d002f4e632d51ad4f026c2b5ba95fcb6c2f32c2c47d8"
|
||||
dependencies = [
|
||||
"bytemuck",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ring"
|
||||
version = "0.16.20"
|
||||
@ -3312,6 +3421,15 @@ version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "afab94fb28594581f62d981211a9a4d53cc8130bbcbbb89a0440d9b8e81a7746"
|
||||
|
||||
[[package]]
|
||||
name = "roxmltree"
|
||||
version = "0.18.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "862340e351ce1b271a378ec53f304a5558f7db87f3769dc655a8f6ecbb68b302"
|
||||
dependencies = [
|
||||
"xmlparser",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rpassword"
|
||||
version = "7.2.0"
|
||||
@ -3395,6 +3513,22 @@ version = "1.0.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4"
|
||||
|
||||
[[package]]
|
||||
name = "rustybuzz"
|
||||
version = "0.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "71cd15fef9112a1f94ac64b58d1e4628192631ad6af4dc69997f995459c874e7"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
"bytemuck",
|
||||
"smallvec",
|
||||
"ttf-parser",
|
||||
"unicode-bidi-mirroring",
|
||||
"unicode-ccc",
|
||||
"unicode-properties",
|
||||
"unicode-script",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.15"
|
||||
@ -3751,6 +3885,15 @@ version = "0.3.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe"
|
||||
|
||||
[[package]]
|
||||
name = "simplecss"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a11be7c62927d9427e9f40f3444d5499d868648e2edbc4e2116de69e7ec0e89d"
|
||||
dependencies = [
|
||||
"log",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "siphasher"
|
||||
version = "0.3.11"
|
||||
@ -3766,6 +3909,15 @@ dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "slotmap"
|
||||
version = "1.0.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e1e08e261d0e8f5c43123b7adf3e4ca1690d655377ac93a03b2c9d3e98de1342"
|
||||
dependencies = [
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "smallvec"
|
||||
version = "1.11.1"
|
||||
@ -3851,6 +4003,15 @@ dependencies = [
|
||||
"regex",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "strict-num"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6637bab7722d379c8b41ba849228d680cc12d0a45ba1fa2b48f2a30577a06731"
|
||||
dependencies = [
|
||||
"float-cmp",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "string_cache"
|
||||
version = "0.8.7"
|
||||
@ -3963,6 +4124,16 @@ dependencies = [
|
||||
"sval_fmt",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "svgtypes"
|
||||
version = "0.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d71499ff2d42f59d26edb21369a308ede691421f79ebc0f001e2b1fd3a7c9e52"
|
||||
dependencies = [
|
||||
"kurbo",
|
||||
"siphasher",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.109"
|
||||
@ -4119,6 +4290,7 @@ dependencies = [
|
||||
"os_info",
|
||||
"os_pipe",
|
||||
"regex",
|
||||
"resvg",
|
||||
"semver",
|
||||
"serde",
|
||||
"serde-value",
|
||||
@ -4353,6 +4525,32 @@ dependencies = [
|
||||
"time-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tiny-skia"
|
||||
version = "0.11.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3b72a92a05db376db09fe6d50b7948d106011761c05a6a45e23e17ee9b556222"
|
||||
dependencies = [
|
||||
"arrayref",
|
||||
"arrayvec",
|
||||
"bytemuck",
|
||||
"cfg-if",
|
||||
"log",
|
||||
"png",
|
||||
"tiny-skia-path",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tiny-skia-path"
|
||||
version = "0.11.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6ac3865b9708fc7e1961a65c3a4fa55e984272f33092d3c859929f887fceb647"
|
||||
dependencies = [
|
||||
"arrayref",
|
||||
"bytemuck",
|
||||
"strict-num",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tinyvec"
|
||||
version = "1.6.0"
|
||||
@ -4553,6 +4751,12 @@ version = "0.2.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed"
|
||||
|
||||
[[package]]
|
||||
name = "ttf-parser"
|
||||
version = "0.19.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "49d64318d8311fc2668e48b63969f4343e0a85c4a109aa8460d6672e364b8bd1"
|
||||
|
||||
[[package]]
|
||||
name = "tungstenite"
|
||||
version = "0.20.1"
|
||||
@ -4599,6 +4803,18 @@ version = "0.3.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-bidi-mirroring"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "56d12260fb92d52f9008be7e4bca09f584780eb2266dc8fecc6a192bec561694"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ccc"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cc2520efa644f8268dce4dcd3050eaa7fc044fca03961e9998ac7e2e92b77cf1"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.12"
|
||||
@ -4614,12 +4830,30 @@ dependencies = [
|
||||
"tinyvec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-properties"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c7f91c8b21fbbaa18853c3d0801c78f4fc94cdb976699bb03e832e75f7fd22f0"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-script"
|
||||
version = "0.5.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7d817255e1bed6dfd4ca47258685d14d2bdcfbc64fdc9e3819bd5848057b8ecc"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-segmentation"
|
||||
version = "1.10.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-vo"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b1d386ff53b415b7fe27b50bb44679e2cc4660272694b7b6f3326d8480823a94"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-width"
|
||||
version = "0.1.11"
|
||||
@ -4671,6 +4905,67 @@ dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "usvg"
|
||||
version = "0.36.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c51daa774fe9ee5efcf7b4fec13019b8119cda764d9a8b5b06df02bb1445c656"
|
||||
dependencies = [
|
||||
"base64 0.21.4",
|
||||
"log",
|
||||
"pico-args",
|
||||
"usvg-parser",
|
||||
"usvg-text-layout",
|
||||
"usvg-tree",
|
||||
"xmlwriter",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "usvg-parser"
|
||||
version = "0.36.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "45c88a5ffaa338f0e978ecf3d4e00d8f9f493e29bed0752e1a808a1db16afc40"
|
||||
dependencies = [
|
||||
"data-url",
|
||||
"flate2",
|
||||
"imagesize",
|
||||
"kurbo",
|
||||
"log",
|
||||
"roxmltree",
|
||||
"simplecss",
|
||||
"siphasher",
|
||||
"svgtypes",
|
||||
"usvg-tree",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "usvg-text-layout"
|
||||
version = "0.36.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4d2374378cb7a3fb8f33894e0fdb8625e1bbc4f25312db8d91f862130b541593"
|
||||
dependencies = [
|
||||
"fontdb",
|
||||
"kurbo",
|
||||
"log",
|
||||
"rustybuzz",
|
||||
"unicode-bidi",
|
||||
"unicode-script",
|
||||
"unicode-vo",
|
||||
"usvg-tree",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "usvg-tree"
|
||||
version = "0.36.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6cacb0c5edeaf3e80e5afcf5b0d4004cc1d36318befc9a7c6606507e5d0f4062"
|
||||
dependencies = [
|
||||
"rctree",
|
||||
"strict-num",
|
||||
"svgtypes",
|
||||
"tiny-skia-path",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "utf-8"
|
||||
version = "0.7.6"
|
||||
@ -5205,6 +5500,18 @@ dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "xmlparser"
|
||||
version = "0.13.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "66fee0b777b0f5ac1c69bb06d361268faafa61cd4682ae064a171c16c433e9e4"
|
||||
|
||||
[[package]]
|
||||
name = "xmlwriter"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ec7a2a501ed189703dba8b08142f057e887dfc4b2cc4db2d343ac6376ba3e0b9"
|
||||
|
||||
[[package]]
|
||||
name = "zeroize"
|
||||
version = "1.6.0"
|
||||
|
@ -94,6 +94,7 @@ serde-value = "0.7.0"
|
||||
itertools = "0.11"
|
||||
local-ip-address = "0.5"
|
||||
css-color = "0.2"
|
||||
resvg = "0.36.0"
|
||||
|
||||
[target."cfg(windows)".dependencies]
|
||||
winapi = { version = "0.3", features = [ "handleapi", "processenv", "winbase", "wincon", "winnt" ] }
|
||||
|
@ -23,6 +23,8 @@ use image::{
|
||||
imageops::FilterType,
|
||||
open, ColorType, DynamicImage, ImageBuffer, ImageEncoder, Rgba,
|
||||
};
|
||||
use resvg::usvg::{fontdb, TreeParsing, TreeTextToPath};
|
||||
use resvg::{tiny_skia, usvg};
|
||||
use serde::Deserialize;
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
@ -41,7 +43,7 @@ struct PngEntry {
|
||||
#[derive(Debug, Parser)]
|
||||
#[clap(about = "Generate various icons for all major platforms")]
|
||||
pub struct Options {
|
||||
/// Path to the source icon (png, 1024x1024px with transparency).
|
||||
/// Path to the source icon (squared PNG or SVG file with transparency).
|
||||
#[clap(default_value = "./app-icon.png")]
|
||||
input: PathBuf,
|
||||
/// Output directory.
|
||||
@ -58,6 +60,43 @@ pub struct Options {
|
||||
ios_color: String,
|
||||
}
|
||||
|
||||
enum Source {
|
||||
Svg(resvg::Tree),
|
||||
DynamicImage(DynamicImage),
|
||||
}
|
||||
|
||||
impl Source {
|
||||
fn width(&self) -> u32 {
|
||||
match self {
|
||||
Self::Svg(svg) => svg.size.width() as u32,
|
||||
Self::DynamicImage(i) => i.width(),
|
||||
}
|
||||
}
|
||||
|
||||
fn height(&self) -> u32 {
|
||||
match self {
|
||||
Self::Svg(svg) => svg.size.height() as u32,
|
||||
Self::DynamicImage(i) => i.height(),
|
||||
}
|
||||
}
|
||||
|
||||
fn resize_exact(&self, size: u32) -> Result<DynamicImage> {
|
||||
match self {
|
||||
Self::Svg(svg) => {
|
||||
let mut pixmap = tiny_skia::Pixmap::new(size, size).unwrap();
|
||||
let scale = size as f32 / svg.size.height();
|
||||
svg.render(
|
||||
tiny_skia::Transform::from_scale(scale, scale),
|
||||
&mut pixmap.as_mut(),
|
||||
);
|
||||
let img_buffer = ImageBuffer::from_raw(size, size, pixmap.take()).unwrap();
|
||||
Ok(DynamicImage::ImageRgba8(img_buffer))
|
||||
}
|
||||
Self::DynamicImage(i) => Ok(i.resize_exact(size, size, FilterType::Lanczos3)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn command(options: Options) -> Result<()> {
|
||||
let input = options.input;
|
||||
let out_dir = options.output.unwrap_or_else(|| tauri_dir().join("icons"));
|
||||
@ -75,11 +114,37 @@ pub fn command(options: Options) -> Result<()> {
|
||||
|
||||
create_dir_all(&out_dir).context("Can't create output directory")?;
|
||||
|
||||
let source = open(input)
|
||||
.context("Can't read and decode source image")?
|
||||
.into_rgba8();
|
||||
let source = if let Some(extension) = input.extension() {
|
||||
if extension == "svg" {
|
||||
let rtree = {
|
||||
let opt = usvg::Options {
|
||||
// Get file's absolute directory.
|
||||
resources_dir: std::fs::canonicalize(&input)
|
||||
.ok()
|
||||
.and_then(|p| p.parent().map(|p| p.to_path_buf())),
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
let source = DynamicImage::ImageRgba8(source);
|
||||
let mut fontdb = fontdb::Database::new();
|
||||
fontdb.load_system_fonts();
|
||||
|
||||
let svg_data = std::fs::read(&input).unwrap();
|
||||
let mut tree = usvg::Tree::from_data(&svg_data, &opt).unwrap();
|
||||
tree.convert_text(&fontdb);
|
||||
resvg::Tree::from_usvg(&tree)
|
||||
};
|
||||
|
||||
Source::Svg(rtree)
|
||||
} else {
|
||||
Source::DynamicImage(DynamicImage::ImageRgba8(
|
||||
open(&input)
|
||||
.context("Can't read and decode source image")?
|
||||
.into_rgba8(),
|
||||
))
|
||||
}
|
||||
} else {
|
||||
panic!("Error loading image");
|
||||
};
|
||||
|
||||
if source.height() != source.width() {
|
||||
panic!("Source image must be square");
|
||||
@ -106,29 +171,29 @@ pub fn command(options: Options) -> Result<()> {
|
||||
.collect::<Vec<PngEntry>>()
|
||||
{
|
||||
log::info!(action = "PNG"; "Creating {}", target.name);
|
||||
resize_and_save_png(&source, target.size, &target.out_path)?;
|
||||
resize_and_save_png(&source, target.size, &target.out_path, None)?;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn appx(source: &DynamicImage, out_dir: &Path) -> Result<()> {
|
||||
fn appx(source: &Source, out_dir: &Path) -> Result<()> {
|
||||
log::info!(action = "Appx"; "Creating StoreLogo.png");
|
||||
resize_and_save_png(source, 50, &out_dir.join("StoreLogo.png"))?;
|
||||
resize_and_save_png(source, 50, &out_dir.join("StoreLogo.png"), None)?;
|
||||
|
||||
for size in [30, 44, 71, 89, 107, 142, 150, 284, 310] {
|
||||
let file_name = format!("Square{size}x{size}Logo.png");
|
||||
log::info!(action = "Appx"; "Creating {}", file_name);
|
||||
|
||||
resize_and_save_png(source, size, &out_dir.join(&file_name))?;
|
||||
resize_and_save_png(source, size, &out_dir.join(&file_name), None)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
// Main target: macOS
|
||||
fn icns(source: &DynamicImage, out_dir: &Path) -> Result<()> {
|
||||
fn icns(source: &Source, out_dir: &Path) -> Result<()> {
|
||||
log::info!(action = "ICNS"; "Creating icon.icns");
|
||||
let entries: HashMap<String, IcnsEntry> =
|
||||
serde_json::from_slice(include_bytes!("helpers/icns.json")).unwrap();
|
||||
@ -139,7 +204,7 @@ fn icns(source: &DynamicImage, out_dir: &Path) -> Result<()> {
|
||||
let size = entry.size;
|
||||
let mut buf = Vec::new();
|
||||
|
||||
let image = source.resize_exact(size, size, FilterType::Lanczos3);
|
||||
let image = source.resize_exact(size)?;
|
||||
|
||||
write_png(image.as_bytes(), &mut buf, size)?;
|
||||
|
||||
@ -162,12 +227,12 @@ fn icns(source: &DynamicImage, out_dir: &Path) -> Result<()> {
|
||||
|
||||
// Generate .ico file with layers for the most common sizes.
|
||||
// Main target: Windows
|
||||
fn ico(source: &DynamicImage, out_dir: &Path) -> Result<()> {
|
||||
fn ico(source: &Source, out_dir: &Path) -> Result<()> {
|
||||
log::info!(action = "ICO"; "Creating icon.ico");
|
||||
let mut frames = Vec::new();
|
||||
|
||||
for size in [32, 16, 24, 48, 64, 256] {
|
||||
let image = source.resize_exact(size, size, FilterType::Lanczos3);
|
||||
let image = source.resize_exact(size)?;
|
||||
|
||||
// Only the 256px layer can be compressed according to the ico specs.
|
||||
if size == 256 {
|
||||
@ -196,7 +261,7 @@ fn ico(source: &DynamicImage, out_dir: &Path) -> Result<()> {
|
||||
|
||||
// Generate .png files in 32x32, 128x128, 256x256, 512x512 (icon.png)
|
||||
// Main target: Linux
|
||||
fn png(source: &DynamicImage, out_dir: &Path, ios_color: Rgba<u8>) -> Result<()> {
|
||||
fn png(source: &Source, out_dir: &Path, ios_color: Rgba<u8>) -> Result<()> {
|
||||
fn desktop_entries(out_dir: &Path) -> Vec<PngEntry> {
|
||||
let mut entries = Vec::new();
|
||||
|
||||
@ -383,27 +448,32 @@ fn png(source: &DynamicImage, out_dir: &Path, ios_color: Rgba<u8>) -> Result<()>
|
||||
|
||||
for entry in entries {
|
||||
log::info!(action = "PNG"; "Creating {}", entry.name);
|
||||
resize_and_save_png(source, entry.size, &entry.out_path)?;
|
||||
resize_and_save_png(source, entry.size, &entry.out_path, None)?;
|
||||
}
|
||||
|
||||
let source_rgba8 = source.as_rgba8().expect("unexpected image type");
|
||||
let mut img = ImageBuffer::from_fn(source_rgba8.width(), source_rgba8.height(), |_, _| {
|
||||
ios_color
|
||||
});
|
||||
image::imageops::overlay(&mut img, source_rgba8, 0, 0);
|
||||
let image = DynamicImage::ImageRgba8(img);
|
||||
|
||||
for entry in ios_entries(&out)? {
|
||||
log::info!(action = "iOS"; "Creating {}", entry.name);
|
||||
resize_and_save_png(&image, entry.size, &entry.out_path)?;
|
||||
resize_and_save_png(source, entry.size, &entry.out_path, Some(ios_color))?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
// Resize image and save it to disk.
|
||||
fn resize_and_save_png(source: &DynamicImage, size: u32, file_path: &Path) -> Result<()> {
|
||||
let image = source.resize_exact(size, size, FilterType::Lanczos3);
|
||||
fn resize_and_save_png(
|
||||
source: &Source,
|
||||
size: u32,
|
||||
file_path: &Path,
|
||||
bg_color: Option<Rgba<u8>>,
|
||||
) -> Result<()> {
|
||||
let mut image = source.resize_exact(size)?;
|
||||
|
||||
if let Some(bg_color) = bg_color {
|
||||
let mut bg_img = ImageBuffer::from_fn(size, size, |_, _| bg_color);
|
||||
image::imageops::overlay(&mut bg_img, &image, 0, 0);
|
||||
image = bg_img.into();
|
||||
}
|
||||
|
||||
let mut out_file = BufWriter::new(File::create(file_path)?);
|
||||
write_png(image.as_bytes(), &mut out_file, size)?;
|
||||
Ok(out_file.flush()?)
|
||||
|
Loading…
Reference in New Issue
Block a user