From b05e61f5c8ae61c9f3c7cc08cded53901ebbccfd Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Wed, 3 Apr 2024 21:07:54 +0200 Subject: Redesign `iced_wgpu` layering architecture --- graphics/src/image.rs | 154 ++++++++++++++++++++++++++++++-------------------- 1 file changed, 94 insertions(+), 60 deletions(-) (limited to 'graphics/src/image.rs') diff --git a/graphics/src/image.rs b/graphics/src/image.rs index d89caace..e8626717 100644 --- a/graphics/src/image.rs +++ b/graphics/src/image.rs @@ -1,14 +1,94 @@ //! Load and operate on images. -use crate::core::image::{Data, Handle}; +#[cfg(feature = "image")] +pub use ::image as image_rs; -use bitflags::bitflags; +use crate::core::image; +use crate::core::svg; +use crate::core::{Color, Rectangle}; -pub use ::image as image_rs; +/// A raster or vector image. +#[derive(Debug, Clone)] +pub enum Image { + /// A raster image. + Raster { + /// The handle of a raster image. + handle: image::Handle, + + /// The filter method of a raster image. + filter_method: image::FilterMethod, + + /// The bounds of the image. + bounds: Rectangle, + }, + /// A vector image. + Vector { + /// The handle of a vector image. + handle: svg::Handle, + + /// The [`Color`] filter + color: Option, + /// The bounds of the image. + bounds: Rectangle, + }, +} + +#[cfg(feature = "image")] /// Tries to load an image by its [`Handle`]. -pub fn load(handle: &Handle) -> image_rs::ImageResult { +pub fn load( + handle: &image::Handle, +) -> ::image::ImageResult<::image::DynamicImage> { + use bitflags::bitflags; + + bitflags! { + struct Operation: u8 { + const FLIP_HORIZONTALLY = 0b001; + const ROTATE_180 = 0b010; + const FLIP_DIAGONALLY = 0b100; + } + } + + impl Operation { + // Meaning of the returned value is described e.g. at: + // https://magnushoff.com/articles/jpeg-orientation/ + fn from_exif(reader: &mut R) -> Result + where + R: std::io::BufRead + std::io::Seek, + { + let exif = exif::Reader::new().read_from_container(reader)?; + + Ok(exif + .get_field(exif::Tag::Orientation, exif::In::PRIMARY) + .and_then(|field| field.value.get_uint(0)) + .and_then(|value| u8::try_from(value).ok()) + .and_then(|value| Self::from_bits(value.saturating_sub(1))) + .unwrap_or_else(Self::empty)) + } + + fn perform( + self, + mut image: ::image::DynamicImage, + ) -> ::image::DynamicImage { + use ::image::imageops; + + if self.contains(Self::FLIP_DIAGONALLY) { + imageops::flip_vertical_in_place(&mut image); + } + + if self.contains(Self::ROTATE_180) { + imageops::rotate180_in_place(&mut image); + } + + if self.contains(Self::FLIP_HORIZONTALLY) { + imageops::flip_horizontal_in_place(&mut image); + } + + image + } + } + match handle.data() { - Data::Path(path) => { + image::Data::Path(path) => { let image = ::image::open(path)?; let operation = std::fs::File::open(path) @@ -19,7 +99,7 @@ pub fn load(handle: &Handle) -> image_rs::ImageResult { Ok(operation.perform(image)) } - Data::Bytes(bytes) => { + image::Data::Bytes(bytes) => { let image = ::image::load_from_memory(bytes)?; let operation = Operation::from_exif(&mut std::io::Cursor::new(bytes)) @@ -28,68 +108,22 @@ pub fn load(handle: &Handle) -> image_rs::ImageResult { Ok(operation.perform(image)) } - Data::Rgba { + image::Data::Rgba { width, height, pixels, } => { - if let Some(image) = image_rs::ImageBuffer::from_vec( - *width, - *height, - pixels.to_vec(), - ) { - Ok(image_rs::DynamicImage::ImageRgba8(image)) + if let Some(image) = + ::image::ImageBuffer::from_vec(*width, *height, pixels.to_vec()) + { + Ok(::image::DynamicImage::ImageRgba8(image)) } else { - Err(image_rs::error::ImageError::Limits( - image_rs::error::LimitError::from_kind( - image_rs::error::LimitErrorKind::DimensionError, + Err(::image::error::ImageError::Limits( + ::image::error::LimitError::from_kind( + ::image::error::LimitErrorKind::DimensionError, ), )) } } } } - -bitflags! { - struct Operation: u8 { - const FLIP_HORIZONTALLY = 0b001; - const ROTATE_180 = 0b010; - const FLIP_DIAGONALLY = 0b100; - } -} - -impl Operation { - // Meaning of the returned value is described e.g. at: - // https://magnushoff.com/articles/jpeg-orientation/ - fn from_exif(reader: &mut R) -> Result - where - R: std::io::BufRead + std::io::Seek, - { - let exif = exif::Reader::new().read_from_container(reader)?; - - Ok(exif - .get_field(exif::Tag::Orientation, exif::In::PRIMARY) - .and_then(|field| field.value.get_uint(0)) - .and_then(|value| u8::try_from(value).ok()) - .and_then(|value| Self::from_bits(value.saturating_sub(1))) - .unwrap_or_else(Self::empty)) - } - - fn perform(self, mut image: image::DynamicImage) -> image::DynamicImage { - use image::imageops; - - if self.contains(Self::FLIP_DIAGONALLY) { - imageops::flip_vertical_in_place(&mut image); - } - - if self.contains(Self::ROTATE_180) { - imageops::rotate180_in_place(&mut image); - } - - if self.contains(Self::FLIP_HORIZONTALLY) { - imageops::flip_horizontal_in_place(&mut image); - } - - image - } -} -- cgit From cc05cb9be4a1de5f0427f93ce64e658be0703f8b Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Wed, 3 Apr 2024 23:39:38 +0200 Subject: Fix broken doc links in `iced_wgpu` and `iced_graphics` --- graphics/src/image.rs | 2 ++ 1 file changed, 2 insertions(+) (limited to 'graphics/src/image.rs') diff --git a/graphics/src/image.rs b/graphics/src/image.rs index e8626717..47a7b30e 100644 --- a/graphics/src/image.rs +++ b/graphics/src/image.rs @@ -35,6 +35,8 @@ pub enum Image { #[cfg(feature = "image")] /// Tries to load an image by its [`Handle`]. +/// +/// [`Handle`]: image::Handle pub fn load( handle: &image::Handle, ) -> ::image::ImageResult<::image::DynamicImage> { -- cgit From fdd9896dc5f727f4c659ad6252f1ab36cca77762 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Wed, 10 Apr 2024 19:55:27 +0200 Subject: Track image damage in `iced_tiny_skia` --- graphics/src/image.rs | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'graphics/src/image.rs') diff --git a/graphics/src/image.rs b/graphics/src/image.rs index 47a7b30e..c6135e9e 100644 --- a/graphics/src/image.rs +++ b/graphics/src/image.rs @@ -7,7 +7,7 @@ use crate::core::svg; use crate::core::{Color, Rectangle}; /// A raster or vector image. -#[derive(Debug, Clone)] +#[derive(Debug, Clone, PartialEq)] pub enum Image { /// A raster image. Raster { @@ -33,6 +33,17 @@ pub enum Image { }, } +impl Image { + /// Returns the bounds of the [`Image`]. + pub fn bounds(&self) -> Rectangle { + match self { + Image::Raster { bounds, .. } | Image::Vector { bounds, .. } => { + *bounds + } + } + } +} + #[cfg(feature = "image")] /// Tries to load an image by its [`Handle`]. /// -- cgit