2022-08-12 00:00:13 +00:00
|
|
|
use std::io::Cursor;
|
2022-08-14 21:05:12 +00:00
|
|
|
use image::{io::Reader, DynamicImage, ImageResult, ImageFormat};
|
2022-08-12 00:00:13 +00:00
|
|
|
use webp::{Encoder, WebPMemory};
|
|
|
|
|
2022-08-14 21:05:12 +00:00
|
|
|
use crate::protobuf::image::Format;
|
|
|
|
|
2022-11-09 22:45:21 +00:00
|
|
|
pub fn thumbnail(bytes: &[u8]) -> ImageResult<(Option<WebPMemory>, u32, u32, WebPMemory, String, Format)> {
|
2022-08-14 21:05:12 +00:00
|
|
|
let original_image_encoded = Reader::new(Cursor::new(bytes))
|
|
|
|
.with_guessed_format().expect("IO errors impossible with Cursor");
|
|
|
|
let original_format = original_image_encoded.format();
|
|
|
|
let original_image = original_image_encoded.decode()?;
|
|
|
|
|
2022-08-12 00:00:13 +00:00
|
|
|
let new_dimm = u32::min(original_image.height(), original_image.width());
|
|
|
|
let crop_x = (original_image.width() - new_dimm) / 2;
|
|
|
|
let crop_y = (original_image.height() - new_dimm) / 2;
|
|
|
|
let cropped = original_image.crop_imm(crop_x, crop_y, new_dimm, new_dimm);
|
|
|
|
let scaled = if new_dimm < 400 {
|
|
|
|
cropped
|
|
|
|
} else {
|
2022-11-09 22:51:49 +00:00
|
|
|
cropped.thumbnail_exact(400, 400)
|
2022-08-12 00:00:13 +00:00
|
|
|
}.into_rgba8();
|
2022-08-14 21:05:12 +00:00
|
|
|
let scale = scaled.width();
|
|
|
|
|
|
|
|
let blurhash = blurhash::encode(4, 4, scale, scale, scaled.as_raw());
|
|
|
|
|
|
|
|
let (recoded_original, format) = match original_format {
|
|
|
|
Some(ImageFormat::WebP) => (None, Format::WEBP),
|
|
|
|
Some(ImageFormat::Avif) => (None, Format::AVIF),
|
|
|
|
Some(ImageFormat::Jpeg) => (None, Format::JPG),
|
|
|
|
Some(ImageFormat::Png) => (None, Format::PNG),
|
|
|
|
Some(ImageFormat::Gif) => (None, Format::GIF),
|
|
|
|
_ => ( // Unrecognized or format which isn't spec-supported
|
|
|
|
Some(
|
|
|
|
Encoder::from_image(&original_image)
|
|
|
|
.expect("Error transcoding image as webp")
|
|
|
|
.encode_lossless(),
|
|
|
|
),
|
|
|
|
Format::WEBP
|
|
|
|
)
|
|
|
|
};
|
|
|
|
|
2022-08-12 00:00:13 +00:00
|
|
|
Ok((
|
2022-08-14 21:05:12 +00:00
|
|
|
recoded_original,
|
2022-11-09 22:45:21 +00:00
|
|
|
original_image.width(),
|
|
|
|
original_image.height(),
|
2022-08-12 00:00:13 +00:00
|
|
|
Encoder::from_image(&DynamicImage::ImageRgba8(scaled))
|
|
|
|
.expect("Unexpected difficulty interpretting thumbnail")
|
|
|
|
.encode(50.0),
|
2022-08-14 21:05:12 +00:00
|
|
|
blurhash,
|
|
|
|
format,
|
2022-08-12 00:00:13 +00:00
|
|
|
))
|
|
|
|
}
|