Read EXIF in JPEG for resize
This commit is contained in:
parent
2114a02fcb
commit
f9aab1ef78
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "libcaesium"
|
name = "libcaesium"
|
||||||
version = "0.16.3"
|
version = "0.16.4"
|
||||||
authors = ["Matteo Paonessa <matteo.paonessa@gmail.com>"]
|
authors = ["Matteo Paonessa <matteo.paonessa@gmail.com>"]
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
categories = ["multimedia::images"]
|
categories = ["multimedia::images"]
|
||||||
|
|
|
@ -7,7 +7,7 @@ use img_parts::{DynImage, ImageEXIF, ImageICC};
|
||||||
|
|
||||||
use crate::{compress_in_memory, CSParameters, SupportedFileTypes};
|
use crate::{compress_in_memory, CSParameters, SupportedFileTypes};
|
||||||
use crate::error::CaesiumError;
|
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<u8>, format: SupportedFileTypes, parameters: &CSParameters) -> Result<Vec<u8>, CaesiumError> {
|
pub fn convert_in_memory(in_file: Vec<u8>, format: SupportedFileTypes, parameters: &CSParameters) -> Result<Vec<u8>, CaesiumError> {
|
||||||
let mut iccp = None;
|
let mut iccp = None;
|
||||||
|
@ -128,20 +128,3 @@ fn map_image_format(format: SupportedFileTypes) -> Result<ImageFormat, CaesiumEr
|
||||||
|
|
||||||
Ok(image_format)
|
Ok(image_format)
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
use std::io::Cursor;
|
use std::io::Cursor;
|
||||||
|
|
||||||
use image::DynamicImage;
|
|
||||||
use image::imageops::FilterType;
|
use image::imageops::FilterType;
|
||||||
use image::io::Reader as ImageReader;
|
use image::io::Reader as ImageReader;
|
||||||
|
use image::DynamicImage;
|
||||||
|
|
||||||
use crate::error::CaesiumError;
|
use crate::error::CaesiumError;
|
||||||
|
use crate::utils::get_jpeg_orientation;
|
||||||
|
|
||||||
pub fn resize(
|
pub fn resize(
|
||||||
image_buffer: Vec<u8>,
|
image_buffer: Vec<u8>,
|
||||||
|
@ -12,7 +13,15 @@ pub fn resize(
|
||||||
height: u32,
|
height: u32,
|
||||||
format: image::ImageFormat,
|
format: image::ImageFormat,
|
||||||
) -> Result<Vec<u8>, CaesiumError> {
|
) -> Result<Vec<u8>, 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()
|
.with_guessed_format()
|
||||||
.map_err(|e| CaesiumError {
|
.map_err(|e| CaesiumError {
|
||||||
message: e.to_string(),
|
message: e.to_string(),
|
||||||
|
@ -24,7 +33,7 @@ pub fn resize(
|
||||||
code: 10301,
|
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);
|
image = image.resize_exact(dimensions.0, dimensions.1, FilterType::Lanczos3);
|
||||||
|
|
||||||
let mut resized_file: Vec<u8> = vec![];
|
let mut resized_file: Vec<u8> = vec![];
|
||||||
|
|
19
src/utils.rs
19
src/utils.rs
|
@ -1,3 +1,4 @@
|
||||||
|
use std::io::Cursor;
|
||||||
use infer::Type;
|
use infer::Type;
|
||||||
use crate::SupportedFileTypes;
|
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 {
|
fn match_supported_filetypes(ft: Type) -> SupportedFileTypes {
|
||||||
match ft.mime_type() {
|
match ft.mime_type() {
|
||||||
"image/jpeg" => SupportedFileTypes::Jpeg,
|
"image/jpeg" => SupportedFileTypes::Jpeg,
|
||||||
|
|
Loading…
Reference in New Issue