PngEncoder set_icc_profile doesn't work
"image" version: 0.25.5 rustc version: 1.84.0 target: stable-aarch64-apple-darwin profile: release
Expected
Running set_icc_profile followed by write_image on an instance of PngEncoder saves the image with the provided ICC profile
Actual behaviour
Image is saved but with no ICC profile
Reproduction steps
You can find the profile I used at: https://github.com/ellelstone/elles_icc_profiles/
Code:
use std::{fs, io::Read, vec};
use image::{codecs::png::{CompressionType, FilterType, PngEncoder}, ExtendedColorType::Rgb16, ImageEncoder};
fn read_file_bytes(path: &str) -> Vec<u8> {
let file = fs::File::open(path).unwrap();
let mut buf_reader = std::io::BufReader::new(file);
let mut bytes = Vec::new();
buf_reader.read_to_end(&mut bytes).unwrap();
bytes
}
fn main() {
let width = 10;
let height = 10;
let image_bytes = vec![0u8; width * height * 6];
let icc_profile = read_file_bytes("data/sRGB-elle-V4-g10.icc");
fs::create_dir_all("output").unwrap_or_default();
let mut encoder = PngEncoder::new_with_quality(
fs::File::create("output/test.png").unwrap(),
CompressionType::Best,
FilterType::Adaptive,
);
encoder.set_icc_profile(icc_profile.to_vec()).unwrap_or_default();
encoder
.write_image(
&image_bytes,
width as u32,
height as u32,
Rgb16
)
.unwrap();
}
ExifTool check:
$ exiftool -icc_profile -b -w icc dir/output/test.png
0 output files created
GIMP also didn't recognize the profile in the image
Notes
I considered that the ICC profile might be invalid, or that I'm doing something wrong
So I embedded the profile to a new image using GIMP, and read it's bytes using PngDecoder
The bytes exactly matched the contents of the original ICC file
Also, ExifTool recognized the profile in the new image
Could you check what version of the png crate you're using? There was a bug in ICC encoding in the 0.17.15 version that was fixed in the next release
I tried to reproduce and with the current version the ICC file is extract as expected (and bit-by-bit identical to the input as it should).