#Confused about how to iterate over ImageBuffer objects in the image crate

12 messages · Page 1 of 1 (latest)

quasi sable
#

Is anybody here familiar with the image crate?
I'm trying to use ImageBuffer::enumerate_rows_mut but I can't figure out how it works exactly.
I get that it returns an iterator over a tuple where the first element is the row number, and the second element is some kind of object that represents the row, but I'm having trouble figuring out how to work with the row object.
What I want is to be able to iterate over that row object and get a tuple (x, pixel).
The reason I want to do a nested loop is to track the progress of generating an image in a raytracer, I want to keep track of how many rows of the image are left.

#

Oh, and I should have mentioned that I've done the following:

  • Looked through the image crate documentation to see if I could figure it out.
  • Looked at examples in the image crate GitHub repository to see if there was one that used enumerate_rows or enumerate_rows_mut
  • Google searched on phrases such as rust image enumerate_rows_mut example
  • Tried to just write the code and see if I can follow the types
#

Here is the code I have:

    for (y, row) in imgbuf.enumerate_rows_mut() {
        for (x, pixel) in row.enumerate() {
            *pixel = do_something_to_get_the_pixel_color();
        }
    }

The outer loop is fine, it's the inner loop I'm not sure how to write

#

imgbuf is a mutable ImageBuffer type

unborn onyx
#

It feels like you don't have a clear idea on where to store your result yet. Those _mut methods give you a mutable reference to some original data. But you don't want to manipulate imgbuf, you want to extract information from it.

About row.. the docs tell you that it's some special type that's meant to implement an iterator on it's own. Check the type of Item to learn what it's iterating over: https://docs.rs/image/latest/image/buffer/struct.EnumeratePixelsMut.html#impl-Iterator-for-EnumeratePixelsMut<'a%2C P>
I assume that's (x, y, pixel).

Putting it all together, you could write it like this (I didn't compile it..)

let pixels: Vec<Vec<_>> = imgbuf.enumerate_rows().map(|(_, row)| row.map(|(x, _, px)| (x, px))).collect();

Although you probably want to do more in the inner map.

Imperative style would work too of course.
for (x, _, pixel) in row { should work.

quasi sable
#

for (x, _, pixel) in row { works, thanks

unborn onyx
#

Alright, misread your intentions then.

quasi sable
#

I didn't realize the iterator over the row returned the y coordinate as well

#

since the documentation wasn't very clear on it

unborn onyx
#

It's all there, but knowing what to look for takes some time

quasi sable
#

apologies if i came off as lazy or being unwilling to learn