How can I draw a rectangle in image

I'm trying to open an image, converting it into gray, and drawing a rectangle, then save it under another name, so, I'm using image and imageproc, and wrote the below code:

use image::{GenericImageView, FilterType, Rgb};
use imageproc::drawing::draw_hollow_rect_mut;
use imageproc::rect::Rect;

fn main() {
    let img = image::open("self.jpg").unwrap();
    
    let mut gray = img.grayscale();
    let white = Rgb([255u8, 255u8, 255u8]);

    draw_hollow_rect_mut(&mut gray, Rect::at(60, 10).of_size(20, 20), white);

    gray.save("gray.png").unwrap();
}

But I got the below error:

error[E0277]: the trait bound `image::dynimage::DynamicImage: image::image::GenericImage` is not satisfied
  --> src/main.rs:34:5
   |
34 |     draw_hollow_rect_mut(&mut gray, Rect::at(60, 10).of_size(20, 20), white);
   |     ^^^^^^^^^^^^^^^^^^^^ the trait `image::image::GenericImage` is not implemented for `image::dynimage::DynamicImage`
   
   = note: required by `imageproc::drawing::rect::draw_hollow_rect_mut`

Could this be

DynamicImage implement the GenericImage trait for RGBA pixels.

You were not far from it. My guess is the main issue there is your version of the crates in your toml file. If you click on the GenericImage trait in the documentation of the draw_hollow_rect_mut function, you will arrive on the image crate version 0.21 doc, whereas last version is 0.22. Traits are usually not compatible for different versions of the same crate, and this is hard to spot. So make sure you have this in your toml config file:

[dependencies]
image = "0.21"
imageproc = "0.18"

There was also a small Rgb instead of Rgba mistake but you would have spot that with the error message using the compatible versions. For a white on gray rectangle, you can do:

use image::Luma;
use imageproc::drawing::draw_hollow_rect_mut;
use imageproc::rect::Rect;

fn main() {
    let img = image::open("self.png").unwrap();
    let mut gray = img.to_luma();
    let white = Luma([255]);
    draw_hollow_rect_mut(&mut gray, Rect::at(60, 10).of_size(20, 20), white);
    gray.save("gray.png").unwrap();
}
1 Like