The reason I was asking, is I don't think your ICC profile is a deflate compressed byte[]
. You state "This is not the problem", but I really think it is. :-)
If I don't apply deflate compression to the ICC profile, I get a similar warning from ExifTool as you get from identify.
Warning : Error inflating iCCP
ICC Profile : (Binary data 526 bytes, use -b option to extract)
If I properly apply deflate compression to the ICC profile, the ICC profile is correctly identified as "Adobe RGB 1998".
Profile CMM Type : ADBE
Profile Version : 2.1.0
Profile Class : Display Device Profile
Color Space Data : RGB
[...]
CMM Flags : Not Embedded, Independent
Rendering Intent : Perceptual
Connection Space Illuminant : 0.9642 1 0.82491
Profile Creator : ADBE
Profile ID : 0
Profile Copyright : Copyright 2000 Adobe Systems Incorporated
Profile Description : Adobe RGB (1998)
The following code works for me:
public class PNGICCProfileIssue {
public static void main(String[] args) throws IOException {
File input = new File(args[0]);
BufferedImage image = ImageIO.read(input);
Iterator<ImageWriter> writers = ImageIO.getImageWritersByFormatName("PNG");
if (!writers.hasNext()) {
return;
}
ImageWriter writer = writers.next();
writer.setOutput(ImageIO.createImageOutputStream(new File(input.getParent(), input.getName().replace('.', '_') + "_icc.png")));
IIOMetadata imageMetadata = writer.getDefaultImageMetadata(ImageTypeSpecifier.createFromRenderedImage(image), writer.getDefaultWriteParam());
//add ICC PROFILE
IIOMetadataNode iccp = new IIOMetadataNode("iCCP");
ICC_ColorSpace colorSpace = (ICC_ColorSpace) ColorSpaces.getColorSpace(ColorSpaces.CS_ADOBE_RGB_1998);
iccp.setUserObject(getAsDeflatedBytes(colorSpace));
iccp.setAttribute("profileName", "AdobeRGB1998");
iccp.setAttribute("compressionMethod", "deflate");
Node nativeTree = imageMetadata.getAsTree(imageMetadata.getNativeMetadataFormatName());
nativeTree.appendChild(iccp);
imageMetadata.mergeTree(imageMetadata.getNativeMetadataFormatName(), nativeTree);
writer.write(new IIOImage(image, null, imageMetadata));
}
private static byte[] getAsDeflatedBytes(ICC_ColorSpace colorSpace) throws IOException {
byte[] data = colorSpace.getProfile().getData();
ByteArrayOutputStream deflated = new ByteArrayOutputStream();
DeflaterOutputStream deflater = new DeflaterOutputStream(deflated);
deflater.write(data);
deflater.flush();
deflater.close();
return deflated.toByteArray();
}
I think this requirement should have been documented in the metadata documentation, as I have to give you it is kind of confusing..
Good luck!