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

Cannot create a single channel image #171

Open
jice-nospam opened this issue Oct 24, 2022 · 11 comments
Open

Cannot create a single channel image #171

jice-nospam opened this issue Oct 24, 2022 · 11 comments
Labels
bug Something isn't working

Comments

@jice-nospam
Copy link

Description

When using a single channel image, the pixel function should return a (f32) which is as far as I understand simplified into f32 by the compiler. This results in a compilation error :

the trait bound `f32: IntoRecursive` is not satisfied

Reproducing

let channels = SpecificChannels::build()
        .with_channel("H")
        .with_pixel_fn(|_| {
            (0.0f32)
        });

Environment

  • Windows 10
  • EXRS Version 1.5.2
@jice-nospam jice-nospam added the bug Something isn't working label Oct 24, 2022
@johannesvollmer
Copy link
Owner

johannesvollmer commented Oct 24, 2022

thanks for taking the time :)
yes, this is probably a design issue in exrs. I think this is an edge case that was never tested. should be rather simple to fix

@johannesvollmer
Copy link
Owner

johannesvollmer commented Oct 24, 2022

If you need a workaround, there are multiple options.

You could add a second optional channel and ignore it (very dirty)

You can also use dynamic channels, which loads all the channels without the need to specify them, and then you can extract the channel you are interested in.

.largest_resolution_level().all_channels().all_layers().all_attributes()

@jice-nospam
Copy link
Author

I'm actually trying to write a single channel file (used as a heightmap). For now I'm adding a second channel filled with zeroes :)

@johannesvollmer
Copy link
Owner

Oh yeah, oopsie. In either case, there is another option: use a custom struct that knows your image data, and make it implement WritableChannels. You can pass your struct into a layer, instead of using SpecificChannels, like in this example:

SpecificChannels::rgba(|_pos| (0.8_f32, 0.5_f32, 0.1_f32, 1.0_f32)),

@jice-nospam
Copy link
Author

I tried this way but it seems very complex for what I need, I'll keep my empty channel for now.
Also using globally the exr prelude breaks all the code because you redefine Result. You shouldn't do that!

@johannesvollmer
Copy link
Owner

Yes, if the second channel workaround works for you, it's definitely the nicest code

@johannesvollmer
Copy link
Owner

johannesvollmer commented Oct 25, 2022

Would it solve the other issue to export a type alias ExrResult in the prelude, but keep the original type name Result internally?

@jice-nospam
Copy link
Author

yes I think it would fix the issue

@johannesvollmer
Copy link
Owner

johannesvollmer commented Oct 25, 2022

Have you tried using the tuple syntax for creating tuples with one value? The Syntax looks like this:
let tuple = (value,)

let channels = SpecificChannels::build()
        .with_channel("H")
        .with_pixel_fn(|_| {
            (0.0f32,)
        });

@jice-nospam
Copy link
Author

oh yes it works ! thanks I didn't know this syntax !

@johannesvollmer
Copy link
Owner

johannesvollmer commented Oct 25, 2022

Nice to have it working - but let's keep the issue open, because exrs can be improved nevertheless. IntoRecursive should be implemented for f32.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants