From d9b45171c26eef1ba4bd34811ecbb2832a5a425c Mon Sep 17 00:00:00 2001 From: "Sergey \"Shnatsel\" Davidoff" Date: Sat, 27 Jul 2024 11:41:57 +0100 Subject: [PATCH 01/19] Add in-place 180 degree rotation to DynamicImage --- src/dynimage.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/dynimage.rs b/src/dynimage.rs index 0d0ab74d87..56fa3edd94 100644 --- a/src/dynimage.rs +++ b/src/dynimage.rs @@ -896,6 +896,11 @@ impl DynamicImage { dynamic_map!(*self, ref p => imageops::rotate180(p)) } + /// Rotate this image 180 degrees clockwise in place. + pub fn rotate180_in_place(&mut self) { + dynamic_map!(*self, ref mut p, imageops::rotate180_in_place(p)) + } + /// Rotate this image 270 degrees clockwise. #[must_use] pub fn rotate270(&self) -> DynamicImage { From da93b9de2e8c432c2845c27c3e7715edbf47c7e6 Mon Sep 17 00:00:00 2001 From: "Sergey \"Shnatsel\" Davidoff" Date: Sat, 27 Jul 2024 11:42:53 +0100 Subject: [PATCH 02/19] Doc comment: when rotating 180 degrees, direction doesn't matter --- src/dynimage.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dynimage.rs b/src/dynimage.rs index 56fa3edd94..d2e318313b 100644 --- a/src/dynimage.rs +++ b/src/dynimage.rs @@ -890,13 +890,13 @@ impl DynamicImage { dynamic_map!(*self, ref p => imageops::rotate90(p)) } - /// Rotate this image 180 degrees clockwise. + /// Rotate this image 180 degrees. #[must_use] pub fn rotate180(&self) -> DynamicImage { dynamic_map!(*self, ref p => imageops::rotate180(p)) } - /// Rotate this image 180 degrees clockwise in place. + /// Rotate this image 180 degrees in place. pub fn rotate180_in_place(&mut self) { dynamic_map!(*self, ref mut p, imageops::rotate180_in_place(p)) } From f8cea836fff751919753bea2e453232d8c1afe8f Mon Sep 17 00:00:00 2001 From: "Sergey \"Shnatsel\" Davidoff" Date: Sat, 27 Jul 2024 11:45:39 +0100 Subject: [PATCH 03/19] Add in-place flips to DynamicImage --- src/dynimage.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/dynimage.rs b/src/dynimage.rs index d2e318313b..abd6735c28 100644 --- a/src/dynimage.rs +++ b/src/dynimage.rs @@ -878,12 +878,22 @@ impl DynamicImage { dynamic_map!(*self, ref p => imageops::flip_vertical(p)) } + /// Flip this image vertically in place + pub fn flipv_in_place(&mut self) { + dynamic_map!(*self, ref mut p, imageops::flip_vertical_in_place(p)) + } + /// Flip this image horizontally #[must_use] pub fn fliph(&self) -> DynamicImage { dynamic_map!(*self, ref p => imageops::flip_horizontal(p)) } + /// Flip this image horizontally in place + pub fn fliph_in_place(&mut self) { + dynamic_map!(*self, ref mut p, imageops::flip_horizontal_in_place(p)) + } + /// Rotate this image 90 degrees clockwise. #[must_use] pub fn rotate90(&self) -> DynamicImage { From a79973615548f7c286881d152ecb80efab708bd6 Mon Sep 17 00:00:00 2001 From: "Sergey \"Shnatsel\" Davidoff" Date: Tue, 30 Jul 2024 15:36:16 +0100 Subject: [PATCH 04/19] Add a function to apply Exif rotation --- src/dynimage.rs | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/src/dynimage.rs b/src/dynimage.rs index abd6735c28..65951df157 100644 --- a/src/dynimage.rs +++ b/src/dynimage.rs @@ -917,6 +917,43 @@ impl DynamicImage { dynamic_map!(*self, ref p => imageops::rotate270(p)) } + /// Applies the [Exif orientation](https://web.archive.org/web/20200412005226/https://www.impulseadventure.com/photo/exif-orientation.html) to the image. + /// + /// Orientation is specified in the Exif metadata, and is often written by cameras. + /// It is expressed as an integer in the range 1..=8; passing other values will return an error. + /// + /// Due to an implementation detail, orientations 5..=8 copy the image internally. + /// This operation should become truly in-place in the future. + pub fn apply_exif_orientation_in_place(&mut self, orientation: u8) -> Result<(), ImageError> { + // Verified against `convert -auto-orient` + let image = self; + match orientation { + 1 => Ok(()), // no transformations needed + 2 => Ok(image.fliph_in_place()), + 3 => Ok(image.rotate180_in_place()), + 4 => Ok(image.flipv_in_place()), + 5 => { + let mut new_image = image.rotate90(); + new_image.fliph_in_place(); + *image = new_image; + Ok(()) + } + 6 => Ok(*image = image.rotate90()), + 7 => { + let mut new_image = image.rotate270(); + new_image.fliph_in_place(); + *image = new_image; + Ok(()) + } + 8 => Ok(*image = image.rotate270()), + 0 | 9.. => { + return Err(ImageError::Parameter(ParameterError::from_kind( + ParameterErrorKind::Generic(format!("Invalid exif orientation: {orientation}")), + ))) + } + } + } + /// Encode this image and write it to ```w```. /// /// Assumes the writer is buffered. In most cases, From fb1ccafdc7752fb6c0c776cf036d3cc32f3e1b5d Mon Sep 17 00:00:00 2001 From: "Sergey \"Shnatsel\" Davidoff" Date: Tue, 30 Jul 2024 21:49:33 +0100 Subject: [PATCH 05/19] Do not promise to implement complex algorithms that aren't currently planned --- src/dynimage.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/dynimage.rs b/src/dynimage.rs index 65951df157..8e44f10066 100644 --- a/src/dynimage.rs +++ b/src/dynimage.rs @@ -923,7 +923,6 @@ impl DynamicImage { /// It is expressed as an integer in the range 1..=8; passing other values will return an error. /// /// Due to an implementation detail, orientations 5..=8 copy the image internally. - /// This operation should become truly in-place in the future. pub fn apply_exif_orientation_in_place(&mut self, orientation: u8) -> Result<(), ImageError> { // Verified against `convert -auto-orient` let image = self; From d3a8acf29a3434d1aa48c85b8dae6e0ad493bbb8 Mon Sep 17 00:00:00 2001 From: "Sergey \"Shnatsel\" Davidoff" Date: Sun, 1 Sep 2024 22:19:19 +0100 Subject: [PATCH 06/19] Create a type to encode image orientation, accept it in the function for applying orientation --- src/dynimage.rs | 35 +++++++++++++++-------------------- src/lib.rs | 2 ++ src/orientation.rs | 40 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 57 insertions(+), 20 deletions(-) create mode 100644 src/orientation.rs diff --git a/src/dynimage.rs b/src/dynimage.rs index 8e44f10066..4629dd29d5 100644 --- a/src/dynimage.rs +++ b/src/dynimage.rs @@ -17,9 +17,9 @@ use crate::image::{GenericImage, GenericImageView, ImageDecoder, ImageEncoder, I use crate::image_reader::free_functions; use crate::math::resize_dimensions; use crate::traits::Pixel; -use crate::ImageReader; use crate::{image, Luma, LumaA}; use crate::{imageops, ExtendedColorType}; +use crate::{ImageReader, Orientation}; use crate::{Rgb32FImage, Rgba32FImage}; /// A Dynamic Image @@ -917,39 +917,34 @@ impl DynamicImage { dynamic_map!(*self, ref p => imageops::rotate270(p)) } - /// Applies the [Exif orientation](https://web.archive.org/web/20200412005226/https://www.impulseadventure.com/photo/exif-orientation.html) to the image. + /// Applies the specified [Orientation] to the image. /// - /// Orientation is specified in the Exif metadata, and is often written by cameras. - /// It is expressed as an integer in the range 1..=8; passing other values will return an error. + /// Note that for some orientations cannot be efficiently applied in-place. + /// In that case this function will make a copy of the image internally. /// - /// Due to an implementation detail, orientations 5..=8 copy the image internally. - pub fn apply_exif_orientation_in_place(&mut self, orientation: u8) -> Result<(), ImageError> { - // Verified against `convert -auto-orient` + /// If this matters to you, please see the documentation on the variants of [Orientation] + /// to learn which orientations can and cannot be applied without copying. + pub fn apply_orientation(&mut self, orientation: Orientation) -> Result<(), ImageError> { let image = self; match orientation { - 1 => Ok(()), // no transformations needed - 2 => Ok(image.fliph_in_place()), - 3 => Ok(image.rotate180_in_place()), - 4 => Ok(image.flipv_in_place()), - 5 => { + Orientation::NoTransforms => Ok(()), + Orientation::Rotate90 => Ok(*image = image.rotate90()), + Orientation::Rotate180 => Ok(image.rotate180_in_place()), + Orientation::Rotate270 => Ok(*image = image.rotate270()), + Orientation::FlipH => Ok(image.fliph_in_place()), + Orientation::FlipV => Ok(image.flipv_in_place()), + Orientation::Rotate90FlipH => { let mut new_image = image.rotate90(); new_image.fliph_in_place(); *image = new_image; Ok(()) } - 6 => Ok(*image = image.rotate90()), - 7 => { + Orientation::Rotate270FlipH => { let mut new_image = image.rotate270(); new_image.fliph_in_place(); *image = new_image; Ok(()) } - 8 => Ok(*image = image.rotate270()), - 0 | 9.. => { - return Err(ImageError::Parameter(ParameterError::from_kind( - ParameterErrorKind::Generic(format!("Invalid exif orientation: {orientation}")), - ))) - } } } diff --git a/src/lib.rs b/src/lib.rs index 72f1109c0c..761d82d533 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -172,6 +172,7 @@ pub use crate::image_reader::{ImageReader, LimitSupport, Limits}; pub use crate::dynimage::DynamicImage; pub use crate::animation::{Delay, Frame, Frames}; +pub use crate::orientation::Orientation; // More detailed error type pub mod error; @@ -289,6 +290,7 @@ mod color; mod dynimage; mod image; mod image_reader; +mod orientation; //TODO delete this module after a few releases /// deprecated io module the original io module has been renamed to `image_reader` pub mod io { diff --git a/src/orientation.rs b/src/orientation.rs new file mode 100644 index 0000000000..80dd85e3c7 --- /dev/null +++ b/src/orientation.rs @@ -0,0 +1,40 @@ +/// Describes the transformations to be applied to the image. +/// Compatible with [Exif orientation](https://web.archive.org/web/20200412005226/https://www.impulseadventure.com/photo/exif-orientation.html). +/// +/// Orientation is specified in the Exif metadata, and is often written by cameras. +#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] +pub enum Orientation { + /// Do not perform any transformations. + NoTransforms, + /// Rotate by 90 degrees clockwise. + Rotate90, + /// Rotate by 180 degrees. Can be performed in-place. + Rotate180, + /// Rotate by 90 degrees clockwise. + Rotate270, + /// Flip horizontally. Can be performed in-place. + FlipH, + /// Flip vertically. Can be performed in-place. + FlipV, + /// Rotate by 90 degrees clockwise and flip horizontally. + Rotate90FlipH, + /// Rotate by 270 degrees clockwise and flip horizontally. + Rotate270FlipH, +} + +impl Orientation { + /// Converts from [Exif orientation](https://web.archive.org/web/20200412005226/https://www.impulseadventure.com/photo/exif-orientation.html) + pub fn from_exif(exif_orientation: u8) -> Option { + match exif_orientation { + 1 => Some(Self::NoTransforms), + 2 => Some(Self::FlipH), + 3 => Some(Self::Rotate180), + 4 => Some(Self::FlipV), + 5 => Some(Self::Rotate90FlipH), + 6 => Some(Self::Rotate90), + 7 => Some(Self::Rotate90FlipH), + 8 => Some(Self::Rotate270), + 0 | 9.. => None, + } + } +} From 91f15b1643a26fb9a8a60048940675856dda8964 Mon Sep 17 00:00:00 2001 From: "Sergey \"Shnatsel\" Davidoff" Date: Mon, 9 Sep 2024 03:20:06 +0100 Subject: [PATCH 07/19] Make newly added in-place transformation functions private --- src/dynimage.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/dynimage.rs b/src/dynimage.rs index 4629dd29d5..f615efa1ff 100644 --- a/src/dynimage.rs +++ b/src/dynimage.rs @@ -879,7 +879,7 @@ impl DynamicImage { } /// Flip this image vertically in place - pub fn flipv_in_place(&mut self) { + fn flipv_in_place(&mut self) { dynamic_map!(*self, ref mut p, imageops::flip_vertical_in_place(p)) } @@ -890,7 +890,7 @@ impl DynamicImage { } /// Flip this image horizontally in place - pub fn fliph_in_place(&mut self) { + fn fliph_in_place(&mut self) { dynamic_map!(*self, ref mut p, imageops::flip_horizontal_in_place(p)) } @@ -907,7 +907,7 @@ impl DynamicImage { } /// Rotate this image 180 degrees in place. - pub fn rotate180_in_place(&mut self) { + fn rotate180_in_place(&mut self) { dynamic_map!(*self, ref mut p, imageops::rotate180_in_place(p)) } From 92d2ec29126fd1768028a4c0f08df4ec51bc4981 Mon Sep 17 00:00:00 2001 From: "Sergey \"Shnatsel\" Davidoff" Date: Mon, 9 Sep 2024 03:22:12 +0100 Subject: [PATCH 08/19] Change doc comment following review comment --- src/dynimage.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dynimage.rs b/src/dynimage.rs index f615efa1ff..139e937f03 100644 --- a/src/dynimage.rs +++ b/src/dynimage.rs @@ -917,7 +917,7 @@ impl DynamicImage { dynamic_map!(*self, ref p => imageops::rotate270(p)) } - /// Applies the specified [Orientation] to the image. + /// Rotates and/or flips the image as indicated by [Orientation]. /// /// Note that for some orientations cannot be efficiently applied in-place. /// In that case this function will make a copy of the image internally. From ecdf8f59602b7a8cd859ad090f781d3e3c20733f Mon Sep 17 00:00:00 2001 From: "Sergey \"Shnatsel\" Davidoff" Date: Mon, 9 Sep 2024 03:24:12 +0100 Subject: [PATCH 09/19] Rename flip orientations to make them more explicit --- src/dynimage.rs | 4 ++-- src/orientation.rs | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/dynimage.rs b/src/dynimage.rs index 139e937f03..b85bf4b0ac 100644 --- a/src/dynimage.rs +++ b/src/dynimage.rs @@ -931,8 +931,8 @@ impl DynamicImage { Orientation::Rotate90 => Ok(*image = image.rotate90()), Orientation::Rotate180 => Ok(image.rotate180_in_place()), Orientation::Rotate270 => Ok(*image = image.rotate270()), - Orientation::FlipH => Ok(image.fliph_in_place()), - Orientation::FlipV => Ok(image.flipv_in_place()), + Orientation::FlipHorizontal => Ok(image.fliph_in_place()), + Orientation::FlipVertical => Ok(image.flipv_in_place()), Orientation::Rotate90FlipH => { let mut new_image = image.rotate90(); new_image.fliph_in_place(); diff --git a/src/orientation.rs b/src/orientation.rs index 80dd85e3c7..a1690e9889 100644 --- a/src/orientation.rs +++ b/src/orientation.rs @@ -13,9 +13,9 @@ pub enum Orientation { /// Rotate by 90 degrees clockwise. Rotate270, /// Flip horizontally. Can be performed in-place. - FlipH, + FlipHorizontal, /// Flip vertically. Can be performed in-place. - FlipV, + FlipVertical, /// Rotate by 90 degrees clockwise and flip horizontally. Rotate90FlipH, /// Rotate by 270 degrees clockwise and flip horizontally. @@ -27,9 +27,9 @@ impl Orientation { pub fn from_exif(exif_orientation: u8) -> Option { match exif_orientation { 1 => Some(Self::NoTransforms), - 2 => Some(Self::FlipH), + 2 => Some(Self::FlipHorizontal), 3 => Some(Self::Rotate180), - 4 => Some(Self::FlipV), + 4 => Some(Self::FlipVertical), 5 => Some(Self::Rotate90FlipH), 6 => Some(Self::Rotate90), 7 => Some(Self::Rotate90FlipH), From fad5aaaff564f035df088557ec5440be36dffa17 Mon Sep 17 00:00:00 2001 From: "Sergey \"Shnatsel\" Davidoff" Date: Mon, 9 Sep 2024 03:28:32 +0100 Subject: [PATCH 10/19] Document apply_orientation as an alternative to non-in-place functions --- src/dynimage.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/dynimage.rs b/src/dynimage.rs index b85bf4b0ac..d3a70387f6 100644 --- a/src/dynimage.rs +++ b/src/dynimage.rs @@ -873,6 +873,8 @@ impl DynamicImage { } /// Flip this image vertically + /// + /// Use [`apply_orientation`] of you want to flip the image in-place instead. #[must_use] pub fn flipv(&self) -> DynamicImage { dynamic_map!(*self, ref p => imageops::flip_vertical(p)) @@ -884,6 +886,8 @@ impl DynamicImage { } /// Flip this image horizontally + /// + /// Use [`apply_orientation`] of you want to flip the image in-place. #[must_use] pub fn fliph(&self) -> DynamicImage { dynamic_map!(*self, ref p => imageops::flip_horizontal(p)) @@ -901,6 +905,8 @@ impl DynamicImage { } /// Rotate this image 180 degrees. + /// + /// Use [`apply_orientation`] of you want to rotate the image in-place. #[must_use] pub fn rotate180(&self) -> DynamicImage { dynamic_map!(*self, ref p => imageops::rotate180(p)) From c3cec8cc1ff4660553bce9b7e2a61237dd6b8264 Mon Sep 17 00:00:00 2001 From: "Sergey \"Shnatsel\" Davidoff" Date: Mon, 9 Sep 2024 03:42:09 +0100 Subject: [PATCH 11/19] Suppress Clippy false positive --- src/dynimage.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/dynimage.rs b/src/dynimage.rs index d3a70387f6..1cb4c0c526 100644 --- a/src/dynimage.rs +++ b/src/dynimage.rs @@ -931,6 +931,7 @@ impl DynamicImage { /// If this matters to you, please see the documentation on the variants of [Orientation] /// to learn which orientations can and cannot be applied without copying. pub fn apply_orientation(&mut self, orientation: Orientation) -> Result<(), ImageError> { + #![allow(clippy::unit_arg)] // false positive, requires multiple lines for no reason let image = self; match orientation { Orientation::NoTransforms => Ok(()), From 873c410b24a29e588e197146458a125cd43364a6 Mon Sep 17 00:00:00 2001 From: "Sergey \"Shnatsel\" Davidoff" Date: Mon, 9 Sep 2024 03:43:49 +0100 Subject: [PATCH 12/19] Link to Clippy lint issue instead of just handwaving --- src/dynimage.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dynimage.rs b/src/dynimage.rs index 1cb4c0c526..526b212761 100644 --- a/src/dynimage.rs +++ b/src/dynimage.rs @@ -931,7 +931,7 @@ impl DynamicImage { /// If this matters to you, please see the documentation on the variants of [Orientation] /// to learn which orientations can and cannot be applied without copying. pub fn apply_orientation(&mut self, orientation: Orientation) -> Result<(), ImageError> { - #![allow(clippy::unit_arg)] // false positive, requires multiple lines for no reason + #![allow(clippy::unit_arg)] // https://github.com/rust-lang/rust-clippy/issues/6521 let image = self; match orientation { Orientation::NoTransforms => Ok(()), From 9d1a694917d67712800e64adfc2356b98bdf7645 Mon Sep 17 00:00:00 2001 From: "Sergey \"Shnatsel\" Davidoff" Date: Mon, 9 Sep 2024 05:50:28 +0100 Subject: [PATCH 13/19] Make apply_orientation infallible now that it accepts an enum --- src/dynimage.rs | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/src/dynimage.rs b/src/dynimage.rs index 526b212761..30fd9d761d 100644 --- a/src/dynimage.rs +++ b/src/dynimage.rs @@ -930,27 +930,24 @@ impl DynamicImage { /// /// If this matters to you, please see the documentation on the variants of [Orientation] /// to learn which orientations can and cannot be applied without copying. - pub fn apply_orientation(&mut self, orientation: Orientation) -> Result<(), ImageError> { - #![allow(clippy::unit_arg)] // https://github.com/rust-lang/rust-clippy/issues/6521 + pub fn apply_orientation(&mut self, orientation: Orientation) { let image = self; match orientation { - Orientation::NoTransforms => Ok(()), - Orientation::Rotate90 => Ok(*image = image.rotate90()), - Orientation::Rotate180 => Ok(image.rotate180_in_place()), - Orientation::Rotate270 => Ok(*image = image.rotate270()), - Orientation::FlipHorizontal => Ok(image.fliph_in_place()), - Orientation::FlipVertical => Ok(image.flipv_in_place()), + Orientation::NoTransforms => (), + Orientation::Rotate90 => *image = image.rotate90(), + Orientation::Rotate180 => image.rotate180_in_place(), + Orientation::Rotate270 => *image = image.rotate270(), + Orientation::FlipHorizontal => image.fliph_in_place(), + Orientation::FlipVertical => image.flipv_in_place(), Orientation::Rotate90FlipH => { let mut new_image = image.rotate90(); new_image.fliph_in_place(); *image = new_image; - Ok(()) } Orientation::Rotate270FlipH => { let mut new_image = image.rotate270(); new_image.fliph_in_place(); *image = new_image; - Ok(()) } } } From 25bd5ebaf80e843bfaa84cfebe26a3fb7bb4ce93 Mon Sep 17 00:00:00 2001 From: "Sergey \"Shnatsel\" Davidoff" Date: Thu, 12 Sep 2024 10:41:13 +0100 Subject: [PATCH 14/19] Fix incorrect doc comment --- src/orientation.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/orientation.rs b/src/orientation.rs index a1690e9889..c1b8af4f42 100644 --- a/src/orientation.rs +++ b/src/orientation.rs @@ -10,7 +10,7 @@ pub enum Orientation { Rotate90, /// Rotate by 180 degrees. Can be performed in-place. Rotate180, - /// Rotate by 90 degrees clockwise. + /// Rotate by 270 degrees clockwise. Equivalent to rotating by 90 degrees counter-clockwise. Rotate270, /// Flip horizontally. Can be performed in-place. FlipHorizontal, From b4cb2d6e0951b8724c1e7dda7aac1d8f507fcb47 Mon Sep 17 00:00:00 2001 From: "Sergey \"Shnatsel\" Davidoff" Date: Fri, 13 Sep 2024 06:48:17 +0100 Subject: [PATCH 15/19] Fix erroneous exif conversion for value 7 --- src/orientation.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/orientation.rs b/src/orientation.rs index c1b8af4f42..37399e47c8 100644 --- a/src/orientation.rs +++ b/src/orientation.rs @@ -32,9 +32,10 @@ impl Orientation { 4 => Some(Self::FlipVertical), 5 => Some(Self::Rotate90FlipH), 6 => Some(Self::Rotate90), - 7 => Some(Self::Rotate90FlipH), + 7 => Some(Self::Rotate270FlipH), 8 => Some(Self::Rotate270), 0 | 9.. => None, } } + } From 9c0d517dabd856761460bf1721a4a1e96e58fec7 Mon Sep 17 00:00:00 2001 From: "Sergey \"Shnatsel\" Davidoff" Date: Fri, 13 Sep 2024 06:49:56 +0100 Subject: [PATCH 16/19] Add a function to convert from Orientation to Exif values --- src/orientation.rs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/orientation.rs b/src/orientation.rs index 37399e47c8..f2e2493b33 100644 --- a/src/orientation.rs +++ b/src/orientation.rs @@ -38,4 +38,17 @@ impl Orientation { } } + /// Converts into [Exif orientation](https://web.archive.org/web/20200412005226/https://www.impulseadventure.com/photo/exif-orientation.html) + pub fn to_exif(self) -> u8 { + match self { + Self::NoTransforms => 1, + Self::FlipHorizontal => 2, + Self::Rotate180 => 3, + Self::FlipVertical => 4, + Self::Rotate90FlipH => 5, + Self::Rotate90 => 6, + Self::Rotate270FlipH => 7, + Self::Rotate270 => 8, + } + } } From 005844dd862e252f17e39be6fcb7a63bcf7cef09 Mon Sep 17 00:00:00 2001 From: "Sergey \"Shnatsel\" Davidoff" Date: Fri, 13 Sep 2024 06:56:20 +0100 Subject: [PATCH 17/19] Rename the module with `Orientation` struct to `metadata` --- src/lib.rs | 4 ++-- src/{orientation.rs => metadata.rs} | 0 2 files changed, 2 insertions(+), 2 deletions(-) rename src/{orientation.rs => metadata.rs} (100%) diff --git a/src/lib.rs b/src/lib.rs index d3862fb7e0..0d6a6cb497 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -172,7 +172,7 @@ pub use crate::image_reader::{ImageReader, LimitSupport, Limits}; pub use crate::dynimage::DynamicImage; pub use crate::animation::{Delay, Frame, Frames}; -pub use crate::orientation::Orientation; +pub use crate::metadata::Orientation; // More detailed error type pub mod error; @@ -290,7 +290,7 @@ mod color; mod dynimage; mod image; mod image_reader; -mod orientation; +mod metadata; //TODO delete this module after a few releases /// deprecated io module the original io module has been renamed to `image_reader` pub mod io { diff --git a/src/orientation.rs b/src/metadata.rs similarity index 100% rename from src/orientation.rs rename to src/metadata.rs From c461e99b5cf6810080b8b9ba9224a7f4ac863df8 Mon Sep 17 00:00:00 2001 From: "Sergey \"Shnatsel\" Davidoff" Date: Fri, 13 Sep 2024 07:04:21 +0100 Subject: [PATCH 18/19] Fix doclinks --- src/dynimage.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/dynimage.rs b/src/dynimage.rs index 30fd9d761d..923eb1f0c7 100644 --- a/src/dynimage.rs +++ b/src/dynimage.rs @@ -874,7 +874,7 @@ impl DynamicImage { /// Flip this image vertically /// - /// Use [`apply_orientation`] of you want to flip the image in-place instead. + /// Use [`apply_orientation`](Self::apply_orientation) of you want to flip the image in-place instead. #[must_use] pub fn flipv(&self) -> DynamicImage { dynamic_map!(*self, ref p => imageops::flip_vertical(p)) @@ -887,7 +887,7 @@ impl DynamicImage { /// Flip this image horizontally /// - /// Use [`apply_orientation`] of you want to flip the image in-place. + /// Use [`apply_orientation`](Self::apply_orientation) of you want to flip the image in-place. #[must_use] pub fn fliph(&self) -> DynamicImage { dynamic_map!(*self, ref p => imageops::flip_horizontal(p)) @@ -906,7 +906,7 @@ impl DynamicImage { /// Rotate this image 180 degrees. /// - /// Use [`apply_orientation`] of you want to rotate the image in-place. + /// Use [`apply_orientation`](Self::apply_orientation) of you want to rotate the image in-place. #[must_use] pub fn rotate180(&self) -> DynamicImage { dynamic_map!(*self, ref p => imageops::rotate180(p)) From 6dad395b28bfeb5c51be7ebb13de45f3f2181a04 Mon Sep 17 00:00:00 2001 From: "Sergey \"Shnatsel\" Davidoff" Date: Fri, 13 Sep 2024 07:05:48 +0100 Subject: [PATCH 19/19] Link from Orientation struct to the function that applies it --- src/metadata.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/metadata.rs b/src/metadata.rs index f2e2493b33..f5453d7b4b 100644 --- a/src/metadata.rs +++ b/src/metadata.rs @@ -2,6 +2,8 @@ /// Compatible with [Exif orientation](https://web.archive.org/web/20200412005226/https://www.impulseadventure.com/photo/exif-orientation.html). /// /// Orientation is specified in the Exif metadata, and is often written by cameras. +/// +/// You can apply it to an image via [`DynamicImage::apply_orientation`](crate::DynamicImage::apply_orientation). #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] pub enum Orientation { /// Do not perform any transformations.