eframe/
icon_data.rs

1//! Helpers for loading [`egui::IconData`].
2
3use egui::IconData;
4
5/// Helpers for working with [`IconData`].
6pub trait IconDataExt {
7    /// Convert into [`image::RgbaImage`]
8    ///
9    /// # Errors
10    /// If `width*height != 4 * rgba.len()`, or if the image is too big.
11    fn to_image(&self) -> Result<image::RgbaImage, String>;
12
13    /// Encode as PNG.
14    ///
15    /// # Errors
16    /// The image is invalid, or the PNG encoder failed.
17    fn to_png_bytes(&self) -> Result<Vec<u8>, String>;
18}
19
20/// Load the contents of .png file.
21///
22/// # Errors
23/// If this is not a valid png.
24pub fn from_png_bytes(png_bytes: &[u8]) -> Result<IconData, image::ImageError> {
25    profiling::function_scope!();
26    let image = image::load_from_memory(png_bytes)?;
27    Ok(from_image(image))
28}
29
30fn from_image(image: image::DynamicImage) -> IconData {
31    let image = image.into_rgba8();
32    IconData {
33        width: image.width(),
34        height: image.height(),
35        rgba: image.into_raw(),
36    }
37}
38
39impl IconDataExt for IconData {
40    fn to_image(&self) -> Result<image::RgbaImage, String> {
41        profiling::function_scope!();
42        let Self {
43            rgba,
44            width,
45            height,
46        } = self.clone();
47        image::RgbaImage::from_raw(width, height, rgba).ok_or_else(|| "Invalid IconData".to_owned())
48    }
49
50    fn to_png_bytes(&self) -> Result<Vec<u8>, String> {
51        profiling::function_scope!();
52        let image = self.to_image()?;
53        let mut png_bytes: Vec<u8> = Vec::new();
54        image
55            .write_to(
56                &mut std::io::Cursor::new(&mut png_bytes),
57                image::ImageFormat::Png,
58            )
59            .map_err(|err| err.to_string())?;
60        Ok(png_bytes)
61    }
62}