2022-01-28 14:21:07 +01:00
|
|
|
#[cfg(not(feature = "previews-image"))]
|
|
|
|
use anyhow::anyhow;
|
2022-01-24 17:04:27 +01:00
|
|
|
#[cfg(feature = "previews-image")]
|
|
|
|
use image::{io::Reader as ImageReader, GenericImageView};
|
2022-09-18 13:10:01 +02:00
|
|
|
use std::{cmp, collections::HashMap, path::Path};
|
2022-01-24 17:04:27 +01:00
|
|
|
|
|
|
|
use anyhow::Result;
|
|
|
|
|
|
|
|
use super::Previewable;
|
|
|
|
|
|
|
|
pub struct ImagePath<'a>(pub &'a Path);
|
|
|
|
|
|
|
|
impl<'a> Previewable for ImagePath<'a> {
|
2022-09-18 13:10:01 +02:00
|
|
|
fn get_thumbnail(&self, options: HashMap<String, String>) -> Result<Option<Vec<u8>>> {
|
2022-01-24 17:04:27 +01:00
|
|
|
#[cfg(feature = "previews-image")]
|
|
|
|
{
|
2023-03-19 20:10:13 +01:00
|
|
|
let file = std::fs::File::open(self.0)?;
|
2022-03-16 11:30:06 +01:00
|
|
|
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());
|
|
|
|
|
2024-01-17 23:37:47 +01:00
|
|
|
let image = ImageReader::open(self.0)?.with_guessed_format()?.decode()?;
|
2022-03-16 11:30:06 +01:00
|
|
|
let image = match orientation {
|
|
|
|
Some(3) => image.rotate180(),
|
|
|
|
Some(6) => image.rotate90(),
|
|
|
|
Some(8) => image.rotate270(),
|
2022-04-15 22:43:40 +02:00
|
|
|
_ => image,
|
2022-03-16 11:30:06 +01:00
|
|
|
};
|
2022-09-18 13:10:01 +02:00
|
|
|
|
2022-01-24 17:04:27 +01:00
|
|
|
let (w, h) = image.dimensions();
|
2022-09-18 13:10:01 +02:00
|
|
|
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);
|
2022-01-24 18:26:53 +01:00
|
|
|
let thumbnail = thumbnail.into_rgba8();
|
|
|
|
let (w, h) = thumbnail.dimensions();
|
|
|
|
let encoder = webp::Encoder::from_rgba(&thumbnail, w, h);
|
2022-09-18 13:10:01 +02:00
|
|
|
let result = encoder.encode(quality);
|
2022-01-24 18:26:53 +01:00
|
|
|
Ok(Some(result.to_vec()))
|
2022-01-24 17:04:27 +01:00
|
|
|
} else {
|
2022-01-24 18:26:53 +01:00
|
|
|
Ok(None)
|
|
|
|
}
|
2022-01-24 17:04:27 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(not(feature = "previews-image"))]
|
|
|
|
Err(anyhow!("Image preview support not enabled!"))
|
|
|
|
}
|
|
|
|
}
|