h_image/
transform.rs

1use crate::buffer::Buffer;
2use crate::color::Color;
3
4impl Buffer {
5
6    // blit src on self
7    // (0, 0) of src goes to (x, y) of self
8    pub fn blit(&mut self, src: &Buffer, x: i32, y: i32) -> &mut Self {
9
10        for curr_x in 0..src.width as i32 {
11
12            if x + curr_x < 0 || x + curr_x >= self.width as i32 {
13                continue;
14            }
15
16            for curr_y in 0..src.height as i32 {
17
18                if y + curr_y < 0 || y + curr_y >= self.height as i32 {
19                    continue;
20                }
21
22                self.blit_pixel(
23                    (curr_x + x) as usize,
24                    (curr_y + y) as usize,
25                    src.get_pixel(curr_x as usize, curr_y as usize)
26                );
27            }
28
29        }
30
31        self
32    }
33
34    pub fn mask(&mut self, mask: &Buffer) -> &mut Self {
35
36        if self.width != mask.width || self.height != mask.height {
37            return self;
38        }
39
40        for x in 0..self.width {
41
42            for y in 0..self.height {
43
44                if mask.get_pixel(x, y).a < 255 {
45                    self.set_pixel(x, y, Color::rgba(0, 0, 0, 0));
46                }
47
48            }
49
50        }
51
52        self
53    }
54
55    pub fn crop(&self, x: i32, y: i32, w: i32, h: i32) -> Buffer {
56
57        if w <= 0 || h <= 0 {
58            return Buffer::new(0, 0);
59        }
60
61        let mut result = Buffer::new(w as usize, h as usize);
62
63        for curr_x in x..x + w {
64
65            if curr_x < 0 || curr_x >= self.width as i32 {
66                continue;
67            }
68
69            for curr_y in y..y + h {
70                
71                if curr_y < 0 || curr_y >= self.height as i32 {
72                    continue;
73                }
74
75                result.set_pixel((curr_x - x) as usize, (curr_y - y) as usize, self.get_pixel(curr_x as usize, curr_y as usize));
76            }
77
78        }
79
80        result
81    }
82
83    // zoom in/out to fill
84    pub fn resize(&self, w: usize, h: usize) -> Buffer {
85
86        if w == 0 || h == 0 {
87            return self.clone();
88        }
89
90        let mut origin_curr_x = 0;
91        let mut origin_curr_y = 0;
92        let mut xs = Vec::with_capacity(w);
93        let mut ys = Vec::with_capacity(h);
94
95        for result_curr_x in 0..w {
96
97            while result_curr_x * self.width > origin_curr_x * w && origin_curr_x < self.width - 1 {
98                origin_curr_x += 1;
99            }
100
101            xs.push(origin_curr_x);
102        }
103
104        for result_curr_y in 0..h {
105
106            while result_curr_y * self.height > origin_curr_y * h && origin_curr_y < self.height - 1 {
107                origin_curr_y += 1;
108            }
109
110            ys.push(origin_curr_y);
111        }
112
113        let mut result = Buffer::new(w, h);
114
115        for x in 0..w {
116
117            for y in 0..h {
118                result.set_pixel(x, y, self.get_pixel(xs[x], ys[y]));
119            }
120
121        }
122
123        result
124    }
125
126}