#[cfg(not(feature = "previews-image"))] use anyhow::anyhow; #[cfg(feature = "previews-image")] use image::{io::Reader as ImageReader, GenericImageView}; use std::{cmp, collections::HashMap, path::Path}; use anyhow::Result; use super::Previewable; pub struct ImagePath<'a>(pub &'a Path); impl<'a> Previewable for ImagePath<'a> { fn get_thumbnail(&self, options: HashMap) -> Result>> { #[cfg(feature = "previews-image")] { let file = std::fs::File::open(&self.0)?; let mut bufreader = std::io::BufReader::new(&file); let exifreader = exif::Reader::new(); let orientation = exifreader .read_from_container(&mut bufreader) .ok() .and_then(|exif| { exif.get_field(exif::Tag::Orientation, exif::In::PRIMARY) .and_then(|f| match &f.value { exif::Value::Short(shorts) => Some(shorts.clone()), _ => None, }) }) .and_then(|shorts| shorts.first().cloned()); let image = ImageReader::open(&self.0)?.decode()?; let image = match orientation { Some(3) => image.rotate180(), Some(6) => image.rotate90(), Some(8) => image.rotate270(), _ => image, }; let (w, h) = image.dimensions(); let max_dimension = { if let Some(str_size) = options.get("size") { str_size.parse()? } else { 1024 } }; let quality = { if let Some(str_quality) = options.get("quality") { str_quality.parse()? } else { 90.0 } }; if cmp::max(w, h) > max_dimension { let thumbnail = image.thumbnail(max_dimension, max_dimension); let thumbnail = thumbnail.into_rgba8(); let (w, h) = thumbnail.dimensions(); let encoder = webp::Encoder::from_rgba(&thumbnail, w, h); let result = encoder.encode(quality); Ok(Some(result.to_vec())) } else { Ok(None) } } #[cfg(not(feature = "previews-image"))] Err(anyhow!("Image preview support not enabled!")) } }