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>
This commit is contained in:
khuongduy354 2022-12-27 20:34:20 +07:00 committed by GitHub
parent f5305de251
commit 9d2144128f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 54 additions and 18 deletions

6
.changes/custom-icon.md Normal file
View File

@ -0,0 +1,6 @@
---
"cli.rs": minor
"cli.js": minor
---
Add `--png` option for the `icon` command to generate custom icon sizes.

View File

@ -30,6 +30,20 @@ struct IcnsEntry {
ostype: String,
}
struct PngTarget {
size: u32,
file_name: String,
}
impl PngTarget {
fn new(size: u32, file_name: impl Into<String>) -> Self {
Self {
size,
file_name: file_name.into(),
}
}
}
#[derive(Debug, Parser)]
#[clap(about = "Generates various icons for all major platforms")]
pub struct Options {
@ -41,15 +55,18 @@ pub struct Options {
/// Default: 'icons' directory next to the tauri.conf.json file.
#[clap(short, long)]
output: Option<PathBuf>,
/// Custom PNG icon sizes to generate. When set, the default icons are not generated.
#[clap(short, long, use_value_delimiter = true)]
png: Option<Vec<u32>>,
}
pub fn command(options: Options) -> Result<()> {
let input = options.input;
let out_dir = options.output.unwrap_or_else(|| tauri_dir().join("icons"));
let png_icon_sizes = options.png.unwrap_or_default();
create_dir_all(&out_dir).context("Can't create output directory")?;
// Try to read the image as a DynamicImage, convert it to rgba8 and turn it into a DynamicImage again.
// Both things should be catched by the explicit conversions to rgba8 anyway.
let source = open(input)
.context("Can't read and decode source image")?
.into_rgba8();
@ -60,13 +77,32 @@ pub fn command(options: Options) -> Result<()> {
panic!("Source image must be square");
}
appx(&source, &out_dir).context("Failed to generate appx icons")?;
if png_icon_sizes.is_empty() {
appx(&source, &out_dir).context("Failed to generate appx icons")?;
icns(&source, &out_dir).context("Failed to generate .icns file")?;
ico(&source, &out_dir).context("Failed to generate .ico file")?;
icns(&source, &out_dir).context("Failed to generate .icns file")?;
ico(&source, &out_dir).context("Failed to generate .ico file")?;
png(&source, &out_dir).context("Failed to generate png icons")?;
let mut png_targets = vec![
PngTarget::new(256, "128x128@2x.png"),
PngTarget::new(512, "icon.png"),
];
png_targets.extend(
[32, 128]
.into_iter()
.map(|size| PngTarget::new(size, format!("{}x{}.png", size, size)))
.collect::<Vec<PngTarget>>(),
);
png(&source, &out_dir, png_targets).context("Failed to generate png icons")?;
} else {
png(
&source,
&out_dir,
png_icon_sizes
.into_iter()
.map(|size| PngTarget::new(size, format!("{}x{}.png", size, size)))
.collect(),
)?;
}
Ok(())
}
@ -154,16 +190,10 @@ 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) -> Result<()> {
for size in [32, 128, 256, 512] {
let file_name = match size {
256 => "128x128@2x.png".to_string(),
512 => "icon.png".to_string(),
_ => format!("{size}x{size}.png"),
};
log::info!(action = "PNG"; "Creating {}", file_name);
resize_and_save_png(source, size, &out_dir.join(&file_name))?;
fn png(source: &DynamicImage, out_dir: &Path, targets: Vec<PngTarget>) -> Result<()> {
for target in targets {
log::info!(action = "PNG"; "Creating {}", target.file_name);
resize_and_save_png(source, target.size, &out_dir.join(&target.file_name))?;
}
Ok(())