Skip to content

Commit 9d21441

Browse files
khuongduy354FabianLarslucasfernog
authored
feat(cli): add option to make custom icon sizes, closes #5121 (#5246)
Co-authored-by: Fabian-Lars <fabianlars@fabianlars.de> Co-authored-by: Lucas Nogueira <lucas@tauri.studio>
1 parent f5305de commit 9d21441

File tree

2 files changed

+55
-19
lines changed

2 files changed

+55
-19
lines changed

.changes/custom-icon.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
"cli.rs": minor
3+
"cli.js": minor
4+
---
5+
6+
Add `--png` option for the `icon` command to generate custom icon sizes.

tooling/cli/src/icon.rs

Lines changed: 49 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,20 @@ struct IcnsEntry {
3030
ostype: String,
3131
}
3232

33+
struct PngTarget {
34+
size: u32,
35+
file_name: String,
36+
}
37+
38+
impl PngTarget {
39+
fn new(size: u32, file_name: impl Into<String>) -> Self {
40+
Self {
41+
size,
42+
file_name: file_name.into(),
43+
}
44+
}
45+
}
46+
3347
#[derive(Debug, Parser)]
3448
#[clap(about = "Generates various icons for all major platforms")]
3549
pub struct Options {
@@ -41,15 +55,18 @@ pub struct Options {
4155
/// Default: 'icons' directory next to the tauri.conf.json file.
4256
#[clap(short, long)]
4357
output: Option<PathBuf>,
58+
59+
/// Custom PNG icon sizes to generate. When set, the default icons are not generated.
60+
#[clap(short, long, use_value_delimiter = true)]
61+
png: Option<Vec<u32>>,
4462
}
4563

4664
pub fn command(options: Options) -> Result<()> {
4765
let input = options.input;
4866
let out_dir = options.output.unwrap_or_else(|| tauri_dir().join("icons"));
67+
let png_icon_sizes = options.png.unwrap_or_default();
4968
create_dir_all(&out_dir).context("Can't create output directory")?;
5069

51-
// Try to read the image as a DynamicImage, convert it to rgba8 and turn it into a DynamicImage again.
52-
// Both things should be catched by the explicit conversions to rgba8 anyway.
5370
let source = open(input)
5471
.context("Can't read and decode source image")?
5572
.into_rgba8();
@@ -60,13 +77,32 @@ pub fn command(options: Options) -> Result<()> {
6077
panic!("Source image must be square");
6178
}
6279

63-
appx(&source, &out_dir).context("Failed to generate appx icons")?;
64-
65-
icns(&source, &out_dir).context("Failed to generate .icns file")?;
66-
67-
ico(&source, &out_dir).context("Failed to generate .ico file")?;
68-
69-
png(&source, &out_dir).context("Failed to generate png icons")?;
80+
if png_icon_sizes.is_empty() {
81+
appx(&source, &out_dir).context("Failed to generate appx icons")?;
82+
icns(&source, &out_dir).context("Failed to generate .icns file")?;
83+
ico(&source, &out_dir).context("Failed to generate .ico file")?;
84+
85+
let mut png_targets = vec![
86+
PngTarget::new(256, "128x128@2x.png"),
87+
PngTarget::new(512, "icon.png"),
88+
];
89+
png_targets.extend(
90+
[32, 128]
91+
.into_iter()
92+
.map(|size| PngTarget::new(size, format!("{}x{}.png", size, size)))
93+
.collect::<Vec<PngTarget>>(),
94+
);
95+
png(&source, &out_dir, png_targets).context("Failed to generate png icons")?;
96+
} else {
97+
png(
98+
&source,
99+
&out_dir,
100+
png_icon_sizes
101+
.into_iter()
102+
.map(|size| PngTarget::new(size, format!("{}x{}.png", size, size)))
103+
.collect(),
104+
)?;
105+
}
70106

71107
Ok(())
72108
}
@@ -154,16 +190,10 @@ fn ico(source: &DynamicImage, out_dir: &Path) -> Result<()> {
154190

155191
// Generate .png files in 32x32, 128x128, 256x256, 512x512 (icon.png)
156192
// Main target: Linux
157-
fn png(source: &DynamicImage, out_dir: &Path) -> Result<()> {
158-
for size in [32, 128, 256, 512] {
159-
let file_name = match size {
160-
256 => "128x128@2x.png".to_string(),
161-
512 => "icon.png".to_string(),
162-
_ => format!("{size}x{size}.png"),
163-
};
164-
165-
log::info!(action = "PNG"; "Creating {}", file_name);
166-
resize_and_save_png(source, size, &out_dir.join(&file_name))?;
193+
fn png(source: &DynamicImage, out_dir: &Path, targets: Vec<PngTarget>) -> Result<()> {
194+
for target in targets {
195+
log::info!(action = "PNG"; "Creating {}", target.file_name);
196+
resize_and_save_png(source, target.size, &out_dir.join(&target.file_name))?;
167197
}
168198

169199
Ok(())

0 commit comments

Comments
 (0)