image_builder/picture.rs
1use image::imageops::FilterType;
2use image::DynamicImage;
3
4/// External images.
5///
6/// The Picture structure is responsible for defining and adjusting external images that will be
7/// included in the image being built. It allows for cropping, resizing, and positioning to compose
8/// the final image.
9///
10/// **⚠️ It's important to note that if there is both cropping and resizing on the same
11/// image, the library will always perform cropping first, and then resizing.** ⚠️
12/// ## Example
13/// ```
14/// # use image_builder::FilterType;
15/// # let file_bytes:Vec<u8> = Vec::new();
16/// use image_builder::Picture;
17/// use image::DynamicImage;
18///
19/// Picture::new(file_bytes)
20/// .resize(100, 100, FilterType::Triangle) // Resizing is specified here, but the library will first perform the cropping below, and then this resizing.
21/// .crop(50, 50, 200, 200);
22/// ```
23/// In the example above, an image of 300x300 pixels was imported, a square of 200x200 pixels was
24/// cropped, and then this cropped portion was resized by half, resulting in an image of 100x100 pixels.
25#[derive(Clone)]
26pub struct Picture {
27 img: image::DynamicImage,
28 crop: Option<(u32, u32, u32, u32)>,
29 resize: Option<(u32, u32, FilterType)>,
30 position: (u32, u32),
31}
32impl Picture {
33 /// This method instantiates an external image using the file path of the image
34 /// and positions it at the point (0,0) of the image being built.
35 /// ## Example
36 /// ```
37 /// use image::DynamicImage;
38 /// use image_builder::Picture;
39 ///
40 /// Picture::new(image);
41 /// ```
42 pub fn new(img: DynamicImage) -> Picture {
43 Picture {
44 img,
45 resize: None,
46 crop: None,
47 position: (0, 0),
48 }
49 }
50
51 /// This method allows resizing an image by specifying the desired new height, width and [`FilterType`].
52 /// ## Example
53 /// ```rust
54 /// # use image_builder::FilterType;
55 /// use image_builder::Picture;
56 ///
57 /// Picture::new("/home/user/logo.png")
58 /// .resize(200, 100, FilterType::Triangle);
59 /// ```
60 pub fn resize(&mut self, width: u32, height: u32, filter: FilterType) -> Self {
61 self.resize = Some((width, height, filter));
62 self.clone()
63 }
64
65 /// Use this method to crop an imported image by providing the starting point of the crop (x, y),
66 /// as well as the desired height and width to be cropped.
67 /// ## Example
68 /// ```
69 /// use image_builder::Picture;
70 ///
71 /// Picture::new("/home/user/logo.png")
72 /// .crop(50, 50, 200, 200);
73 /// ```
74 pub fn crop(&mut self, x: u32, y: u32, width: u32, height: u32) -> Self {
75 self.crop = Some((x, y, width, height));
76 self.clone()
77 }
78
79 /// This method allows you to adjust the position of the imported image within the image being constructed.
80 /// ## Example
81 /// ```
82 /// use image_builder::Picture;
83 ///
84 /// Picture::new("/home/user/logo.png")
85 /// .position(100, 100);
86 /// ```
87 pub fn position(&mut self, x: u32, y: u32) -> Self {
88 self.position = (x, y);
89 self.clone()
90 }
91}
92
93#[derive(Clone)]
94pub struct CropValues {
95 pub x: u32,
96 pub y: u32,
97 pub width: u32,
98 pub height: u32,
99}
100
101#[derive(Clone)]
102pub struct ResizeValues {
103 pub nwidth: u32,
104 pub nheight: u32,
105 pub filter: FilterType,
106}
107
108#[derive(Clone)]
109pub struct PictureValues<'a> {
110 pub img: &'a DynamicImage,
111 pub x: i64,
112 pub y: i64,
113 pub crop: Option<CropValues>,
114 pub resize: Option<ResizeValues>,
115}
116pub fn extract(picture: &Picture) -> PictureValues {
117 PictureValues {
118 img: &picture.img,
119 x: picture.position.0 as i64,
120 y: picture.position.1 as i64,
121 crop: match picture.crop {
122 None => None,
123 Some(values) => Some(CropValues {
124 x: values.0,
125 y: values.1,
126 width: values.2,
127 height: values.3,
128 }),
129 },
130 resize: match picture.resize {
131 None => None,
132 Some(values) => Some(ResizeValues {
133 nwidth: values.0,
134 nheight: values.1,
135 filter: values.2,
136 }),
137 },
138 }
139}