pub struct Pixel {
pub r: u8,
pub g: u8,
pub b: u8,
pub a: u8,
}Fields§
§r: u8§g: u8§b: u8§a: u8Implementations§
Source§impl Pixel
impl Pixel
Sourcepub fn builder() -> PixelBuilder
pub fn builder() -> PixelBuilder
Examples found in repository?
examples/advanced-filters.rs (line 83)
74fn apply_filter(
75 canvas: &Canvas,
76 center: (u32, u32),
77 kernel: &Vec<f32>,
78 coords: &Vec<(i32, i32)>,
79) -> Pixel {
80 let scales = kernel
81 .iter()
82 .zip(coords.iter())
83 .fold(Pixel::builder(), |acc, (scale, (x, y))| {
84 let pixel =
85 canvas.get_pixel((center.0 as i32 + *x) as u32, (center.1 as i32 + *y) as u32);
86 acc + PixelBuilder::from(
87 pixel.r as f32 * scale,
88 pixel.g as f32 * scale,
89 pixel.b as f32 * scale,
90 pixel.a as f32,
91 )
92 });
93 scales.build()
94}Sourcepub fn new(red: u8, green: u8, blue: u8, alpha: u8) -> Pixel
pub fn new(red: u8, green: u8, blue: u8, alpha: u8) -> Pixel
Examples found in repository?
More examples
examples/vertical-and-horizontal-chunks.rs (line 7)
5fn draw_filter(_: &Canvas, _: u32, y: u32) -> Pixel {
6 let y_level = (y / 10 + 1) as u8;
7 let pixel = Pixel::new(15 * y_level, 0, 0, 255);
8 pixel
9}
10
11// Slice pictures up and stitch them back together.
12fn main() {
13 let canvas = Canvas::new(100, 100);
14
15 // Let's color it.
16 let canvas = canvas.filter(draw_filter);
17 let counts = count_colors(&canvas);
18 assert_eq!(counts.len(), 10);
19 assert_eq!(counts.get(&Pixel::new(30, 0, 0, 255)), Some(&1000));
20 assert_eq!(counts.get(&Pixel::new(0, 0, 0, 0)), None);
21
22 let chunks = canvas.vertical_chunks(10);
23 for (i, chunk) in chunks.iter().enumerate() {
24 let counts = count_colors(&chunk);
25 assert_eq!(counts.len(), 1, "We are testing chunk {}", i);
26 assert_eq!(
27 counts.contains_key(&Pixel::new(((i + 1) * 15) as u8, 0, 0, 255)),
28 true,
29 "We are testing chunk {}",
30 i
31 );
32 }
33}examples/advanced-filters.rs (line 66)
63fn black_or_white_filter(canvas: &Canvas, x: u32, y: u32) -> Pixel {
64 let pixel = canvas.get_pixel(x, y);
65 if pixel.r < 128 {
66 Pixel::new(0, 0, 0, 255)
67 } else {
68 Pixel::new(255, 255, 255, 255)
69 }
70}
71
72
73
74fn apply_filter(
75 canvas: &Canvas,
76 center: (u32, u32),
77 kernel: &Vec<f32>,
78 coords: &Vec<(i32, i32)>,
79) -> Pixel {
80 let scales = kernel
81 .iter()
82 .zip(coords.iter())
83 .fold(Pixel::builder(), |acc, (scale, (x, y))| {
84 let pixel =
85 canvas.get_pixel((center.0 as i32 + *x) as u32, (center.1 as i32 + *y) as u32);
86 acc + PixelBuilder::from(
87 pixel.r as f32 * scale,
88 pixel.g as f32 * scale,
89 pixel.b as f32 * scale,
90 pixel.a as f32,
91 )
92 });
93 scales.build()
94}
95
96fn lap_edge_detection_filter(canvas: &Canvas, x: u32, y: u32) -> Pixel {
97 // NOTE: The kernel (this vector) needs to sum to 1.0. Below 1.0 your image will appear darker
98 // and above 1.0 it will appear lighter.
99 let kernel = vec![0.5, 1.0, 0.5, 1.0, -6.0, 1.0, 0.5, 1.0, 0.5];
100 let coords = vec![
101 (-1, -1),
102 (0, -1),
103 (1, -1),
104 (-1, 0),
105 (0, 0),
106 (1, 0),
107 (-1, 1),
108 (0, 1),
109 (1, 1),
110 ];
111 // For simplicity, we will leave out the edges of the picture.
112 let canvas_size = canvas.dimensions();
113 if x > 0 && y > 0 && x < canvas_size.width - 1 && y < canvas_size.height - 1 {
114 let pixel = apply_filter(canvas, (x, y), &kernel, &coords);
115 return pixel;
116 }
117 canvas.get_pixel(x, y)
118}
119
120fn prewitt_edge_detection_filter(canvas: &Canvas, x: u32, y: u32) -> Pixel {
121 let kernel_one: Vec<f32> = vec![1f32, 0f32, -1f32, 1f32, 0f32, -1f32, 1f32, 0f32, -1f32];
122 let kernel_two: Vec<f32> = vec![1f32, 1f32, 1f32, 0f32, 0f32, 0f32, -1f32, -1f32, -1f32];
123 let coords = vec![
124 (-1, -1),
125 (0, -1),
126 (1, -1),
127 (-1, 0),
128 (0, 0),
129 (1, 0),
130 (-1, 1),
131 (0, 1),
132 (1, 1),
133 ];
134
135 let canvas_size = canvas.dimensions();
136 if x > 0 && y > 0 && x < canvas_size.width - 1 && y < canvas_size.height - 1 {
137 let pixel_one = apply_filter(canvas, (x, y), &kernel_one, &coords);
138 let pixel_two = apply_filter(canvas, (x, y), &kernel_two, &coords);
139
140 let pixel = PixelBuilder::from(
141 ((pixel_one.r as u32 * pixel_one.r as u32 + pixel_two.r as u32 * pixel_two.r as u32)
142 as f64)
143 .sqrt() as f32,
144 ((pixel_one.g as u32 * pixel_one.g as u32 + pixel_two.g as u32 * pixel_two.g as u32)
145 as f64)
146 .sqrt() as f32,
147 ((pixel_one.b as u32 * pixel_one.b as u32 + pixel_two.b as u32 * pixel_two.b as u32)
148 as f64)
149 .sqrt() as f32,
150 255f32,
151 );
152 return pixel.build();
153 }
154 canvas.get_pixel(x, y)
155}
156
157fn inverse(pixel: Pixel) -> Pixel {
158 Pixel {
159 r: u8::max_value() - pixel.r,
160 g: u8::max_value() - pixel.g,
161 b: u8::max_value() - pixel.b,
162 a: pixel.a,
163 }
164}
165
166fn inverse_filter(canvas: &Canvas, x: u32, y: u32) -> Pixel {
167 inverse(canvas.get_pixel(x, y))
168}
169
170fn main() {
171 // Gaussian blur
172 let canvas = Canvas::load(Path::new("assets/lena.png")).unwrap();
173 let test_image = Canvas::load(Path::new("assets/IMG_0771.JPG")).unwrap();
174 let gaussian_canvas = canvas.filter(gaussian_filter);
175 let _ = gaussian_canvas
176 .save(Path::new("gaussian_canvas.png"))
177 .unwrap();
178 let gaussian_canvas = gaussian_canvas.filter(gaussian_filter);
179 let gaussian_canvas = gaussian_canvas.filter(gaussian_filter);
180 let gaussian_canvas = gaussian_canvas.filter(gaussian_filter);
181 let gaussian_canvas = gaussian_canvas.filter(gaussian_filter);
182 let _ = gaussian_canvas
183 .save(Path::new("very_gaussian_canvas.png"))
184 .unwrap();
185
186 // Chaining filters
187 let inverse_gaussian_canvas = canvas.filter(inverse_filter).filter(gaussian_filter);
188 let _ = inverse_gaussian_canvas
189 .save(Path::new("inverse_gaussian_canvas.png"))
190 .unwrap();
191
192 let lap_edge_detection_canvas = canvas.filter(lap_edge_detection_filter);
193 let _ = lap_edge_detection_canvas
194 .save(Path::new("lap_edge_detection_filter.png"))
195 .unwrap();
196
197 let prewitt_edge_detection_canvas = canvas.filter(prewitt_edge_detection_filter);
198 let _ = prewitt_edge_detection_canvas
199 .save(Path::new("prewitt_edge_detection_filter.png"))
200 .unwrap();
201
202 let lap_of_gaussian_filter_canvas = test_image.filter(grey_scale_filter).filter(lap_of_gaussian_filter);
203 //let counted_colors = count_colors(&lap_of_gaussian_filter_canvas);
204 //println!("{}", counted_colors_to_html(&counted_colors));
205 let _ = lap_of_gaussian_filter_canvas
206 .save(Path::new("lap_of_gaussian_edge_detection_filter.png"))
207 .unwrap();
208 let filtered_canvas = lap_of_gaussian_filter_canvas.filter(black_or_white_filter);
209 let _ = filtered_canvas
210 .save(Path::new("filtered_canvas.png"))
211 .unwrap();
212
213 let islands = filtered_canvas.find_islands(&Pixel::new(255, 255, 255, 255));
214 let islands_with_size: Vec<Island> = islands.iter().filter(|x| x.points.len() > 40000).map(|x| x.clone()).collect();
215 // TODO: Now we have the outline of the islands.
216 // Copy the islands a blank canvas.
217 // Fill from the outside
218 // Now you have the entire form of all the islands
219 // Transfer the pixels that were not filled from the outside
220 //
221 //
222 // TODO: NEW IDEA AS WELL: Create a 'fattener'. Paints a 2x2, 3x3, 4x4, ... etc around each
223 // pixel. This way you can expand outwards
224
225
226
227
228
229}examples/filling.rs (line 14)
6fn main() {
7 let color = Pixel {
8 r: 0,
9 g: 0,
10 b: 255,
11 a: 255,
12 };
13
14 let new_color = Pixel::new(255, 0, 0, 255);
15
16 let canvas = Canvas::new_with_background(100, 100, color.clone())
17 .draw_square(10, 10, 80, 80, &new_color)
18 .draw_square(20, 20, 60, 60, &color)
19 .fill(1, 1, &Pixel::new(172, 172, 172, 255));
20 canvas.save(Path::new("testing.png")).unwrap();
21
22 let canvas = Canvas::load(Path::new("assets/20230709_111142.jpg")).unwrap().rotate90();
23 println!("Size of canvas: {} x {}", canvas.dimensions().width, canvas.dimensions().height);
24 /*let subcanvas = canvas.get_subimage(1600, 50, 1400, 400);
25 let (center, distance) = utility::find_center_and_size(&subcanvas);
26 println!("center and distance = {center} and {distance}");
27 let canvas = canvas.fill_by_color_and_distance(1600, 50, &Pixel::new(0,0,0,0), ¢er, 100.0);
28
29 println!("Size of canvas: {} x {}", canvas.dimensions().width, canvas.dimensions().height);
30 canvas.save(Path::new("testing-fill-by-center-and-distance.png")).unwrap();*/
31
32 /*for i in (30..90).step_by(1) {
33 let current_canvas = canvas.clone();
34 let name = format!("output_liv/distance_{i}.png");
35 let current = current_canvas.fill_by_distance(1500, 20, &Pixel::new(0,0,0,0), i as f32);
36 current.save(Path::new(&name)).unwrap();
37 println!("Number {i} done");
38 }*/
39}pub fn from(red: f32, green: f32, blue: f32, alpha: f32) -> Pixel
pub fn denormalize(red: f32, green: f32, blue: f32, alpha: f32) -> Pixel
pub fn random() -> Pixel
pub fn is_zero(&self) -> bool
pub fn multiply(&self, x: f32, y: f32, z: f32) -> Pixel
pub fn scale(&self, s: f32) -> Pixel
pub fn diff(&self, other: &Pixel) -> Pixel
pub fn normalize(&self) -> (f32, f32, f32, f32)
pub fn set_red(self, red: u8) -> Pixel
pub fn set_green(self, green: u8) -> Pixel
pub fn set_blue(self, blue: u8) -> Pixel
pub fn set_alpha(self, alpha: u8) -> Pixel
pub fn set_red_mut(&mut self, red: u8)
pub fn set_green_mut(&mut self, green: u8)
pub fn set_blue_mut(&mut self, blue: u8)
pub fn set_alpha_mut(&mut self, alpha: u8)
Trait Implementations§
Source§impl Add<Pixel> for PixelBuilder
impl Add<Pixel> for PixelBuilder
Source§type Output = PixelBuilder
type Output = PixelBuilder
The resulting type after applying the
+ operator.Source§impl Add<PixelBuilder> for Pixel
impl Add<PixelBuilder> for Pixel
Source§type Output = PixelBuilder
type Output = PixelBuilder
The resulting type after applying the
+ operator.Source§fn add(self, other: PixelBuilder) -> PixelBuilder
fn add(self, other: PixelBuilder) -> PixelBuilder
Performs the
+ operation. Read moreSource§impl Add for Pixel
impl Add for Pixel
Source§type Output = PixelBuilder
type Output = PixelBuilder
The resulting type after applying the
+ operator.Source§impl Div<f32> for Pixel
impl Div<f32> for Pixel
Source§type Output = PixelBuilder
type Output = PixelBuilder
The resulting type after applying the
/ operator.Source§impl Mul<f32> for Pixel
impl Mul<f32> for Pixel
Source§type Output = PixelBuilder
type Output = PixelBuilder
The resulting type after applying the
* operator.impl Eq for Pixel
Auto Trait Implementations§
impl Freeze for Pixel
impl RefUnwindSafe for Pixel
impl Send for Pixel
impl Sync for Pixel
impl Unpin for Pixel
impl UnwindSafe for Pixel
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
Converts
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
Converts
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more