Color changed after decode/encode by image-rs
Expected
Images are identical
Actual behaviour
The green color of texts were changed after decode/encode by image-rs
Reproduction steps
use std::error;
use std::fs;
use image::load_from_memory;
type Result<T> = std::result::Result<T, Box<dyn error::Error>>;
fn main() -> Result<()> {
let raw_png = fs::read("hulu.png")?;
let dynamic_image = load_from_memory(&raw_png)?;
dynamic_image.save_with_format("hulu-image.png", image::ImageFormat::Png)?;
Ok(())
}
- clone https://github.com/Brooooooklyn/image-rs-wrong-color
- cargo run
| Raw | Decode/Encode by image-rs |
|---|---|
![]() |
![]() |
Can you be more precise or recheck? The images in the columns contain literally the same pixel matrix:
$ png2pnm /tmp/hulu.png > /tmp/hulu.pnm
$ png2pnm /tmp/hulu-image.png.png > /tmp/hulu-image.pnm
$ diff /tmp/hulu.pnm /tmp/hulu-image.pnm
Oops, messed up paths, I see it now. Probably color profiles which we definitely are not doing properly through the whole chain.
Wait.. Wait.. The initial observation was correct. Pixels are literally the same value. The difference is simply because we're dropping the color profile chunks.
Original chunks:
ChunkType { type: IHDR, critical: true, private: false, reserved: false, safecopy: false }
ChunkType { type: iCCP, critical: false, private: false, reserved: false, safecopy: false }
ChunkType { type: eXIf, critical: false, private: false, reserved: false, safecopy: true }
ChunkType { type: pHYs, critical: false, private: false, reserved: false, safecopy: true }
ChunkType { type: iTXt, critical: false, private: false, reserved: false, safecopy: true }
ChunkType { type: iDOT, critical: false, private: false, reserved: false, safecopy: false }
ChunkType { type: IDAT, critical: true, private: false, reserved: false, safecopy: false }
[… some more IDAT]
After chunks:
ChunkType { type: IHDR, critical: true, private: false, reserved: false, safecopy: false }
ChunkType { type: IDAT, critical: true, private: false, reserved: false, safecopy: false }
OK: /tmp/hulu-image.png (3008x1904, 8-bit RGB+alpha, non-interlaced, 81.5%)
Any workaround for this issue?
Any progress on fixing this issue?
There actually has been some progress! We've now got an icc_profile method on the ImageDecoder trait which provides the low level API to query the color profile for an image. The next step would be to expose the ability to set a color profile when saving an image

