Vector to image (grayscale)

Hi,

So I take an image and then do some operations over it and then try to save the image back to matrix, here is the code for the same,

let mut final_im_buf = DynamicImage::new_luma8(width as u32, height as u32).to_luma();
	for (y, x, pixel) in final_im_buf.enumerate_pixels_mut(){
		*pixel = image::Luma([mat[x as usize][y as usize]]);
	}
	final_im_buf.save("final_redaction.png").unwrap();

The problem is even even though the final result has exactly the same changes as the initial one, the final extracted image turns out sort of tilted. Is there a way to fix it? I was wondering is such a thing happening because I am using a rectangular image (dimension being 1058 x 323).
Note that width here is 1058 and height here is 323
Should I use maybe a square matrix, like sort of reduce the size of image by compressing or something?

Please let me know.

Thanks!

Are you doing the same transformation to all the pixels???, What is the size of m???

sounds rare to me the part: for (y, x, pixel)

when in one example of the crate:

Hi,

I am not sure if I understand your answer. My first point of operation is I have an array, I have to convert it to a matrix form. This I try to do here,

let mut mat = vec![vec![0u8;width as usize];height as usize];	
	let mut flag = 0;
	for i in 0..(height-1){
		for j in 0..(width-1){
				mat[i as usize][j as usize] = redacted_demo_vec[flag];
				flag = flag + 1;			
			}
	}

But, I think I am doing something wrong earlier. So in order to take an image in and then store the black and white pixel values in an array of u8, I do something like this,

let img = open("sample.png").unwrap();
let mut gray = img.to_luma8();
gray.save("grayscale.png").unwrap();
imageops::dither(&mut gray, &BiLevel);
gray.save("grayscale_bicolor.png").unwrap();
let img_arr = gray.as_bytes(); //converting to array of u8

Am I doing it correctly? I am sorry, I am new to working with images and trying to best of my knowledge to work it out as of now. Please let me know, if the functions I am using are in correct format?

There might be an off-by-one error here since a Range is not inclusive of the upper bound. I could see it making a tilted image with the way you read from redacted_demo_vec. Maybe try:

for i in 0..height {
    for j in 0..width {

you could use the function from_raw directly i think

https://docs.rs/image/0.23.14/image/struct.ImageBuffer.html#method.from_raw

Oh yeah turns out my entire problem was because of indexing

And that's why it's more recommended to use iterator over direct indexing when possible. It's both idiomatic, convenient, less error prone, and potentially faster as it usually guarantees to skip bound check. Try this instead.

mat[..height]
    .iter_mut()
    .flat_map(|s| &mut s[..width])
    .zip(&redacted_demo_vec)
    .for_each(|(mat, demo)| *mat = *demo);

Note that I used .for_each() instead of the for loop because I think it's visually better on code to use it after the long iterator chain. The default way to consume iterator would be the for loop.

EDIT: I missed the mat is a newly allocated zeroed vector which allows better construction method.

let mat: Vec<_> = redacted_demo_vec
    .chunks_exact(width)
    .take(height)
    .map(|s| s.to_vec())
    .collect();
1 Like

Oh, thanks !

This question is completely out of context. But, can I after resizing image to a certain size and doing some editing , get it back to original size?

I mean, you can resize it again? You might lose some quality from scaling it twice though.

I don't think quality is as much of concern as I want only a few things visible and rest I kind of black out. So can I resize it?

Sure, it sounds like you are using the image crate? It has a resize method you can call.

Okay, great, I will check that out.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.