diff --git a/src/img.rs b/src/img.rs index 16efd830858088cb19e377444beed42e38545ae7..bada3c323207243eaed7aceb75df83b12899a706 100644 --- a/src/img.rs +++ b/src/img.rs @@ -1,5 +1,5 @@ use image::{imageops::FilterType, io::Reader as ImageReader, ImageOutputFormat}; -use std::{fs, io::Cursor, path::PathBuf, sync::mpsc::Receiver}; +use std::{cmp::max, fs, io::Cursor, path::PathBuf, sync::mpsc::Receiver}; const IMG_DIM: u32 = 1024; const IMG_MAX_SIZE: u32 = 2048; @@ -20,8 +20,13 @@ impl ImgInfo { // want a imagine that's 512 on one side // resize so that the larger dimension is 512 - // TODO make this better. needs to be smaller than IMG_DIM but still % 16 on both sides - let img = img.resize(IMG_DIM, IMG_DIM, FilterType::Triangle); + let (mut w, mut h) = resize_dimensions(img.width(), img.height(), IMG_DIM, IMG_DIM, false); + + // make both dimensions divisible by 16 (SSDV requirement) + w -= w % 16; + h -= h % 16; + + let img = img.resize_exact(w, h, FilterType::Triangle); let mut bytes = vec![]; @@ -210,3 +215,28 @@ impl ImgManager { Ok(()) } } + +// shamelessly stolen from the image crate +fn resize_dimensions(width: u32, height: u32, nwidth: u32, nheight: u32, fill: bool) -> (u32, u32) { + let wratio = nwidth as f64 / width as f64; + let hratio = nheight as f64 / height as f64; + + let ratio = if fill { + f64::max(wratio, hratio) + } else { + f64::min(wratio, hratio) + }; + + let nw = max((width as f64 * ratio).round() as u64, 1); + let nh = max((height as f64 * ratio).round() as u64, 1); + + if nw > u64::from(u32::MAX) { + let ratio = u32::MAX as f64 / width as f64; + (u32::MAX, max((height as f64 * ratio).round() as u32, 1)) + } else if nh > u64::from(u32::MAX) { + let ratio = u32::MAX as f64 / height as f64; + (max((width as f64 * ratio).round() as u32, 1), u32::MAX) + } else { + (nw as u32, nh as u32) + } +}