Skip to content

Commit 1be37a3

Browse files
authored
refactor(core): remove image dependency (#1859)
1 parent 95d518a commit 1be37a3

5 files changed

Lines changed: 39 additions & 27 deletions

File tree

.changes/remove-image-crate.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
"tauri": patch
3+
"tauri-runtime-wry": patch
4+
---
5+
6+
Removes `image` dependency. For now only `.ico` icons on Windows are supported, and we'll implement other types on demand to optimize bundle size.

core/tauri-runtime-wry/Cargo.toml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,11 @@ readme = "README.md"
1515
wry = { version = "0.9.2", default-features = false, features = [ "file-drop", "protocol", "win32" ] }
1616
tauri-runtime = { version = "0.1.1", path = "../tauri-runtime" }
1717
tauri-utils = { version = "1.0.0-beta.0", path = "../tauri-utils" }
18-
image = "0.23"
1918
uuid = { version = "0.8.2", features = [ "v4" ] }
19+
infer = "0.4"
20+
21+
[target."cfg(windows)".dependencies]
22+
ico = "0.1"
2023

2124
[features]
2225
dox = [ "wry/dox" ]

core/tauri-runtime-wry/src/lib.rs

Lines changed: 28 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ use tauri_runtime::SystemTrayEvent;
2323
#[cfg(feature = "system-tray")]
2424
use wry::application::platform::system_tray::SystemTrayBuilder;
2525

26-
use image::{GenericImageView, Pixel};
2726
use tauri_utils::config::WindowConfig;
2827
use uuid::Uuid;
2928
use wry::{
@@ -47,6 +46,7 @@ use wry::{
4746
use std::{
4847
collections::HashMap,
4948
convert::TryFrom,
49+
fs::read,
5050
sync::{
5151
mpsc::{channel, Receiver, Sender},
5252
Arc, Mutex,
@@ -64,38 +64,42 @@ type MainThreadTask = Box<dyn FnOnce() + Send>;
6464
type WindowEventHandler = Box<dyn Fn(&WindowEvent) + Send>;
6565
type WindowEventListeners = Arc<Mutex<HashMap<Uuid, WindowEventHandler>>>;
6666

67-
#[repr(C)]
68-
#[derive(Debug)]
69-
struct PixelValue {
70-
r: u8,
71-
g: u8,
72-
b: u8,
73-
a: u8,
74-
}
75-
76-
const PIXEL_SIZE: usize = std::mem::size_of::<PixelValue>();
77-
7867
/// Wrapper around a [`wry::application::window::Icon`] that can be created from an [`Icon`].
7968
pub struct WryIcon(WindowIcon);
8069

70+
fn icon_err<E: std::error::Error + Send + 'static>(e: E) -> Error {
71+
Error::InvalidIcon(Box::new(e))
72+
}
73+
8174
impl TryFrom<Icon> for WryIcon {
8275
type Error = Error;
8376
fn try_from(icon: Icon) -> std::result::Result<Self, Self::Error> {
84-
let image = match icon {
85-
Icon::File(path) => image::open(path).map_err(|e| Error::InvalidIcon(Box::new(e)))?,
86-
Icon::Raw(raw) => {
87-
image::load_from_memory(&raw).map_err(|e| Error::InvalidIcon(Box::new(e)))?
88-
}
77+
let image_bytes = match icon {
78+
Icon::File(path) => read(path).map_err(icon_err)?,
79+
Icon::Raw(raw) => raw,
8980
_ => unimplemented!(),
9081
};
91-
let (width, height) = image.dimensions();
92-
let mut rgba = Vec::with_capacity((width * height) as usize * PIXEL_SIZE);
93-
for (_, _, pixel) in image.pixels() {
94-
rgba.extend_from_slice(&pixel.to_rgba().0);
82+
let extension = infer::get(&image_bytes)
83+
.expect("could not determine icon extension")
84+
.extension();
85+
match extension {
86+
#[cfg(windows)]
87+
"ico" => {
88+
let icon_dir = ico::IconDir::read(std::io::Cursor::new(image_bytes)).map_err(icon_err)?;
89+
let entry = &icon_dir.entries()[0];
90+
let icon = WindowIcon::from_rgba(
91+
entry.decode().map_err(icon_err)?.rgba_data().to_vec(),
92+
entry.width(),
93+
entry.height(),
94+
)
95+
.map_err(icon_err)?;
96+
Ok(Self(icon))
97+
}
98+
_ => panic!(
99+
"image `{}` extension not supported; please file a Tauri feature request",
100+
extension
101+
),
95102
}
96-
let icon =
97-
WindowIcon::from_rgba(rgba, width, height).map_err(|e| Error::InvalidIcon(Box::new(e)))?;
98-
Ok(Self(icon))
99103
}
100104
}
101105

core/tauri/Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,6 @@ open = "1.7.0"
6262
shared_child = "0.3"
6363
os_pipe = "0.9"
6464
minisign-verify = "0.1.8"
65-
image = "0.23"
6665
state = "0.4"
6766
bincode = "1.3"
6867

core/tauri/src/app.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -535,7 +535,7 @@ where
535535
}
536536

537537
#[cfg(not(target_os = "linux"))]
538-
if let Some(Icon::File(bytes)) = icon {
538+
if let Some(Icon::File(_)) = icon {
539539
return Err(crate::Error::InvalidIcon(Box::new(Error::new(
540540
ErrorKind::InvalidInput,
541541
"system tray icons on non-linux platforms must be the raw bytes",

0 commit comments

Comments
 (0)