Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Overhaul Pixel methods on ImageBuffer and GenericImage/GenericImageView traits #1920

Closed
wants to merge 4 commits into from

Conversation

okaneco
Copy link
Contributor

@okaneco okaneco commented Apr 30, 2023

#1853 for background

Best viewed commit by commit. Most of the changes are in the first commit.

This PR adds Option-returning methods to the main image traits. Duplicate methods that ImageBuffer implemented were removed.

I migrated functions that used the old methods like get_pixel internally to the newer Option methods where applicable so they could eventually be phased out. Where possible, I kept the old behavior by using Index access on ImageBuffers. Since this is a breaking change, I also removed the deprecated functions from the traits.

  • Add pixel[_unchecked] to GenericImageView
  • Add pixel_mut[_unchecked] to GenericImage
  • Remove get_pixel_mut, blend_pixel from GenericImage
  • Remove get_pixel[_checked], get_pixel_mut[_checked] from ImageBuffer
  • Move the inner implementation of get_pixel[_mut] to Index, IndexMut
  • Add pixel_i64 to GenericImageView, pixel_mut_i64 to GenericImage

okaneco added 4 commits April 30, 2023 14:36
Add `pixel[_unchecked]` to GenericImageView
Add `pixel_mut[_unchecked]` to GenericImage
Remove `get_pixel_mut`, `blend_pixel` from GenericImage
Migrate uses of the old pixel functions to new counterparts in
buffer, flat, image, encoder, and imageops

DynamicImage can't implement the the new methods so they're left
unimplemented.
Remove `get_pixel[_checked]`, `get_pixel_mut[_checked]` from ImageBuffer
Move the inner implementation of `get_pixel[_mut]` to `Index`, `IndexMut`
Fix corresponding tests and imageops to use Index[Mut]
Replace uses in gif and png modules
Add `pixel_i64` to `GenericImageView`,`pixel_mut_i64` to `GenericImage`
Add tests for both on `ImageBuffer`
Update doc tests
Update fractal.rs example
@fintelia
Copy link
Contributor

There's a lot going on in this PR and it will potentially break a lot of existing user code. Thanks for putting this all together, but in its current form, it is probably too big to review and merge.

Some more detailed thoughts:

  • get_pixel_mut and blend_pixel are already deprecated. Makes sense to remove them.
  • Not sure we should be adding pixel_mut[_unchecked] without fixing the problems with get_pixel_mut.
  • The pixel[_mut]_i64 changes seem separate from the rest. Not yet convinced they're worth adding, but either way they would be better as a standalone PR.
  • I'm not really convinced by the Index / IndexMut changes. I haven't seen that pattern used much in Rust, and for such sweeping changes I want to be very sure we're making things more idiomatic rather than less

@okaneco
Copy link
Contributor Author

okaneco commented May 1, 2023

I understand, also don't want to cause too much unnecessary breakage. I'm not sure if sealed extension traits would make sense for forward compatibility and being able to implement newer methods like these.

  • I'd like to see the problems fixed with get_pixel_mut but not sure how that can be solved for different containers or layouts.

  • Agree that the i64 can be a separate change.

  • The indexing method was listed earlier in the readme for the buffer example, so I never saw it as unidiomatic but that might not be a commonly held opinion.

    image/README.md

    Lines 101 to 105 in 139420d

    // Access the pixel at coordinate (100, 100).
    let pixel = img[(100, 100)];
    // Or use the `get_pixel` method from the `GenericImage` trait.
    let pixel = *img.get_pixel(100, 100);

During this PR, I remembered when I was first learning Rust and how I struggled with understanding traits and this crate. Sometimes I had to dereference get_pixel and sometimes not, eventually understanding the problem.

// ImageBuffer
fn get_pixel(&self, x: u32, y: u32) -> &P
// GenericImageView
fn get_pixel(&self, x: u32, y: u32) -> P

The readme needs to be corrected because it's not using the trait method but the ImageBuffer version so it has to dereference on L105. The current state can be confusing to new users but anything to address or deprecate the method will likely cause a lot of churn with CI warnings.
https://docs.rs/image/latest/image/struct.ImageBuffer.html#method.get_pixel
https://docs.rs/image/latest/image/struct.ImageBuffer.html#method.get_pixel-1

@okaneco okaneco closed this May 1, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants