magic_kernel/
resize.rs

1use crate::{
2    kernel::{Kernel2D, MagicKernel, Sharp2013, Sharp2021},
3    ImageF64,
4};
5
6/// Version of a resize algorithm.
7/// See <https://johncostella.com/magic/> for details and difference.
8#[derive(PartialEq, Eq)]
9pub enum Version {
10    /// Original magic kernel version with no extra sharpening
11    MagicKernel,
12    /// 2013 version of Magic Kernel Sharp
13    MagicKernelSharp2013,
14    /// 2021 version of Magic Kernel Sharp
15    MagicKernelSharp2021,
16}
17
18/// Resizes image to a new size. Any of the dimensions could be optional - in that
19/// case, image would be scaled proportionally.
20///
21/// # Examples
22///
23/// ```no_run
24/// // set width, scale height proportionally
25/// use magic_kernel::{Version, magic_resize};
26/// # let image = magic_kernel::ImageF64::new_empty(0, 0, 0);
27/// let result = magic_resize(&image, Version::MagicKernelSharp2021, Some(500), None);
28/// ```
29/// ```no_run
30/// // set height, scale width proportionally
31/// use magic_kernel::{Version, magic_resize};
32/// # let image = magic_kernel::ImageF64::new_empty(0, 0, 0);
33/// let result = magic_resize(&image, Version::MagicKernelSharp2021, None, Some(500));
34/// ```
35/// ```no_run
36/// // scale both width and height
37/// use magic_kernel::{Version, magic_resize};
38/// # let image = magic_kernel::ImageF64::new_empty(0, 0, 0);
39/// let result = magic_resize(&image, Version::MagicKernelSharp2021, Some(250), Some(500));
40/// ```
41pub fn magic_resize(
42    image: &ImageF64,
43    version: Version,
44    new_width: Option<u32>,
45    new_height: Option<u32>,
46) -> ImageF64 {
47    let new_size = match (new_width, new_height) {
48        (Some(new_width), Some(new_height)) => (new_width, new_height),
49        (Some(new_width), None) => {
50            let factor = new_width as f64 / image.width() as f64;
51            let new_height = (image.height() as f64 * factor) as u32;
52            (new_width, new_height)
53        }
54
55        (None, Some(new_height)) => {
56            let factor = new_height as f64 / image.height() as f64;
57            let new_width = (image.width() as f64 * factor) as u32;
58            (new_width, new_height)
59        }
60        (None, None) => (image.width(), image.height()),
61    };
62
63    let size = (image.width(), image.height());
64
65    let out = Kernel2D::new::<MagicKernel>(size, new_size).apply(image);
66    if version == Version::MagicKernel {
67        return out;
68    }
69    let out = Kernel2D::new::<Sharp2013>(new_size, new_size).apply(&out);
70    if version == Version::MagicKernelSharp2013 {
71        return out;
72    }
73
74    // Sharp 2021 version
75    Kernel2D::new::<Sharp2021>(new_size, new_size).apply(&out)
76}