image-rs / image

Encoding and decoding images in Rust
Apache License 2.0
4.77k stars 590 forks source link

Support `Rgba16` color type in decoder for Jpeg #1777

Open djc opened 1 year ago

djc commented 1 year ago

We're using the image crate for transcoding (and resizing etc) images for our Instant Site product at @InstantDomain. When we call DynamicImage::write_to() with ImageOutputFormat::Jpeg(75), we sometimes get an error:

The decoder for Jpeg does not support the color type `Rgba16`

I'm not sure what this does means exactly -- it seems weird that DynamicImage complains about decoder support only on write_to(), but mainly I'm wondering, how hard would it be to fix this? We can probably have someone implement this if you're able to provide us with some guidance. Conceptually it seems like shuffling the order of pixel components around is probably not hard to implement, but I don't have much experience in the image domain so could easily be underestimating this!

aschampion commented 1 year ago

I suspect the issue is you are sometimes getting 16-bit-per-channel images (Rgba16) and attempting to encode them as JPEG, which generally only supports 8-bit (I don't think we support encoding XT/XL and other extensions). The error message from UnsupportedError here is wrong; it's the encoder, not decoder, that doesn't support the color type. If you're only dealing with Rgba images you can first use DynamicImage::to_rgba8 to get a format appropriate for JPEG encoding. If you're dealing with other types of images (grayscale), you'll need to match the inner type of DynamicImage and convert to 8-bit RGB/RGBA/Luma as appropriate.

HeroicKatora commented 1 year ago

If you can sponsor encode/decode integration of JPEG XL (https://docs.rs/jpegxl-rs) that'd be great. We can surely give guidance in reviews and early design work if portions of bindings require it, i.e. how to dispatch over pixels given that the crate's frame structure takes it as a generic parameter.