1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
use image::imageops::{resize, FilterType};
use image::{GenericImage, ImageBuffer, Pixel, RgbImage};
use num::rational::Ratio;
use snafu::Snafu;
pub mod color;
pub use crate::color::{ColorDepth, FixedPalette};
pub fn reduce<I: 'static>(
img: &I,
nwidth: u32,
nheight: u32,
) -> ImageBuffer<I::Pixel, Vec<<I::Pixel as Pixel>::Subpixel>>
where
I: GenericImage,
{
resize(img, nwidth, nheight, FilterType::CatmullRom)
}
pub fn crop(mut image: RgbImage, left: u32, top: u32, width: u32, height: u32) -> RgbImage {
image::imageops::crop(&mut image, left, top, width, height);
image
}
pub fn expand<I: 'static>(
img: &I,
nwidth: u32,
nheight: u32,
) -> ImageBuffer<I::Pixel, Vec<<I::Pixel as Pixel>::Subpixel>>
where
I: GenericImage,
{
resize(img, nwidth, nheight, FilterType::Nearest)
}
#[derive(Debug, Snafu)]
#[snafu(visibility(pub))]
pub enum ResolutionError {
Non,
RatioWithoutSide,
TooMany,
}
pub fn resolve_output_resolution(
width: u32,
height: u32,
output_width: Option<u32>,
output_height: Option<u32>,
pixel_ratio: Option<Ratio<u32>>,
) -> Result<(u32, u32), ResolutionError> {
match (pixel_ratio, output_width, output_height) {
(None, None, None) => Non.fail(),
(None, Some(w), Some(h)) => Ok((w, h)),
(Some(r), None, Some(h)) => {
let w = ((r * h * width) / height).round().to_integer();
Ok((w, h))
}
(Some(r), Some(w), None) => {
let h = (Ratio::from_integer(w) * height / (r * width))
.round()
.to_integer();
Ok((w, h))
}
(None, None, Some(h)) => {
let ir = Ratio::new(width, height);
let w = (Ratio::from_integer(h) * ir).round().to_integer();
Ok((w, h))
}
(None, Some(w), None) => {
let ir = Ratio::new(width, height);
let h = (Ratio::from_integer(w) / ir).round().to_integer();
Ok((w, h))
}
(Some(_r), None, None) => RatioWithoutSide.fail(),
(Some(_r), Some(_w), Some(_h)) => TooMany.fail(),
}
}