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}