html5_picture/utils/
resized_image_details.rs

1use std::path::PathBuf;
2/// Contains the determined image details required for conversion.
3#[derive(Debug)]
4pub struct ResizedImageDetails {
5    pub output_file_name: PathBuf,
6    pub width: u32,
7    pub height: u32,
8}
9
10impl ResizedImageDetails {
11    /// Creates a new instance.
12    pub fn new(output_file_name: PathBuf, width: u32, height: u32) -> Self {
13        Self {
14            output_file_name,
15            width,
16            height,
17        }
18    }
19
20    /// Calculates height, width and output file names for the scaled images.
21    pub fn from(
22        image_file_name: &PathBuf,
23        scaled_images_count: u8,
24    ) -> Result<Vec<ResizedImageDetails>, String> {
25        // get image dimensions
26        let (w, _) = match image::image_dimensions(&image_file_name) {
27            Err(msg) => return Err(msg.to_string()),
28            Ok((w, h)) => (w, h),
29        };
30        // calculate a step in pixel that is used to calculate the new width
31        let step = w as f32 / (scaled_images_count as f32 + 1.0);
32        let mut resized_details = vec![];
33        for idx in 0..scaled_images_count {
34            let new_width = (idx + 1) as f32 * step;
35            let new_width = math::round::ceil(new_width.into(), 0) as u32;
36            let new_height =
37                crate::utils::imageops::calculate_height_preserve_aspect_ratio(
38                    &image_file_name,
39                    new_width,
40                )?;
41            let output_file_name =
42                Self::get_resized_file_name(&image_file_name, new_width)?;
43            resized_details.push(ResizedImageDetails::new(
44                output_file_name,
45                new_width,
46                new_height,
47            ));
48        }
49        Ok(resized_details)
50    }
51
52    /// Constructs the file name for a resized image.
53    pub fn get_resized_file_name(
54        image_file_name: &PathBuf,
55        width: u32,
56    ) -> Result<PathBuf, String> {
57        let file_name = match &image_file_name.file_stem() {
58            Some(f) => f.to_owned(),
59            None => return Err("No filename given!".to_string()),
60        };
61        let file_name = match file_name.to_str() {
62            Some(f) => f,
63            None => {
64                return Err(
65                    "utf-8 check failed for resized filename".to_string()
66                )
67            }
68        };
69        Ok(PathBuf::from(format!("{}-w{}.webp", file_name, width)))
70    }
71}