Canvas

Struct Canvas 

Source
pub struct Canvas { /* private fields */ }

Implementations§

Source§

impl Canvas

Source

pub fn new(width: u32, height: u32) -> Canvas

Creates a new Canvas of size width and height

§Examples
use pixtra::canvas::Canvas;

let canvas = Canvas::new(20, 20);

For more examples look at examples (examples/create-image.rs)

Examples found in repository?
examples/vertical-and-horizontal-chunks.rs (line 13)
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}
More examples
Hide additional examples
examples/rotations.rs (line 12)
11fn main() {
12    let canvas = Canvas::new(100, 200);
13    let canvas = canvas.filter(draw_filter);
14    canvas.save(Path::new("rotation-before-1.png")).unwrap();
15    let canvas_old = canvas.clone();
16    let canvas = canvas.rotate90();
17    canvas.save(Path::new("rotation-after-1.png")).unwrap();
18    let canvas = canvas.rotate90();
19    let canvas = canvas.rotate90();
20    let canvas = canvas.rotate90();
21    let rotate_error = error(&canvas_old, &canvas);
22    println!("ERROR: {}", rotate_error);
23
24    let canvas = Canvas::new(200, 100);
25    let canvas = canvas.filter(draw_filter);
26    canvas.save(Path::new("rotation-before-2.png")).unwrap();
27    let canvas = canvas.rotate90();
28    canvas.save(Path::new("rotation-after-2.png")).unwrap();
29}
examples/draw-on-flamingo.rs (line 24)
10fn main() {
11    println!("Starting");
12    let foreground = Canvas::load(Path::new("assets/flamingos.png")).unwrap();
13    let background = Canvas::load(Path::new("assets/flamingobg.jpg")).unwrap();
14
15    let result = background.draw_subimage(0, 0, &foreground);
16
17    let compare_image = Canvas::load(Path::new("assets/draw-on-example-result.png")).unwrap();
18    let diff = diff_debug(&result, &compare_image);
19    diff.save(Path::new("diff_debug_flamingo.out.png")).unwrap();
20
21    result.save(Path::new("flamingo.out.png")).unwrap();
22
23    let non_zero = diff.find_with_predicate(find_non_zero);
24    let mut diff_two = Canvas::new(400, 400);
25    for e in non_zero.iter() {
26        println!("{:?}", e);
27        diff_two.set_pixel_mut(e.coordinate.x, e.coordinate.y, &Colors::BLACK);
28    }
29    diff_two.save(Path::new("diff_two.png")).unwrap();
30    println!("Count: {}", non_zero.len());
31}
examples/create-image.rs (line 13)
4fn main() {
5    let color = Pixel {
6        r: 255,
7        g: 255,
8        b: 0,
9        a: 255,
10    };
11
12    // Creates new blank canvas. Blank is white.
13    let mut canvas = Canvas::new(10, 10);
14
15    canvas.set_pixel_mut(5, 5, &color);
16
17    let pixel = canvas.get_pixel(5, 5);
18
19    assert_eq!(color, pixel);
20    println!("We found color {} and we expected color {}", pixel, color);
21
22    // We can do the same without the _mut modifier
23    let color = Pixel {
24        r: 255,
25        g: 255,
26        b: 0,
27        a: 255,
28    };
29
30    // Creates new blank canvas. Blank is white.
31    let canvas = Canvas::new(10, 10);
32
33    // Here is the difference.
34    // We discard the old canvas and use the new one which contains the new pixel
35    let canvas = canvas.set_pixel(5, 5, &color);
36
37    let pixel = canvas.get_pixel(5, 5);
38
39    assert_eq!(color, pixel);
40    println!("We found color {} and we expected color {}", pixel, color);
41}
Source

pub fn new_with_data(width: u32, height: u32, data: Vec<Pixel>) -> Canvas

Creates a new Canvas of size width and height with initial data of data

Source

pub fn dimensions(&self) -> Size

Retrieves width and height of canvas in a Size struct.

Examples found in repository?
examples/advanced-filters.rs (line 22)
6fn gaussian_filter(canvas: &Canvas, x: u32, y: u32) -> Pixel {
7    // NOTE: The kernel needs to sum to 1.0. Below 1.0 your image will appear darker
8    // and above 1.0 it will appear lighter.
9    let kernel = vec![0.06, 0.13, 0.06, 0.13, 0.24, 0.13, 0.06, 0.13, 0.06];
10    let coords = vec![
11        (-1, -1),
12        (0, -1),
13        (1, -1),
14        (-1, 0),
15        (0, 0),
16        (1, 0),
17        (-1, 1),
18        (0, 1),
19        (1, 1),
20    ];
21    // For simplicity, we will leave out the edges of the picture.
22    let canvas_size = canvas.dimensions();
23    if x > 0 && y > 0 && x < canvas_size.width - 1 && y < canvas_size.height - 1 {
24        let pixel = apply_filter(canvas, (x, y), &kernel, &coords);
25        return pixel;
26    }
27    canvas.get_pixel(x, y)
28}
29
30fn lap_of_gaussian_filter(canvas: &Canvas, x: u32, y: u32) -> Pixel {
31    // NOTE: The kernel needs to sum to 1.0. Below 1.0 your image will appear darker
32    // and above 1.0 it will appear lighter.
33    let kernel = vec![
34        0, 1, 1, 2, 2, 2, 1, 1, 0,
35        1, 2, 4, 5, 5, 5, 4, 2, 1,
36        1, 4, 5, 3, 0, 3, 5, 4, 1,
37        2, 5, 3, -12, -24, -12, 3, 5, 2,
38        2, 5, 0, -24, -40, -24, 0, 5, 2,
39        2, 5, 3, -12, -24, -12, 3, 5, 2,
40        1, 4, 5, 3, 0, 3, 5, 4, 1,
41        1, 2, 4, 5, 5, 5, 4, 2, 1,
42        0, 1, 1, 2, 2, 2, 1, 1, 0];
43    let kernel = kernel.iter().map(|&x| x as f32).collect();
44    let mut coords = vec![];
45    for y in -4..5 {
46        for x in -4..5 {
47            coords.push((x, y));
48        }
49    }
50    // For simplicity, we will leave out the edges of the picture.
51    let canvas_size = canvas.dimensions();
52    if x > 3 && y > 3 && x < canvas_size.width - 4 && y < canvas_size.height - 4 {
53        let pixel = apply_filter(canvas, (x, y), &kernel, &coords);
54        return pixel;
55    }
56    canvas.get_pixel(x, y)
57}
58
59fn grey_scale_filter(canvas: &Canvas, x: u32, y: u32) -> Pixel {
60    to_grey_lumiosity(&canvas.get_pixel(x, y))
61}
62
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}
More examples
Hide additional examples
examples/filling.rs (line 23)
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), &center, 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}
examples/count-and-replace.rs (line 14)
5fn main() {
6    let color = Pixel {
7        r: 192,
8        g: 192,
9        b: 192,
10        a: 255,
11    };
12
13    let canvas = Canvas::load(Path::new("assets/mario-yellow.png")).unwrap();
14    let canvas_size = canvas.dimensions();
15    let find_pixel = canvas.get_pixel(canvas_size.width / 2, canvas_size.height / 2);
16    let pixel_count = canvas.count_pixels(&find_pixel);
17    println!("We found {} pixels with color {}", pixel_count, find_pixel);
18
19    let gray_canvas = canvas.clone().replace_pixel_with(&find_pixel, &color);
20    gray_canvas.save(Path::new("mario-gray.png")).unwrap();
21    let pixel_count = gray_canvas.count_pixels(&find_pixel);
22    println!("We found {} pixels with color {}", pixel_count, find_pixel);
23
24    let distance = 10.0;
25    let pixel_count = canvas.count_pixels_with_distance(&find_pixel, distance);
26    println!(
27        "We found {} pixels within {} distance of color {}",
28        pixel_count, distance, find_pixel
29    );
30    let gray_canvas_two = canvas
31        .clone()
32        .replace_pixel_with_distance(&find_pixel, distance, &color);
33
34    let pixel_count = gray_canvas_two.count_pixels_with_distance(&find_pixel, distance);
35    println!(
36        "We found {} pixels within {} distance of color {}",
37        pixel_count, distance, find_pixel
38    );
39
40    gray_canvas_two
41        .save(Path::new("mario-gray-two.png"))
42        .unwrap();
43
44    let canvas_size = canvas.dimensions();
45    let position = (canvas_size.width / 2 - 100, canvas_size.height / 2 - 100);
46    let sub_image = canvas.get_subimage(position.0, position.1, 200, 200);
47    let sub_image = sub_image.replace_pixel_with(&find_pixel, &color);
48    let canvas = canvas.set_subimage(position.0, position.1, &sub_image);
49    canvas.save(Path::new("mario-gray-subimage.png")).unwrap();
50}
Source

pub fn pixels(&self) -> Iter<'_, Pixel>

Returns an iterator for all the pixels in the Canvas.

Source

pub fn new_with_background(width: u32, height: u32, color: Pixel) -> Canvas

Creates a new Canvas of size width and height with all pixels initially set to color.

Examples found in repository?
examples/filling.rs (line 16)
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), &center, 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}
Source

pub fn save(&self, filename: &Path) -> Result<(), ImageError>

Saves the canvas as an image at the path given by filename

Examples found in repository?
examples/flipping-and-flopping.rs (line 10)
4fn main() {
5    let canvas = Canvas::load(Path::new("assets/lena.png")).unwrap();
6
7    let flipped = canvas.flip();
8    let double_flipped = flipped.flip();
9
10    let _ = flipped.save(Path::new("flipped.png")).unwrap();
11    let _ = double_flipped
12        .save(Path::new("double_flipped.png"))
13        .unwrap();
14
15    let flopped = canvas.flop();
16    let double_flopped = flopped.flop();
17
18    let _ = flopped.save(Path::new("flopped.png")).unwrap();
19    let _ = double_flopped
20        .save(Path::new("double_flopped.png"))
21        .unwrap();
22}
More examples
Hide additional examples
examples/rotations.rs (line 14)
11fn main() {
12    let canvas = Canvas::new(100, 200);
13    let canvas = canvas.filter(draw_filter);
14    canvas.save(Path::new("rotation-before-1.png")).unwrap();
15    let canvas_old = canvas.clone();
16    let canvas = canvas.rotate90();
17    canvas.save(Path::new("rotation-after-1.png")).unwrap();
18    let canvas = canvas.rotate90();
19    let canvas = canvas.rotate90();
20    let canvas = canvas.rotate90();
21    let rotate_error = error(&canvas_old, &canvas);
22    println!("ERROR: {}", rotate_error);
23
24    let canvas = Canvas::new(200, 100);
25    let canvas = canvas.filter(draw_filter);
26    canvas.save(Path::new("rotation-before-2.png")).unwrap();
27    let canvas = canvas.rotate90();
28    canvas.save(Path::new("rotation-after-2.png")).unwrap();
29}
examples/simple-filters.rs (line 40)
22fn main() {
23    let canvas = Canvas::load(Path::new("assets/lena.png")).unwrap();
24    let filtered_canvas = canvas.filter(unit_filter);
25    let inverse_canvas = canvas.filter(inverse_filter);
26    let inverse_inverse_canvas = inverse_canvas.filter(inverse_filter);
27
28    assert_eq!(canvas, inverse_inverse_canvas);
29    assert_ne!(canvas, inverse_canvas);
30    println!(
31        "Normal and double inversed canvas are equal: {}",
32        canvas == inverse_inverse_canvas
33    );
34    println!(
35        "Normal and single inversed canvas are equal: {}",
36        canvas == inverse_canvas
37    );
38
39    let _ = filtered_canvas
40        .save(Path::new("filtered_canvas.png"))
41        .unwrap();
42    let _ = inverse_canvas
43        .save(Path::new("inverse_canvas.png"))
44        .unwrap();
45}
examples/draw-on-flamingo.rs (line 19)
10fn main() {
11    println!("Starting");
12    let foreground = Canvas::load(Path::new("assets/flamingos.png")).unwrap();
13    let background = Canvas::load(Path::new("assets/flamingobg.jpg")).unwrap();
14
15    let result = background.draw_subimage(0, 0, &foreground);
16
17    let compare_image = Canvas::load(Path::new("assets/draw-on-example-result.png")).unwrap();
18    let diff = diff_debug(&result, &compare_image);
19    diff.save(Path::new("diff_debug_flamingo.out.png")).unwrap();
20
21    result.save(Path::new("flamingo.out.png")).unwrap();
22
23    let non_zero = diff.find_with_predicate(find_non_zero);
24    let mut diff_two = Canvas::new(400, 400);
25    for e in non_zero.iter() {
26        println!("{:?}", e);
27        diff_two.set_pixel_mut(e.coordinate.x, e.coordinate.y, &Colors::BLACK);
28    }
29    diff_two.save(Path::new("diff_two.png")).unwrap();
30    println!("Count: {}", non_zero.len());
31}
examples/filling.rs (line 20)
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), &center, 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}
examples/count-and-replace.rs (line 20)
5fn main() {
6    let color = Pixel {
7        r: 192,
8        g: 192,
9        b: 192,
10        a: 255,
11    };
12
13    let canvas = Canvas::load(Path::new("assets/mario-yellow.png")).unwrap();
14    let canvas_size = canvas.dimensions();
15    let find_pixel = canvas.get_pixel(canvas_size.width / 2, canvas_size.height / 2);
16    let pixel_count = canvas.count_pixels(&find_pixel);
17    println!("We found {} pixels with color {}", pixel_count, find_pixel);
18
19    let gray_canvas = canvas.clone().replace_pixel_with(&find_pixel, &color);
20    gray_canvas.save(Path::new("mario-gray.png")).unwrap();
21    let pixel_count = gray_canvas.count_pixels(&find_pixel);
22    println!("We found {} pixels with color {}", pixel_count, find_pixel);
23
24    let distance = 10.0;
25    let pixel_count = canvas.count_pixels_with_distance(&find_pixel, distance);
26    println!(
27        "We found {} pixels within {} distance of color {}",
28        pixel_count, distance, find_pixel
29    );
30    let gray_canvas_two = canvas
31        .clone()
32        .replace_pixel_with_distance(&find_pixel, distance, &color);
33
34    let pixel_count = gray_canvas_two.count_pixels_with_distance(&find_pixel, distance);
35    println!(
36        "We found {} pixels within {} distance of color {}",
37        pixel_count, distance, find_pixel
38    );
39
40    gray_canvas_two
41        .save(Path::new("mario-gray-two.png"))
42        .unwrap();
43
44    let canvas_size = canvas.dimensions();
45    let position = (canvas_size.width / 2 - 100, canvas_size.height / 2 - 100);
46    let sub_image = canvas.get_subimage(position.0, position.1, 200, 200);
47    let sub_image = sub_image.replace_pixel_with(&find_pixel, &color);
48    let canvas = canvas.set_subimage(position.0, position.1, &sub_image);
49    canvas.save(Path::new("mario-gray-subimage.png")).unwrap();
50}
Source

pub fn load(filename: &Path) -> Result<Canvas, ImageError>

Loads the image at the path given by filename and returns it as a canvas

Examples found in repository?
examples/flipping-and-flopping.rs (line 5)
4fn main() {
5    let canvas = Canvas::load(Path::new("assets/lena.png")).unwrap();
6
7    let flipped = canvas.flip();
8    let double_flipped = flipped.flip();
9
10    let _ = flipped.save(Path::new("flipped.png")).unwrap();
11    let _ = double_flipped
12        .save(Path::new("double_flipped.png"))
13        .unwrap();
14
15    let flopped = canvas.flop();
16    let double_flopped = flopped.flop();
17
18    let _ = flopped.save(Path::new("flopped.png")).unwrap();
19    let _ = double_flopped
20        .save(Path::new("double_flopped.png"))
21        .unwrap();
22}
More examples
Hide additional examples
examples/simple-filters.rs (line 23)
22fn main() {
23    let canvas = Canvas::load(Path::new("assets/lena.png")).unwrap();
24    let filtered_canvas = canvas.filter(unit_filter);
25    let inverse_canvas = canvas.filter(inverse_filter);
26    let inverse_inverse_canvas = inverse_canvas.filter(inverse_filter);
27
28    assert_eq!(canvas, inverse_inverse_canvas);
29    assert_ne!(canvas, inverse_canvas);
30    println!(
31        "Normal and double inversed canvas are equal: {}",
32        canvas == inverse_inverse_canvas
33    );
34    println!(
35        "Normal and single inversed canvas are equal: {}",
36        canvas == inverse_canvas
37    );
38
39    let _ = filtered_canvas
40        .save(Path::new("filtered_canvas.png"))
41        .unwrap();
42    let _ = inverse_canvas
43        .save(Path::new("inverse_canvas.png"))
44        .unwrap();
45}
examples/draw-on-flamingo.rs (line 12)
10fn main() {
11    println!("Starting");
12    let foreground = Canvas::load(Path::new("assets/flamingos.png")).unwrap();
13    let background = Canvas::load(Path::new("assets/flamingobg.jpg")).unwrap();
14
15    let result = background.draw_subimage(0, 0, &foreground);
16
17    let compare_image = Canvas::load(Path::new("assets/draw-on-example-result.png")).unwrap();
18    let diff = diff_debug(&result, &compare_image);
19    diff.save(Path::new("diff_debug_flamingo.out.png")).unwrap();
20
21    result.save(Path::new("flamingo.out.png")).unwrap();
22
23    let non_zero = diff.find_with_predicate(find_non_zero);
24    let mut diff_two = Canvas::new(400, 400);
25    for e in non_zero.iter() {
26        println!("{:?}", e);
27        diff_two.set_pixel_mut(e.coordinate.x, e.coordinate.y, &Colors::BLACK);
28    }
29    diff_two.save(Path::new("diff_two.png")).unwrap();
30    println!("Count: {}", non_zero.len());
31}
examples/find-islands.rs (line 8)
7fn main() {
8    let canvas = Canvas::load(Path::new("assets/small_green_islands.png")).unwrap();
9    let count = count_colors(&canvas);
10    for (key, value) in count.iter() {
11        println!("{}: {}", key, value);
12    }
13    let islands = canvas.find_islands(&Colors::GREEN);
14    println!("Size of islands: {}", islands.len());
15    for (i, island) in islands.iter().enumerate() {
16        println!("Island {} has {} points", i + 1, island.points.len());
17    }
18    let count = count_colors(&canvas);
19    for (key, value) in count.iter() {
20        println!("{}: {}", key, value);
21    }
22    let color_one = canvas.get_pixel(islands[0].points[0].x, islands[0].points[0].y);
23    let color_two = canvas.get_pixel(islands[1].points[0].x, islands[1].points[0].y);
24    println!("Color from island one: {}", color_one);
25    println!("Color from island one: {}", color_two);
26    let mut hashmap = HashMap::new();
27    for c in islands[0].points.iter() {
28        hashmap.insert(c, "");
29    }
30    println!("Island 1 hashmap: {}", hashmap.len());
31    let mut hashmap = HashMap::new();
32    for c in islands[1].points.iter() {
33        hashmap.insert(c, "");
34    }
35    println!("Island 2 hashmap: {}", hashmap.len());
36
37
38}
examples/filling.rs (line 22)
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), &center, 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}
examples/count-and-replace.rs (line 13)
5fn main() {
6    let color = Pixel {
7        r: 192,
8        g: 192,
9        b: 192,
10        a: 255,
11    };
12
13    let canvas = Canvas::load(Path::new("assets/mario-yellow.png")).unwrap();
14    let canvas_size = canvas.dimensions();
15    let find_pixel = canvas.get_pixel(canvas_size.width / 2, canvas_size.height / 2);
16    let pixel_count = canvas.count_pixels(&find_pixel);
17    println!("We found {} pixels with color {}", pixel_count, find_pixel);
18
19    let gray_canvas = canvas.clone().replace_pixel_with(&find_pixel, &color);
20    gray_canvas.save(Path::new("mario-gray.png")).unwrap();
21    let pixel_count = gray_canvas.count_pixels(&find_pixel);
22    println!("We found {} pixels with color {}", pixel_count, find_pixel);
23
24    let distance = 10.0;
25    let pixel_count = canvas.count_pixels_with_distance(&find_pixel, distance);
26    println!(
27        "We found {} pixels within {} distance of color {}",
28        pixel_count, distance, find_pixel
29    );
30    let gray_canvas_two = canvas
31        .clone()
32        .replace_pixel_with_distance(&find_pixel, distance, &color);
33
34    let pixel_count = gray_canvas_two.count_pixels_with_distance(&find_pixel, distance);
35    println!(
36        "We found {} pixels within {} distance of color {}",
37        pixel_count, distance, find_pixel
38    );
39
40    gray_canvas_two
41        .save(Path::new("mario-gray-two.png"))
42        .unwrap();
43
44    let canvas_size = canvas.dimensions();
45    let position = (canvas_size.width / 2 - 100, canvas_size.height / 2 - 100);
46    let sub_image = canvas.get_subimage(position.0, position.1, 200, 200);
47    let sub_image = sub_image.replace_pixel_with(&find_pixel, &color);
48    let canvas = canvas.set_subimage(position.0, position.1, &sub_image);
49    canvas.save(Path::new("mario-gray-subimage.png")).unwrap();
50}
Source

pub fn count_pixels(&self, pixel: &Pixel) -> u32

Counts the amount of pixels in the canvas equal to pixel

Examples found in repository?
examples/count-and-replace.rs (line 16)
5fn main() {
6    let color = Pixel {
7        r: 192,
8        g: 192,
9        b: 192,
10        a: 255,
11    };
12
13    let canvas = Canvas::load(Path::new("assets/mario-yellow.png")).unwrap();
14    let canvas_size = canvas.dimensions();
15    let find_pixel = canvas.get_pixel(canvas_size.width / 2, canvas_size.height / 2);
16    let pixel_count = canvas.count_pixels(&find_pixel);
17    println!("We found {} pixels with color {}", pixel_count, find_pixel);
18
19    let gray_canvas = canvas.clone().replace_pixel_with(&find_pixel, &color);
20    gray_canvas.save(Path::new("mario-gray.png")).unwrap();
21    let pixel_count = gray_canvas.count_pixels(&find_pixel);
22    println!("We found {} pixels with color {}", pixel_count, find_pixel);
23
24    let distance = 10.0;
25    let pixel_count = canvas.count_pixels_with_distance(&find_pixel, distance);
26    println!(
27        "We found {} pixels within {} distance of color {}",
28        pixel_count, distance, find_pixel
29    );
30    let gray_canvas_two = canvas
31        .clone()
32        .replace_pixel_with_distance(&find_pixel, distance, &color);
33
34    let pixel_count = gray_canvas_two.count_pixels_with_distance(&find_pixel, distance);
35    println!(
36        "We found {} pixels within {} distance of color {}",
37        pixel_count, distance, find_pixel
38    );
39
40    gray_canvas_two
41        .save(Path::new("mario-gray-two.png"))
42        .unwrap();
43
44    let canvas_size = canvas.dimensions();
45    let position = (canvas_size.width / 2 - 100, canvas_size.height / 2 - 100);
46    let sub_image = canvas.get_subimage(position.0, position.1, 200, 200);
47    let sub_image = sub_image.replace_pixel_with(&find_pixel, &color);
48    let canvas = canvas.set_subimage(position.0, position.1, &sub_image);
49    canvas.save(Path::new("mario-gray-subimage.png")).unwrap();
50}
Source

pub fn count_pixels_with_distance(&self, pixel: &Pixel, distance: f32) -> u32

Counts the amount of pixels in the canvas that are within the distance of distance of pixel

Examples found in repository?
examples/count-and-replace.rs (line 25)
5fn main() {
6    let color = Pixel {
7        r: 192,
8        g: 192,
9        b: 192,
10        a: 255,
11    };
12
13    let canvas = Canvas::load(Path::new("assets/mario-yellow.png")).unwrap();
14    let canvas_size = canvas.dimensions();
15    let find_pixel = canvas.get_pixel(canvas_size.width / 2, canvas_size.height / 2);
16    let pixel_count = canvas.count_pixels(&find_pixel);
17    println!("We found {} pixels with color {}", pixel_count, find_pixel);
18
19    let gray_canvas = canvas.clone().replace_pixel_with(&find_pixel, &color);
20    gray_canvas.save(Path::new("mario-gray.png")).unwrap();
21    let pixel_count = gray_canvas.count_pixels(&find_pixel);
22    println!("We found {} pixels with color {}", pixel_count, find_pixel);
23
24    let distance = 10.0;
25    let pixel_count = canvas.count_pixels_with_distance(&find_pixel, distance);
26    println!(
27        "We found {} pixels within {} distance of color {}",
28        pixel_count, distance, find_pixel
29    );
30    let gray_canvas_two = canvas
31        .clone()
32        .replace_pixel_with_distance(&find_pixel, distance, &color);
33
34    let pixel_count = gray_canvas_two.count_pixels_with_distance(&find_pixel, distance);
35    println!(
36        "We found {} pixels within {} distance of color {}",
37        pixel_count, distance, find_pixel
38    );
39
40    gray_canvas_two
41        .save(Path::new("mario-gray-two.png"))
42        .unwrap();
43
44    let canvas_size = canvas.dimensions();
45    let position = (canvas_size.width / 2 - 100, canvas_size.height / 2 - 100);
46    let sub_image = canvas.get_subimage(position.0, position.1, 200, 200);
47    let sub_image = sub_image.replace_pixel_with(&find_pixel, &color);
48    let canvas = canvas.set_subimage(position.0, position.1, &sub_image);
49    canvas.save(Path::new("mario-gray-subimage.png")).unwrap();
50}
Source

pub fn replace_pixel_with_distance( self, find_pixel: &Pixel, distance: f32, replace_pixel: &Pixel, ) -> Canvas

Replaces all pixels in the canvas that are within the distance of distance of pixel

Examples found in repository?
examples/count-and-replace.rs (line 32)
5fn main() {
6    let color = Pixel {
7        r: 192,
8        g: 192,
9        b: 192,
10        a: 255,
11    };
12
13    let canvas = Canvas::load(Path::new("assets/mario-yellow.png")).unwrap();
14    let canvas_size = canvas.dimensions();
15    let find_pixel = canvas.get_pixel(canvas_size.width / 2, canvas_size.height / 2);
16    let pixel_count = canvas.count_pixels(&find_pixel);
17    println!("We found {} pixels with color {}", pixel_count, find_pixel);
18
19    let gray_canvas = canvas.clone().replace_pixel_with(&find_pixel, &color);
20    gray_canvas.save(Path::new("mario-gray.png")).unwrap();
21    let pixel_count = gray_canvas.count_pixels(&find_pixel);
22    println!("We found {} pixels with color {}", pixel_count, find_pixel);
23
24    let distance = 10.0;
25    let pixel_count = canvas.count_pixels_with_distance(&find_pixel, distance);
26    println!(
27        "We found {} pixels within {} distance of color {}",
28        pixel_count, distance, find_pixel
29    );
30    let gray_canvas_two = canvas
31        .clone()
32        .replace_pixel_with_distance(&find_pixel, distance, &color);
33
34    let pixel_count = gray_canvas_two.count_pixels_with_distance(&find_pixel, distance);
35    println!(
36        "We found {} pixels within {} distance of color {}",
37        pixel_count, distance, find_pixel
38    );
39
40    gray_canvas_two
41        .save(Path::new("mario-gray-two.png"))
42        .unwrap();
43
44    let canvas_size = canvas.dimensions();
45    let position = (canvas_size.width / 2 - 100, canvas_size.height / 2 - 100);
46    let sub_image = canvas.get_subimage(position.0, position.1, 200, 200);
47    let sub_image = sub_image.replace_pixel_with(&find_pixel, &color);
48    let canvas = canvas.set_subimage(position.0, position.1, &sub_image);
49    canvas.save(Path::new("mario-gray-subimage.png")).unwrap();
50}
Source

pub fn replace_pixel_with_distance_mut( &mut self, find_pixel: &Pixel, distance: f32, replace_pixel: &Pixel, )

Replaces all pixels in the canvas that are within the distance of distance of pixel

Source

pub fn replace_pixel_with( self, find_pixel: &Pixel, replace_pixel: &Pixel, ) -> Canvas

Replaces all pixels in the canvas that are equal to pixel

Examples found in repository?
examples/count-and-replace.rs (line 19)
5fn main() {
6    let color = Pixel {
7        r: 192,
8        g: 192,
9        b: 192,
10        a: 255,
11    };
12
13    let canvas = Canvas::load(Path::new("assets/mario-yellow.png")).unwrap();
14    let canvas_size = canvas.dimensions();
15    let find_pixel = canvas.get_pixel(canvas_size.width / 2, canvas_size.height / 2);
16    let pixel_count = canvas.count_pixels(&find_pixel);
17    println!("We found {} pixels with color {}", pixel_count, find_pixel);
18
19    let gray_canvas = canvas.clone().replace_pixel_with(&find_pixel, &color);
20    gray_canvas.save(Path::new("mario-gray.png")).unwrap();
21    let pixel_count = gray_canvas.count_pixels(&find_pixel);
22    println!("We found {} pixels with color {}", pixel_count, find_pixel);
23
24    let distance = 10.0;
25    let pixel_count = canvas.count_pixels_with_distance(&find_pixel, distance);
26    println!(
27        "We found {} pixels within {} distance of color {}",
28        pixel_count, distance, find_pixel
29    );
30    let gray_canvas_two = canvas
31        .clone()
32        .replace_pixel_with_distance(&find_pixel, distance, &color);
33
34    let pixel_count = gray_canvas_two.count_pixels_with_distance(&find_pixel, distance);
35    println!(
36        "We found {} pixels within {} distance of color {}",
37        pixel_count, distance, find_pixel
38    );
39
40    gray_canvas_two
41        .save(Path::new("mario-gray-two.png"))
42        .unwrap();
43
44    let canvas_size = canvas.dimensions();
45    let position = (canvas_size.width / 2 - 100, canvas_size.height / 2 - 100);
46    let sub_image = canvas.get_subimage(position.0, position.1, 200, 200);
47    let sub_image = sub_image.replace_pixel_with(&find_pixel, &color);
48    let canvas = canvas.set_subimage(position.0, position.1, &sub_image);
49    canvas.save(Path::new("mario-gray-subimage.png")).unwrap();
50}
Source

pub fn replace_pixel_with_mut( &mut self, find_pixel: &Pixel, replace_pixel: &Pixel, )

Replaces all pixels in the canvas that are equal to pixel

Source

pub fn get_subimage(&self, x: u32, y: u32, width: u32, height: u32) -> Canvas

Returns a canvas that is subimage starting at (x, y) with size width x height.

Examples found in repository?
examples/count-and-replace.rs (line 46)
5fn main() {
6    let color = Pixel {
7        r: 192,
8        g: 192,
9        b: 192,
10        a: 255,
11    };
12
13    let canvas = Canvas::load(Path::new("assets/mario-yellow.png")).unwrap();
14    let canvas_size = canvas.dimensions();
15    let find_pixel = canvas.get_pixel(canvas_size.width / 2, canvas_size.height / 2);
16    let pixel_count = canvas.count_pixels(&find_pixel);
17    println!("We found {} pixels with color {}", pixel_count, find_pixel);
18
19    let gray_canvas = canvas.clone().replace_pixel_with(&find_pixel, &color);
20    gray_canvas.save(Path::new("mario-gray.png")).unwrap();
21    let pixel_count = gray_canvas.count_pixels(&find_pixel);
22    println!("We found {} pixels with color {}", pixel_count, find_pixel);
23
24    let distance = 10.0;
25    let pixel_count = canvas.count_pixels_with_distance(&find_pixel, distance);
26    println!(
27        "We found {} pixels within {} distance of color {}",
28        pixel_count, distance, find_pixel
29    );
30    let gray_canvas_two = canvas
31        .clone()
32        .replace_pixel_with_distance(&find_pixel, distance, &color);
33
34    let pixel_count = gray_canvas_two.count_pixels_with_distance(&find_pixel, distance);
35    println!(
36        "We found {} pixels within {} distance of color {}",
37        pixel_count, distance, find_pixel
38    );
39
40    gray_canvas_two
41        .save(Path::new("mario-gray-two.png"))
42        .unwrap();
43
44    let canvas_size = canvas.dimensions();
45    let position = (canvas_size.width / 2 - 100, canvas_size.height / 2 - 100);
46    let sub_image = canvas.get_subimage(position.0, position.1, 200, 200);
47    let sub_image = sub_image.replace_pixel_with(&find_pixel, &color);
48    let canvas = canvas.set_subimage(position.0, position.1, &sub_image);
49    canvas.save(Path::new("mario-gray-subimage.png")).unwrap();
50}
Source

pub fn resize(self, x: u32, y: u32) -> Canvas

Source

pub fn resize_mut(&mut self, x: u32, y: u32)

Source

pub fn rotate90_mut(&mut self)

Source

pub fn rotate180_mut(&mut self)

Source

pub fn rotate270_mut(&mut self)

Source

pub fn rotate90(self) -> Canvas

Examples found in repository?
examples/rotations.rs (line 16)
11fn main() {
12    let canvas = Canvas::new(100, 200);
13    let canvas = canvas.filter(draw_filter);
14    canvas.save(Path::new("rotation-before-1.png")).unwrap();
15    let canvas_old = canvas.clone();
16    let canvas = canvas.rotate90();
17    canvas.save(Path::new("rotation-after-1.png")).unwrap();
18    let canvas = canvas.rotate90();
19    let canvas = canvas.rotate90();
20    let canvas = canvas.rotate90();
21    let rotate_error = error(&canvas_old, &canvas);
22    println!("ERROR: {}", rotate_error);
23
24    let canvas = Canvas::new(200, 100);
25    let canvas = canvas.filter(draw_filter);
26    canvas.save(Path::new("rotation-before-2.png")).unwrap();
27    let canvas = canvas.rotate90();
28    canvas.save(Path::new("rotation-after-2.png")).unwrap();
29}
More examples
Hide additional examples
examples/filling.rs (line 22)
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), &center, 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}
Source

pub fn rotate180(self) -> Canvas

Source

pub fn rotate270(self) -> Canvas

Source

pub fn vertical_chunks(&self, size_of_chunk: u32) -> Vec<Canvas>

Examples found in repository?
examples/vertical-and-horizontal-chunks.rs (line 22)
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}
Source

pub fn horizontal_chunks(&self, size_of_chunk: u32) -> Vec<Canvas>

Source

pub fn iter(&self) -> impl Iterator<Item = Pixel> + '_

Source

pub fn iter_with_coordinates( &self, ) -> impl Iterator<Item = PixelWithCoordinate> + '_

Source

pub fn draw_subimage_mut(&mut self, x: u32, y: u32, canvas: &Canvas)

Draws canvas canvas as a subimage at (x, y)

Source

pub fn set_subimage_mut(&mut self, x: u32, y: u32, canvas: &Canvas)

Inserts canvas canvas as a subimage at (x, y)

Source

pub fn trace( self, island: &Island, left: u32, right: u32, up: u32, down: u32, ) -> Canvas

Source

pub fn trace_mut( &mut self, island: &Island, left: u32, right: u32, up: u32, down: u32, )

Source

pub fn draw_island(self, island: &Island, color: &Pixel) -> Canvas

Source

pub fn draw_island_mut(&mut self, island: &Island, color: &Pixel)

Source

pub fn draw_subimage(self, x: u32, y: u32, canvas: &Canvas) -> Canvas

Draws canvas canvas as a subimage at (x, y)

Examples found in repository?
examples/draw-on-flamingo.rs (line 15)
10fn main() {
11    println!("Starting");
12    let foreground = Canvas::load(Path::new("assets/flamingos.png")).unwrap();
13    let background = Canvas::load(Path::new("assets/flamingobg.jpg")).unwrap();
14
15    let result = background.draw_subimage(0, 0, &foreground);
16
17    let compare_image = Canvas::load(Path::new("assets/draw-on-example-result.png")).unwrap();
18    let diff = diff_debug(&result, &compare_image);
19    diff.save(Path::new("diff_debug_flamingo.out.png")).unwrap();
20
21    result.save(Path::new("flamingo.out.png")).unwrap();
22
23    let non_zero = diff.find_with_predicate(find_non_zero);
24    let mut diff_two = Canvas::new(400, 400);
25    for e in non_zero.iter() {
26        println!("{:?}", e);
27        diff_two.set_pixel_mut(e.coordinate.x, e.coordinate.y, &Colors::BLACK);
28    }
29    diff_two.save(Path::new("diff_two.png")).unwrap();
30    println!("Count: {}", non_zero.len());
31}
Source

pub fn set_subimage(self, x: u32, y: u32, canvas: &Canvas) -> Canvas

Inserts canvas canvas as a subimage at (x, y)

Examples found in repository?
examples/count-and-replace.rs (line 48)
5fn main() {
6    let color = Pixel {
7        r: 192,
8        g: 192,
9        b: 192,
10        a: 255,
11    };
12
13    let canvas = Canvas::load(Path::new("assets/mario-yellow.png")).unwrap();
14    let canvas_size = canvas.dimensions();
15    let find_pixel = canvas.get_pixel(canvas_size.width / 2, canvas_size.height / 2);
16    let pixel_count = canvas.count_pixels(&find_pixel);
17    println!("We found {} pixels with color {}", pixel_count, find_pixel);
18
19    let gray_canvas = canvas.clone().replace_pixel_with(&find_pixel, &color);
20    gray_canvas.save(Path::new("mario-gray.png")).unwrap();
21    let pixel_count = gray_canvas.count_pixels(&find_pixel);
22    println!("We found {} pixels with color {}", pixel_count, find_pixel);
23
24    let distance = 10.0;
25    let pixel_count = canvas.count_pixels_with_distance(&find_pixel, distance);
26    println!(
27        "We found {} pixels within {} distance of color {}",
28        pixel_count, distance, find_pixel
29    );
30    let gray_canvas_two = canvas
31        .clone()
32        .replace_pixel_with_distance(&find_pixel, distance, &color);
33
34    let pixel_count = gray_canvas_two.count_pixels_with_distance(&find_pixel, distance);
35    println!(
36        "We found {} pixels within {} distance of color {}",
37        pixel_count, distance, find_pixel
38    );
39
40    gray_canvas_two
41        .save(Path::new("mario-gray-two.png"))
42        .unwrap();
43
44    let canvas_size = canvas.dimensions();
45    let position = (canvas_size.width / 2 - 100, canvas_size.height / 2 - 100);
46    let sub_image = canvas.get_subimage(position.0, position.1, 200, 200);
47    let sub_image = sub_image.replace_pixel_with(&find_pixel, &color);
48    let canvas = canvas.set_subimage(position.0, position.1, &sub_image);
49    canvas.save(Path::new("mario-gray-subimage.png")).unwrap();
50}
Source

pub fn get_pixel(&self, x: u32, y: u32) -> Pixel

Returns pixel at position (x, y) from the canvas

Examples found in repository?
examples/simple-filters.rs (line 15)
14fn unit_filter(canvas: &Canvas, x: u32, y: u32) -> Pixel {
15    canvas.get_pixel(x, y)
16}
17
18fn inverse_filter(canvas: &Canvas, x: u32, y: u32) -> Pixel {
19    inverse(canvas.get_pixel(x, y))
20}
More examples
Hide additional examples
examples/advanced-filters.rs (line 27)
6fn gaussian_filter(canvas: &Canvas, x: u32, y: u32) -> Pixel {
7    // NOTE: The kernel needs to sum to 1.0. Below 1.0 your image will appear darker
8    // and above 1.0 it will appear lighter.
9    let kernel = vec![0.06, 0.13, 0.06, 0.13, 0.24, 0.13, 0.06, 0.13, 0.06];
10    let coords = vec![
11        (-1, -1),
12        (0, -1),
13        (1, -1),
14        (-1, 0),
15        (0, 0),
16        (1, 0),
17        (-1, 1),
18        (0, 1),
19        (1, 1),
20    ];
21    // For simplicity, we will leave out the edges of the picture.
22    let canvas_size = canvas.dimensions();
23    if x > 0 && y > 0 && x < canvas_size.width - 1 && y < canvas_size.height - 1 {
24        let pixel = apply_filter(canvas, (x, y), &kernel, &coords);
25        return pixel;
26    }
27    canvas.get_pixel(x, y)
28}
29
30fn lap_of_gaussian_filter(canvas: &Canvas, x: u32, y: u32) -> Pixel {
31    // NOTE: The kernel needs to sum to 1.0. Below 1.0 your image will appear darker
32    // and above 1.0 it will appear lighter.
33    let kernel = vec![
34        0, 1, 1, 2, 2, 2, 1, 1, 0,
35        1, 2, 4, 5, 5, 5, 4, 2, 1,
36        1, 4, 5, 3, 0, 3, 5, 4, 1,
37        2, 5, 3, -12, -24, -12, 3, 5, 2,
38        2, 5, 0, -24, -40, -24, 0, 5, 2,
39        2, 5, 3, -12, -24, -12, 3, 5, 2,
40        1, 4, 5, 3, 0, 3, 5, 4, 1,
41        1, 2, 4, 5, 5, 5, 4, 2, 1,
42        0, 1, 1, 2, 2, 2, 1, 1, 0];
43    let kernel = kernel.iter().map(|&x| x as f32).collect();
44    let mut coords = vec![];
45    for y in -4..5 {
46        for x in -4..5 {
47            coords.push((x, y));
48        }
49    }
50    // For simplicity, we will leave out the edges of the picture.
51    let canvas_size = canvas.dimensions();
52    if x > 3 && y > 3 && x < canvas_size.width - 4 && y < canvas_size.height - 4 {
53        let pixel = apply_filter(canvas, (x, y), &kernel, &coords);
54        return pixel;
55    }
56    canvas.get_pixel(x, y)
57}
58
59fn grey_scale_filter(canvas: &Canvas, x: u32, y: u32) -> Pixel {
60    to_grey_lumiosity(&canvas.get_pixel(x, y))
61}
62
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}
examples/create-image.rs (line 17)
4fn main() {
5    let color = Pixel {
6        r: 255,
7        g: 255,
8        b: 0,
9        a: 255,
10    };
11
12    // Creates new blank canvas. Blank is white.
13    let mut canvas = Canvas::new(10, 10);
14
15    canvas.set_pixel_mut(5, 5, &color);
16
17    let pixel = canvas.get_pixel(5, 5);
18
19    assert_eq!(color, pixel);
20    println!("We found color {} and we expected color {}", pixel, color);
21
22    // We can do the same without the _mut modifier
23    let color = Pixel {
24        r: 255,
25        g: 255,
26        b: 0,
27        a: 255,
28    };
29
30    // Creates new blank canvas. Blank is white.
31    let canvas = Canvas::new(10, 10);
32
33    // Here is the difference.
34    // We discard the old canvas and use the new one which contains the new pixel
35    let canvas = canvas.set_pixel(5, 5, &color);
36
37    let pixel = canvas.get_pixel(5, 5);
38
39    assert_eq!(color, pixel);
40    println!("We found color {} and we expected color {}", pixel, color);
41}
examples/find-islands.rs (line 22)
7fn main() {
8    let canvas = Canvas::load(Path::new("assets/small_green_islands.png")).unwrap();
9    let count = count_colors(&canvas);
10    for (key, value) in count.iter() {
11        println!("{}: {}", key, value);
12    }
13    let islands = canvas.find_islands(&Colors::GREEN);
14    println!("Size of islands: {}", islands.len());
15    for (i, island) in islands.iter().enumerate() {
16        println!("Island {} has {} points", i + 1, island.points.len());
17    }
18    let count = count_colors(&canvas);
19    for (key, value) in count.iter() {
20        println!("{}: {}", key, value);
21    }
22    let color_one = canvas.get_pixel(islands[0].points[0].x, islands[0].points[0].y);
23    let color_two = canvas.get_pixel(islands[1].points[0].x, islands[1].points[0].y);
24    println!("Color from island one: {}", color_one);
25    println!("Color from island one: {}", color_two);
26    let mut hashmap = HashMap::new();
27    for c in islands[0].points.iter() {
28        hashmap.insert(c, "");
29    }
30    println!("Island 1 hashmap: {}", hashmap.len());
31    let mut hashmap = HashMap::new();
32    for c in islands[1].points.iter() {
33        hashmap.insert(c, "");
34    }
35    println!("Island 2 hashmap: {}", hashmap.len());
36
37
38}
examples/count-and-replace.rs (line 15)
5fn main() {
6    let color = Pixel {
7        r: 192,
8        g: 192,
9        b: 192,
10        a: 255,
11    };
12
13    let canvas = Canvas::load(Path::new("assets/mario-yellow.png")).unwrap();
14    let canvas_size = canvas.dimensions();
15    let find_pixel = canvas.get_pixel(canvas_size.width / 2, canvas_size.height / 2);
16    let pixel_count = canvas.count_pixels(&find_pixel);
17    println!("We found {} pixels with color {}", pixel_count, find_pixel);
18
19    let gray_canvas = canvas.clone().replace_pixel_with(&find_pixel, &color);
20    gray_canvas.save(Path::new("mario-gray.png")).unwrap();
21    let pixel_count = gray_canvas.count_pixels(&find_pixel);
22    println!("We found {} pixels with color {}", pixel_count, find_pixel);
23
24    let distance = 10.0;
25    let pixel_count = canvas.count_pixels_with_distance(&find_pixel, distance);
26    println!(
27        "We found {} pixels within {} distance of color {}",
28        pixel_count, distance, find_pixel
29    );
30    let gray_canvas_two = canvas
31        .clone()
32        .replace_pixel_with_distance(&find_pixel, distance, &color);
33
34    let pixel_count = gray_canvas_two.count_pixels_with_distance(&find_pixel, distance);
35    println!(
36        "We found {} pixels within {} distance of color {}",
37        pixel_count, distance, find_pixel
38    );
39
40    gray_canvas_two
41        .save(Path::new("mario-gray-two.png"))
42        .unwrap();
43
44    let canvas_size = canvas.dimensions();
45    let position = (canvas_size.width / 2 - 100, canvas_size.height / 2 - 100);
46    let sub_image = canvas.get_subimage(position.0, position.1, 200, 200);
47    let sub_image = sub_image.replace_pixel_with(&find_pixel, &color);
48    let canvas = canvas.set_subimage(position.0, position.1, &sub_image);
49    canvas.save(Path::new("mario-gray-subimage.png")).unwrap();
50}
Source

pub fn set_pixel(self, x: u32, y: u32, pixel: &Pixel) -> Canvas

Sets pixel at position (x, y) to pixel

Examples found in repository?
examples/create-image.rs (line 35)
4fn main() {
5    let color = Pixel {
6        r: 255,
7        g: 255,
8        b: 0,
9        a: 255,
10    };
11
12    // Creates new blank canvas. Blank is white.
13    let mut canvas = Canvas::new(10, 10);
14
15    canvas.set_pixel_mut(5, 5, &color);
16
17    let pixel = canvas.get_pixel(5, 5);
18
19    assert_eq!(color, pixel);
20    println!("We found color {} and we expected color {}", pixel, color);
21
22    // We can do the same without the _mut modifier
23    let color = Pixel {
24        r: 255,
25        g: 255,
26        b: 0,
27        a: 255,
28    };
29
30    // Creates new blank canvas. Blank is white.
31    let canvas = Canvas::new(10, 10);
32
33    // Here is the difference.
34    // We discard the old canvas and use the new one which contains the new pixel
35    let canvas = canvas.set_pixel(5, 5, &color);
36
37    let pixel = canvas.get_pixel(5, 5);
38
39    assert_eq!(color, pixel);
40    println!("We found color {} and we expected color {}", pixel, color);
41}
Source

pub fn set_pixel_mut(&mut self, x: u32, y: u32, pixel: &Pixel)

Mutable sets pixel at position (x, y) to pixel

Examples found in repository?
examples/draw-on-flamingo.rs (line 27)
10fn main() {
11    println!("Starting");
12    let foreground = Canvas::load(Path::new("assets/flamingos.png")).unwrap();
13    let background = Canvas::load(Path::new("assets/flamingobg.jpg")).unwrap();
14
15    let result = background.draw_subimage(0, 0, &foreground);
16
17    let compare_image = Canvas::load(Path::new("assets/draw-on-example-result.png")).unwrap();
18    let diff = diff_debug(&result, &compare_image);
19    diff.save(Path::new("diff_debug_flamingo.out.png")).unwrap();
20
21    result.save(Path::new("flamingo.out.png")).unwrap();
22
23    let non_zero = diff.find_with_predicate(find_non_zero);
24    let mut diff_two = Canvas::new(400, 400);
25    for e in non_zero.iter() {
26        println!("{:?}", e);
27        diff_two.set_pixel_mut(e.coordinate.x, e.coordinate.y, &Colors::BLACK);
28    }
29    diff_two.save(Path::new("diff_two.png")).unwrap();
30    println!("Count: {}", non_zero.len());
31}
More examples
Hide additional examples
examples/create-image.rs (line 15)
4fn main() {
5    let color = Pixel {
6        r: 255,
7        g: 255,
8        b: 0,
9        a: 255,
10    };
11
12    // Creates new blank canvas. Blank is white.
13    let mut canvas = Canvas::new(10, 10);
14
15    canvas.set_pixel_mut(5, 5, &color);
16
17    let pixel = canvas.get_pixel(5, 5);
18
19    assert_eq!(color, pixel);
20    println!("We found color {} and we expected color {}", pixel, color);
21
22    // We can do the same without the _mut modifier
23    let color = Pixel {
24        r: 255,
25        g: 255,
26        b: 0,
27        a: 255,
28    };
29
30    // Creates new blank canvas. Blank is white.
31    let canvas = Canvas::new(10, 10);
32
33    // Here is the difference.
34    // We discard the old canvas and use the new one which contains the new pixel
35    let canvas = canvas.set_pixel(5, 5, &color);
36
37    let pixel = canvas.get_pixel(5, 5);
38
39    assert_eq!(color, pixel);
40    println!("We found color {} and we expected color {}", pixel, color);
41}
Source

pub fn set_pixel_mut_signed(&mut self, x: i64, y: i64, pixel: &Pixel)

Mutable sets pixel at position (x, y) to pixel if x: i64 and y: i64 is within image bounds

Source

pub fn to_grey(&self) -> Canvas

Turns the entire canvas grayscale.

Source

pub fn to_grey_mut(&mut self)

Turns the entire canvas grayscale.

Source

pub fn draw_square_mut(&mut self, x: u32, y: u32, w: u32, h: u32, color: &Pixel)

Draws a square on the canvas. Draws at position (x, y) with size width x height. Color is color.

Source

pub fn draw_square( self, x: u32, y: u32, w: u32, h: u32, color: &Pixel, ) -> Canvas

Draws a square on the canvas. Draws at position (x, y) with size width x height. Color is color.

Examples found in repository?
examples/filling.rs (line 17)
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), &center, 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}
Source

pub fn find_islands(&self, island_color: &Pixel) -> Vec<Island>

Examples found in repository?
examples/find-islands.rs (line 13)
7fn main() {
8    let canvas = Canvas::load(Path::new("assets/small_green_islands.png")).unwrap();
9    let count = count_colors(&canvas);
10    for (key, value) in count.iter() {
11        println!("{}: {}", key, value);
12    }
13    let islands = canvas.find_islands(&Colors::GREEN);
14    println!("Size of islands: {}", islands.len());
15    for (i, island) in islands.iter().enumerate() {
16        println!("Island {} has {} points", i + 1, island.points.len());
17    }
18    let count = count_colors(&canvas);
19    for (key, value) in count.iter() {
20        println!("{}: {}", key, value);
21    }
22    let color_one = canvas.get_pixel(islands[0].points[0].x, islands[0].points[0].y);
23    let color_two = canvas.get_pixel(islands[1].points[0].x, islands[1].points[0].y);
24    println!("Color from island one: {}", color_one);
25    println!("Color from island one: {}", color_two);
26    let mut hashmap = HashMap::new();
27    for c in islands[0].points.iter() {
28        hashmap.insert(c, "");
29    }
30    println!("Island 1 hashmap: {}", hashmap.len());
31    let mut hashmap = HashMap::new();
32    for c in islands[1].points.iter() {
33        hashmap.insert(c, "");
34    }
35    println!("Island 2 hashmap: {}", hashmap.len());
36
37
38}
More examples
Hide additional examples
examples/advanced-filters.rs (line 213)
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}
Source

pub fn fill_by_distance( self, x: u32, y: u32, fill_color: &Pixel, distance: f32, ) -> Canvas

Source

pub fn fill_by_color_and_distance( self, x: u32, y: u32, fill_color: &Pixel, color: &Pixel, distance: f32, ) -> Canvas

Source

pub fn fill(self, x: u32, y: u32, fill_color: &Pixel) -> Canvas

Examples found in repository?
examples/filling.rs (line 19)
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), &center, 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}
Source

pub fn filter(&self, filter: fn(&Canvas, u32, u32) -> Pixel) -> Canvas

Applies filter to entire canvas. filter is a function that takes a reference to the canvas and position (x, y) and returns the color which should be set at that position.

Examples found in repository?
examples/vertical-and-horizontal-chunks.rs (line 16)
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}
More examples
Hide additional examples
examples/rotations.rs (line 13)
11fn main() {
12    let canvas = Canvas::new(100, 200);
13    let canvas = canvas.filter(draw_filter);
14    canvas.save(Path::new("rotation-before-1.png")).unwrap();
15    let canvas_old = canvas.clone();
16    let canvas = canvas.rotate90();
17    canvas.save(Path::new("rotation-after-1.png")).unwrap();
18    let canvas = canvas.rotate90();
19    let canvas = canvas.rotate90();
20    let canvas = canvas.rotate90();
21    let rotate_error = error(&canvas_old, &canvas);
22    println!("ERROR: {}", rotate_error);
23
24    let canvas = Canvas::new(200, 100);
25    let canvas = canvas.filter(draw_filter);
26    canvas.save(Path::new("rotation-before-2.png")).unwrap();
27    let canvas = canvas.rotate90();
28    canvas.save(Path::new("rotation-after-2.png")).unwrap();
29}
examples/simple-filters.rs (line 24)
22fn main() {
23    let canvas = Canvas::load(Path::new("assets/lena.png")).unwrap();
24    let filtered_canvas = canvas.filter(unit_filter);
25    let inverse_canvas = canvas.filter(inverse_filter);
26    let inverse_inverse_canvas = inverse_canvas.filter(inverse_filter);
27
28    assert_eq!(canvas, inverse_inverse_canvas);
29    assert_ne!(canvas, inverse_canvas);
30    println!(
31        "Normal and double inversed canvas are equal: {}",
32        canvas == inverse_inverse_canvas
33    );
34    println!(
35        "Normal and single inversed canvas are equal: {}",
36        canvas == inverse_canvas
37    );
38
39    let _ = filtered_canvas
40        .save(Path::new("filtered_canvas.png"))
41        .unwrap();
42    let _ = inverse_canvas
43        .save(Path::new("inverse_canvas.png"))
44        .unwrap();
45}
examples/advanced-filters.rs (line 174)
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}
Source

pub fn find_with_predicate( &self, predicate: fn(&Pixel, u32, u32) -> bool, ) -> Vec<PixelWithCoordinate>

Finds all pixels where predicate predicate holds

Examples found in repository?
examples/draw-on-flamingo.rs (line 23)
10fn main() {
11    println!("Starting");
12    let foreground = Canvas::load(Path::new("assets/flamingos.png")).unwrap();
13    let background = Canvas::load(Path::new("assets/flamingobg.jpg")).unwrap();
14
15    let result = background.draw_subimage(0, 0, &foreground);
16
17    let compare_image = Canvas::load(Path::new("assets/draw-on-example-result.png")).unwrap();
18    let diff = diff_debug(&result, &compare_image);
19    diff.save(Path::new("diff_debug_flamingo.out.png")).unwrap();
20
21    result.save(Path::new("flamingo.out.png")).unwrap();
22
23    let non_zero = diff.find_with_predicate(find_non_zero);
24    let mut diff_two = Canvas::new(400, 400);
25    for e in non_zero.iter() {
26        println!("{:?}", e);
27        diff_two.set_pixel_mut(e.coordinate.x, e.coordinate.y, &Colors::BLACK);
28    }
29    diff_two.save(Path::new("diff_two.png")).unwrap();
30    println!("Count: {}", non_zero.len());
31}
Source

pub fn flip(&self) -> Canvas

Flips the image on the vertical axis

Examples found in repository?
examples/flipping-and-flopping.rs (line 7)
4fn main() {
5    let canvas = Canvas::load(Path::new("assets/lena.png")).unwrap();
6
7    let flipped = canvas.flip();
8    let double_flipped = flipped.flip();
9
10    let _ = flipped.save(Path::new("flipped.png")).unwrap();
11    let _ = double_flipped
12        .save(Path::new("double_flipped.png"))
13        .unwrap();
14
15    let flopped = canvas.flop();
16    let double_flopped = flopped.flop();
17
18    let _ = flopped.save(Path::new("flopped.png")).unwrap();
19    let _ = double_flopped
20        .save(Path::new("double_flopped.png"))
21        .unwrap();
22}
Source

pub fn flop(&self) -> Canvas

Flips the image on the horizontal axis

Examples found in repository?
examples/flipping-and-flopping.rs (line 15)
4fn main() {
5    let canvas = Canvas::load(Path::new("assets/lena.png")).unwrap();
6
7    let flipped = canvas.flip();
8    let double_flipped = flipped.flip();
9
10    let _ = flipped.save(Path::new("flipped.png")).unwrap();
11    let _ = double_flipped
12        .save(Path::new("double_flipped.png"))
13        .unwrap();
14
15    let flopped = canvas.flop();
16    let double_flopped = flopped.flop();
17
18    let _ = flopped.save(Path::new("flopped.png")).unwrap();
19    let _ = double_flopped
20        .save(Path::new("double_flopped.png"))
21        .unwrap();
22}

Trait Implementations§

Source§

impl Clone for Canvas

Source§

fn clone(&self) -> Canvas

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for Canvas

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Display for Canvas

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl PartialEq for Canvas

Source§

fn eq(&self, other: &Self) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl Eq for Canvas

Auto Trait Implementations§

§

impl Freeze for Canvas

§

impl RefUnwindSafe for Canvas

§

impl Send for Canvas

§

impl Sync for Canvas

§

impl Unpin for Canvas

§

impl UnwindSafe for Canvas

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

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 more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

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
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T> ToString for T
where T: Display + ?Sized,

Source§

fn to_string(&self) -> String

Converts the given value to a String. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V