Skip to content

Commit

Permalink
feat(cli): add --ios-color option to set iOS icon background color (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
lucasfernog authored Feb 12, 2023
1 parent 96b5e92 commit 6775542
Show file tree
Hide file tree
Showing 22 changed files with 44 additions and 7 deletions.
6 changes: 6 additions & 0 deletions .changes/ios-icon-color.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"cli.rs": patch
"cli.js": patch
---

Added `--ios-color` option to the `tauri icon` command.
7 changes: 7 additions & 0 deletions tooling/cli/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions tooling/cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ kuchiki = "0.8"
tokio = { version = "1", features = [ "macros", "sync" ] }
common-path = "1"
local-ip-address = "0.4"
css-color = "0.2"

[target."cfg(windows)".dependencies]
winapi = { version = "0.3", features = [ "handleapi", "processenv", "winbase", "wincon", "winnt" ] }
Expand Down
37 changes: 30 additions & 7 deletions tooling/cli/src/icon.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use std::{
fs::{create_dir_all, File},
io::{BufWriter, Write},
path::{Path, PathBuf},
str::FromStr,
};

use anyhow::Context;
Expand All @@ -20,7 +21,7 @@ use image::{
png::{CompressionType, FilterType as PngFilterType, PngEncoder},
},
imageops::FilterType,
open, ColorType, DynamicImage, ImageEncoder,
open, ColorType, DynamicImage, ImageBuffer, ImageEncoder, Rgba,
};
use serde::Deserialize;

Expand Down Expand Up @@ -48,11 +49,25 @@ pub struct Options {
/// Default: 'icons' directory next to the tauri.conf.json file.
#[clap(short, long)]
output: Option<PathBuf>,
/// The background color of the iOS icon - string as defined in the W3C's CSS Color Module Level 4 <https://www.w3.org/TR/css-color-4/>.
#[clap(long, default_value = "#fff")]
ios_color: String,
}

pub fn command(options: Options) -> Result<()> {
let input = options.input;
let out_dir = options.output.unwrap_or_else(|| tauri_dir().join("icons"));
let ios_color = css_color::Srgb::from_str(&options.ios_color)
.map(|color| {
Rgba([
(color.red * 255.) as u8,
(color.green * 255.) as u8,
(color.blue * 255.) as u8,
(color.alpha * 255.) as u8,
])
})
.map_err(|_| anyhow::anyhow!("failed to parse iOS color"))?;

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.
Expand All @@ -73,7 +88,7 @@ pub fn command(options: Options) -> Result<()> {

ico(&source, &out_dir).context("Failed to generate .ico file")?;

png(&source, &out_dir).context("Failed to generate png icons")?;
png(&source, &out_dir, ios_color).context("Failed to generate png icons")?;

Ok(())
}
Expand Down Expand Up @@ -161,7 +176,7 @@ fn ico(source: &DynamicImage, out_dir: &Path) -> Result<()> {

// Generate .png files in 32x32, 128x128, 256x256, 512x512 (icon.png)
// Main target: Linux & Android
fn png(source: &DynamicImage, out_dir: &Path) -> Result<()> {
fn png(source: &DynamicImage, out_dir: &Path, ios_color: Rgba<u8>) -> Result<()> {
fn desktop_entries(out_dir: &Path) -> Vec<PngEntry> {
let mut entries = Vec::new();

Expand Down Expand Up @@ -350,24 +365,32 @@ fn png(source: &DynamicImage, out_dir: &Path) -> Result<()> {
create_dir_all(&out).context("Can't create iOS output directory")?;
out
};
entries.extend(ios_entries(&out)?);

for entry in entries {
log::info!(action = "PNG"; "Creating {}", entry.name);
resize_and_save_png(source, entry.size, &entry.out_path)?;
}

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)?;
}

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);

let mut out_file = BufWriter::new(File::create(file_path)?);

write_png(image.as_bytes(), &mut out_file, size)?;

Ok(out_file.flush()?)
}

Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 6775542

Please sign in to comment.