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

Building and manipulating Image objects pixel-by-pixel is very tedious and error prone #11887

Open
alice-i-cecile opened this issue Feb 16, 2024 · 5 comments
Labels
A-Rendering Drawing game state to the screen C-Feature A new feature, making something new possible

Comments

@alice-i-cecile
Copy link
Member

What problem does this solve or what need does it fill?

Building images from programmatically controlled data can be a useful tool for getting reasonably high performance without having to swap to shaders. Staying in pure Rust is great: I've previously used this to quickly hack together a minimap.

However, the APIs for constructing and accessing an Image is painful: offering only access to the raw data.

What solution would you like?

I would like:

  1. Image::from_colors, which takes a 2 dimensional vector of Color types, converted into the format of the user's choice.
  2. Image::get_pixel, which returns the color at the provided pixel.
  3. Image::set_pixel, which sets the value of the data at the provided pixel.

What alternative(s) have you considered?

We could construct a higher level abstraction for this, which then gets converted into an image?

We could also say that this is an abuse of the API, and point users to a more appropriate solution.

@alice-i-cecile alice-i-cecile added C-Feature A new feature, making something new possible A-Rendering Drawing game state to the screen labels Feb 16, 2024
@shanecelis
Copy link
Contributor

I decided to take this on. I have a preliminary implementation here: pixel.rs.

I'm curious, which of the TextureFormats do we want to support? I've implemented support for Rgba8Unorm(Srgb) and the R8*s for get_pixel() just to get a feeling for what that would look like.

The Unorm and Snorm formats seem useful for pixel operations. I'm less convinced the Uint and Sint would be practical.

I implemented the requested methods above. However, I see now I've deviated on the Image::from_colors specification. I accept a 1D array and don't accept a format. I can amend that but I do think two dimensional arrays are awkward to work with. Any suggestions on the actual type? Maybe Vec<[C; N]> would at least ensure it's a valid form.

I also implemented Image::pixels which returns an iterator of the color. It's not necessary. I can drop it but might be a nice way to feed into from_colors however.

For the get and set pixel, I made it work with linear or cartesian indices. Sometimes one form is immensely more helpful than the other, so let's do both if it doesn't hurt the ergonomics was my thought.

@shanecelis
Copy link
Contributor

Looks like there is a more mature implementation here.

@mintlu8
Copy link
Contributor

mintlu8 commented Aug 13, 2024

I think I'd rather use a rusttyle like API

Image::construct(usize, usize, impl FnMut(usize, usize) -> LinearRgba))

@rparrett
Copy link
Contributor

rparrett commented Aug 17, 2024

Related: #1502

@shanecelis
Copy link
Contributor

In the discord someone mentioned that DynamicImage actually has a lot of this functionality already. See RgbImage. But it doesn't use bevy's Color. Perhaps that would be the right implementation avenue though.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-Rendering Drawing game state to the screen C-Feature A new feature, making something new possible
Projects
None yet
Development

No branches or pull requests

4 participants