image icon indicating copy to clipboard operation
image copied to clipboard

SubImage pixels_mut() function from GenericImage trait

Open arthmis opened this issue 6 years ago • 5 comments

Since pixels_mut() from the GenericImage trait is deprecated, is there an alternative to looping through the pixels for a subimage or should I convert it to an image buffer then loop?

arthmis avatar May 04 '19 04:05 arthmis

Honestly, there's nothing wrong with just looping through the coordinates calling get_pixel_mut or get_pixel + put_pixel. The optimizer is pretty smart and should be able to generate quite fast code from that. The one thing to watch out for is that for cache reasons you'll want to have the innermost loop go in the horizontal direction:

for y in 0..height { 
    for x in 0..width {
        let p = img.get_pixel_mut(x, y);
        ...
    }
}

fintelia avatar May 04 '19 04:05 fintelia

I tried drafting an interface once that would allow us to optimize certain cases such as rows/columns of contiuous pixels: see #866. But not currently in the library and nowhere near finished.

197g avatar May 04 '19 11:05 197g

I would like to propose an idea of two image traits, one for random access to pixels and one for the simpler cases of iterating over pixels in row-major order. This makes it possible to implement operations that need random access on that trait, and other operations can be implemented on the more general trait.

birktj avatar May 04 '19 12:05 birktj

@fintelia Thank you! I wasn't sure it would be as optimized.

arthmis avatar May 04 '19 13:05 arthmis

@lazypassion In the case of ImageBuffer/DynamicImage the iterator is as optimized as iterating yourself. I have a feeling it might not be as fast as iterating over a pure slice of data but I don't have any data pointing either way.

197g avatar May 04 '19 13:05 197g

Closing as not-planned. PixelsMut would need unsafe internally in order to yield &mut _ references that live as long as the underlying reference. We don't require GenericImage to adhere to any contract where different coordinates are different pixels. The iterators on ImageBuffer however have all local information to provide the necessary guarantees. Without rehashing this in detail, it's unfortunately only possible when using an ImageBuffer or ViewMut type instead of a generic parameter impl GenericImage.

197g avatar Aug 08 '25 14:08 197g