Similar question has been asked many times. But I still don't get why I get too dark output after I converted a picture with ICC_Profile. I've tried many profiles: from Adobe site, and from the picture itself.
Before Image
After Image
Code
Iterator<ImageReader> readers = ImageIO.getImageReadersByFormatName("jpeg");
ImageReader reader = null;
while (readers.hasNext()){
reader = readers.next();
if (reader.canReadRaster()){
break;
}
}
// read
ImageInputStream ios = ImageIO.createImageInputStream(new FileInputStream(new File(myPic.jpg)));
reader.setInput(ios);
Raster r = reader.readRaster(0, null);
BufferedImage result = new BufferedImage(r.getWidth(), r.getHeight(), bufferedImage.TYPE_INT_RGB);
WritableRaster resultRaster = result.getRaster();
ICC_Profile iccProfile = ICC_Profile.getInstance(new File("profile_name.icc");
ColorSpace cs = new ICC_ColorSpace(iccProfile);
ColorConvertOp cmykToRgb = new ColorConvertOp(cs, result.getColorModel().getColorSpace(), null);
cmykToRgb.filter(r, resultRaster);
// write
ImageIo.write(resul, "jpg", new File("myPic.jpg"));
Do I have to do something else after I have converted the picture?
Like I said, the idea was to convert CMYK pictures to RGB, and use them in my application.
But for some reason ConvertOp doesn't do any CMYK to RGB conversion. It reduces numBand numbers to 3 and that's it. And I decided to try CMYKtoRGB algorithms.
i.e. Get an image, recognize its ColorSpace and read it or convert it.
Also another problem was Photoshop. This quote I found on the internet.
In the case of adobe it includes the CMYK profile in the metadata, but then saves the raw image data as inverted YCbCrK colors.
Finally I could achieve my goal with this algorithm below. I don't use icc_profiles so far, the output looks a little bit darker.. I got proper RGB images which looks fine.
pseudocode
BufferedImage result = null;
Raster r = reader.readRaster()
if (r.getNumBands != 4){
result = reader.read(0);
} else {
if (isPhotoshopYCCK(reader)){
result = YCCKtoCMYKtoRGB(r);
}else{
result = CMYKtoRGB(r);
}
}
private boolean isPhotoshopYCCK(reader){
// read IIOMetadata from reader and according to
// http://download.oracle.com/javase/6/docs/api/javax/imageio/metadata/doc-files/jpeg_metadata.html decide which ColorSpace is used
// or maybe there is another way to do it
int transform = ... // 2 or 0 or something else
return transform;
}
I doesn't make any sense to show YCCKtoCMYKtoRGB or CMYKtoRGB algorithms. It is easy to find on the internet.