diff options
Diffstat (limited to 'dichroism/src/models/photo_set.rs')
-rw-r--r-- | dichroism/src/models/photo_set.rs | 72 |
1 files changed, 66 insertions, 6 deletions
diff --git a/dichroism/src/models/photo_set.rs b/dichroism/src/models/photo_set.rs index 2f6c128..84fe0e1 100644 --- a/dichroism/src/models/photo_set.rs +++ b/dichroism/src/models/photo_set.rs @@ -1,8 +1,68 @@ -#[derive(Debug, Queryable, Clone)] +use super::photo::Photo; +use crate::constants::{PHOTO_BASE_XY, PHOTO_FULLSIZE_XY, PHOTO_THUMBNAIL_XY}; +use crate::error::DichroismError; +use crate::result::Result; +use base64::decode; +use image::imageops::FilterType; +use image::GenericImageView; +use once_cell::sync::Lazy; +use regex::Regex; + +static DATA_URI_RE: Lazy<Regex> = Lazy::new(|| { + Regex::new("^data:image/(png|jpeg);base64,(?P<data>.+)") + .expect("Couldn't parse data URI Regex.") +}); + pub struct PhotoSet { - pub id: i32, - pub base: i32, - pub fullsize: i32, - pub thumbnail: i32, - pub original: i32, + pub original: Photo, // original, just for safe-keeping + pub fullsize: Photo, // full-size, "zoomed" view + pub base: Photo, // basic viewing + pub thumbnail: Photo, // tiny, square thumbnail +} + +impl PhotoSet { + pub fn from_data_uri(uri: &str) -> Result<Self> { + let data = DATA_URI_RE + .captures(uri) + .ok_or(DichroismError::UriDataExtract)? + .name("data") + .ok_or(DichroismError::UriDataExtract)? + .as_str(); + let original = image::load_from_memory(&decode(data)?)?; + let fullsize = original.resize(PHOTO_FULLSIZE_XY, PHOTO_FULLSIZE_XY, FilterType::Lanczos3); + let base = original.resize(PHOTO_BASE_XY, PHOTO_BASE_XY, FilterType::Lanczos3); + + let (width, height) = original.dimensions(); + let thumbnail = if width > height { + let offset = (width - height) / 2; + original.crop_imm(offset, 0, width - offset * 2, height) + } else { + let offset = (height - width) / 2; + original.crop_imm(0, offset, width, height - offset * 2) + } + .resize(PHOTO_THUMBNAIL_XY, PHOTO_THUMBNAIL_XY, FilterType::Lanczos3); + + Ok(Self { + original: Photo::from_image(&original)?, + fullsize: Photo::from_image(&fullsize)?, + base: Photo::from_image(&base)?, + thumbnail: Photo::from_image(&thumbnail)?, + }) + } +} + +#[cfg(test)] +mod tests { + //use super::*; + + const TEST_DATA_URI: &str = include_str!("../unit_test_data/img_data_uri.txt"); + const TEST_DATA_BASE64: &str = include_str!("../unit_test_data/test_data_base64.txt"); + + #[test] + fn test_gen_product_images() { + // PhotoSet::from_data_uri(TEST_DATA_URI.trim()) + // .unwrap() + // .commit(".") + // .unwrap(); + } } |