From f9aab1ef784c9b781ad39a7114ebacb2e3ab4471 Mon Sep 17 00:00:00 2001 From: Matteo Paonessa Date: Sat, 10 Aug 2024 17:56:40 +0200 Subject: [PATCH] Read EXIF in JPEG for resize --- Cargo.toml | 2 +- src/convert.rs | 21 ++------------------- src/resize.rs | 15 ++++++++++++--- src/utils.rs | 19 +++++++++++++++++++ 4 files changed, 34 insertions(+), 23 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index d0c22a2..51fca3d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "libcaesium" -version = "0.16.3" +version = "0.16.4" authors = ["Matteo Paonessa "] edition = "2021" categories = ["multimedia::images"] diff --git a/src/convert.rs b/src/convert.rs index 1a2c427..a26ceb5 100644 --- a/src/convert.rs +++ b/src/convert.rs @@ -7,7 +7,7 @@ use img_parts::{DynImage, ImageEXIF, ImageICC}; use crate::{compress_in_memory, CSParameters, SupportedFileTypes}; use crate::error::CaesiumError; -use crate::utils::get_filetype_from_memory; +use crate::utils::{get_filetype_from_memory, get_jpeg_orientation}; pub fn convert_in_memory(in_file: Vec, format: SupportedFileTypes, parameters: &CSParameters) -> Result, CaesiumError> { let mut iccp = None; @@ -127,21 +127,4 @@ fn map_image_format(format: SupportedFileTypes) -> Result u32 { - let reader = exif::Reader::new(); - let mut cursor = Cursor::new(data); - - let exif_data = match reader.read_from_container(&mut cursor) { - Ok(v) => v, - Err(_) => return 1 - }; - - let exif_field = match exif_data.get_field(exif::Tag::Orientation, exif::In::PRIMARY) { - Some(value) => value, - None => return 1, - }; - - exif_field.value.get_uint(0).unwrap_or(1) -} +} \ No newline at end of file diff --git a/src/resize.rs b/src/resize.rs index dcb125d..26e5015 100644 --- a/src/resize.rs +++ b/src/resize.rs @@ -1,10 +1,11 @@ use std::io::Cursor; -use image::DynamicImage; use image::imageops::FilterType; use image::io::Reader as ImageReader; +use image::DynamicImage; use crate::error::CaesiumError; +use crate::utils::get_jpeg_orientation; pub fn resize( image_buffer: Vec, @@ -12,7 +13,15 @@ pub fn resize( height: u32, format: image::ImageFormat, ) -> Result, CaesiumError> { - let mut image = ImageReader::new(Cursor::new(image_buffer)) + let buffer_slice = image_buffer.as_slice(); + let (mut desired_width, mut desired_height) = (width, height); + if format == image::ImageFormat::Jpeg { + let orientation = get_jpeg_orientation(buffer_slice); + (desired_width, desired_height) = match orientation { + 5..=8 => (height, width), + _ => (width, height) + }; + }let mut image = ImageReader::new(Cursor::new(image_buffer)) .with_guessed_format() .map_err(|e| CaesiumError { message: e.to_string(), @@ -24,7 +33,7 @@ pub fn resize( code: 10301, })?; - let dimensions = compute_dimensions(image.width(), image.height(), width, height); + let dimensions = compute_dimensions(image.width(), image.height(), desired_width, desired_height); image = image.resize_exact(dimensions.0, dimensions.1, FilterType::Lanczos3); let mut resized_file: Vec = vec![]; diff --git a/src/utils.rs b/src/utils.rs index c51ec26..c590b37 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -1,3 +1,4 @@ +use std::io::Cursor; use infer::Type; use crate::SupportedFileTypes; @@ -18,6 +19,24 @@ pub fn get_filetype_from_memory(buf: &[u8]) -> SupportedFileTypes { } } +pub fn get_jpeg_orientation(data: &[u8]) -> u32 { + let reader = exif::Reader::new(); + let mut cursor = Cursor::new(data); + + let exif_data = match reader.read_from_container(&mut cursor) { + Ok(v) => v, + Err(_) => return 1 + }; + + let exif_field = match exif_data.get_field(exif::Tag::Orientation, exif::In::PRIMARY) { + Some(value) => value, + None => return 1, + }; + + exif_field.value.get_uint(0).unwrap_or(1) +} + + fn match_supported_filetypes(ft: Type) -> SupportedFileTypes { match ft.mime_type() { "image/jpeg" => SupportedFileTypes::Jpeg,