diff options
Diffstat (limited to 'dichroism')
-rw-r--r-- | dichroism/Cargo.lock | 16 | ||||
-rw-r--r-- | dichroism/Cargo.toml | 1 | ||||
-rw-r--r-- | dichroism/src/handlers.rs | 2 | ||||
-rw-r--r-- | dichroism/src/image_service.rs | 26 |
4 files changed, 42 insertions, 3 deletions
diff --git a/dichroism/Cargo.lock b/dichroism/Cargo.lock index 1fe4b81..f08e9a4 100644 --- a/dichroism/Cargo.lock +++ b/dichroism/Cargo.lock @@ -761,6 +761,7 @@ dependencies = [ "env_logger", "futures", "image", + "kamadak-exif", "listenfd", "log", "mime", @@ -1246,6 +1247,15 @@ dependencies = [ ] [[package]] +name = "kamadak-exif" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "524f22a6373f7d4f4e7caa44d54efbaf1e92c09d41f38647db2784ebce610aa8" +dependencies = [ + "mutate_once", +] + +[[package]] name = "kernel32-sys" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1449,6 +1459,12 @@ dependencies = [ ] [[package]] +name = "mutate_once" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16cf681a23b4d0a43fc35024c176437f9dcd818db34e0f42ab456a0ee5ad497b" + +[[package]] name = "nb-connect" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" diff --git a/dichroism/Cargo.toml b/dichroism/Cargo.toml index 22b8a42..bacd843 100644 --- a/dichroism/Cargo.toml +++ b/dichroism/Cargo.toml @@ -14,6 +14,7 @@ diesel = { version = "1", features = [ "sqlite", "r2d2" ] } env_logger = "0.8" futures = "0.3" image = "0.23" +kamadak-exif = "0.5.2" listenfd = "0.3" log = "0.4" mime = "0.3" diff --git a/dichroism/src/handlers.rs b/dichroism/src/handlers.rs index 8dd0f3b..b9420af 100644 --- a/dichroism/src/handlers.rs +++ b/dichroism/src/handlers.rs @@ -117,7 +117,7 @@ async fn post_photo( } // create new photo_set - let photo_set = web::block(move || image_service::generate_photo_set(&data)) + let photo_set = web::block(move || image_service::generate_photo_set(data)) .await .map_err(to_internal_error)?; let conn = pool.get().map_err(to_internal_error)?; diff --git a/dichroism/src/image_service.rs b/dichroism/src/image_service.rs index a69cca2..0d2ed14 100644 --- a/dichroism/src/image_service.rs +++ b/dichroism/src/image_service.rs @@ -2,14 +2,36 @@ use crate::config::CONFIG_INSTANCE; use crate::constants::{PHOTO_BASE_XY, PHOTO_FULLSIZE_XY, PHOTO_THUMBNAIL_XY}; use crate::error::DichroismError; use crate::models::{Photo, PhotoSet}; +use exif::Reader; use image::imageops::FilterType; use image::DynamicImage; use image::GenericImageView; +use std::io::{BufReader, Cursor}; use std::path::PathBuf; use uuid::Uuid; -pub fn generate_photo_set(data: &[u8]) -> Result<PhotoSet, DichroismError> { - let original = image::load_from_memory(&data)?; +pub fn generate_photo_set(data: Vec<u8>) -> Result<PhotoSet, DichroismError> { + // load image data from bytes + let mut original = image::load_from_memory(&data)?; + + // read EXIF tags to check for required rotation + let exifreader = Reader::new(); + let mut reader = BufReader::new(Cursor::new(data)); + let exif = exifreader.read_from_container(&mut reader).unwrap(); + if let Some(orient) = exif + .get_field(exif::Tag::Orientation, exif::In::PRIMARY) + .map(|o| o.value.get_uint(0)) + .flatten() + { + // if a tag was present, rotate original image data as necessary + match orient { + 8 => original = original.rotate270(), + 3 => original = original.rotate180(), + 6 => original = original.rotate90(), + _ => {} + } + } + let fullsize = original.resize(PHOTO_FULLSIZE_XY, PHOTO_FULLSIZE_XY, FilterType::Lanczos3); let base = original.resize(PHOTO_BASE_XY, PHOTO_BASE_XY, FilterType::Lanczos3); |