Newer
Older
use std::{io::Cursor, path::Path};
use anyhow::{bail, Context};
use image::{io::Reader as ImageReader, DynamicImage, ImageOutputFormat};
use crate::{
load::Loadable,
resp::{Expiry, Response},
util::slugify,
};
pub struct MyImage {
original: DynamicImage,
thumbnail: DynamicImage,
format: ImageOutputFormat,
original_url: String,
thumbnail_url: String,
}
impl MyImage {
// (original, thumbnail)
pub fn into_responses(self) -> anyhow::Result<(String, Response, String, Response)> {
let content_type = format_to_content_type(&self.format)?;
let mut original = vec![];
self.original
.write_to(&mut Cursor::new(&mut original), self.format.clone())?;
let mut thumbnail = vec![];
self.thumbnail
.write_to(&mut Cursor::new(&mut thumbnail), self.format)?;
Ok((
self.original_url,
Response {
content_type,
data: original,
},
self.thumbnail_url,
Response {
content_type,
data: thumbnail,
},
))
}
}
impl Loadable for MyImage {
fn load(_: &Path, path: &Path, slug_prefix: &str) -> anyhow::Result<MyImage> {
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
let file_name = path
.file_name()
.context("Could not get file name")?
.to_str()
.context("Could not convert filename into string")?
.to_owned();
let original_url = slugify(&format!("/img/{slug_prefix}/{file_name}"));
let thumbnail_url = slugify(&format!("/thumb/{slug_prefix}/{file_name}"));
let reader = ImageReader::open(path)?;
let format = reader
.format()
.context("Could not determine image format")?
.into();
let original = reader.decode()?;
let thumbnail = original.thumbnail(400, 800);
Ok(Self {
original,
thumbnail,
format,
original_url,
thumbnail_url,
})
}
}
fn format_to_content_type(f: &ImageOutputFormat) -> anyhow::Result<&'static str> {
let s = match f {
ImageOutputFormat::Png => "image/png",
ImageOutputFormat::Jpeg(_) => "image/jpg",
ImageOutputFormat::Bmp => "image/bmp",
ImageOutputFormat::Gif => "image/gif",
ImageOutputFormat::Ico => "image/x-icon",
_ => bail!("Invalid content type {:?}", f),
};
Ok(s)
}