It seems that ImageIO thinks to have a CMYK image due to the 4 channels and does it all wrong. I tried to find a way of telling imageio to take only the 3 RGB channels and I also found something like that, but it still generates very strange files that are too big (about 3 times as big as they should be) and don't display correctly on some viewers.
Here's my code:
-----
File file = new File(filename);
ios = ImageIO.createImageOutputStream(file);
writer.setOutput(ios);
// Set some parameters
ImageWriteParam param = writer.getDefaultWriteParam();
if (param.canWriteCompressed() && quality >= 0.0 && quality <= 1.0) {
param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
param.setCompressionQuality(quality);
}
// if bi has type ARGB and alpha is false, we have to tell the writer to not use the alpha channel:
// this is especially needed for jpeg files where imageio seems to produce wrong jpeg files right now...
if (bi.getType() == BufferedImage.TYPE_INT_ARGB) {
// create a new ColorModel with OPAQUE transparency and no alpha channel.
ColorModel cm = new ComponentColorModel(bi.getColorModel().getColorSpace(), false, false, Transparency.OPAQUE, DataBuffer.TYPE_BYTE);
// tell the writer to only use the first 3 bands (skip alpha)
param.setSourceBands(new int[] {0, 1, 2});
// although the java documentation says that SampleModel can be null, an exception is thrown in that case
// therefore a 1*1 SampleModel that is compatible to cm is created:
param.setDestinationType(new ImageTypeSpecifier(cm, cm.createCompatibleSampleModel(1, 1)));
}
// Write the image
writer.write(null, new IIOImage(bi, null, null), param);
ios.flush();
-----
The interesting part happens in here:
-----
// create a new ColorModel with OPAQUE transparency and no alpha channel.
ColorModel cm = new ComponentColorModel(bi.getColorModel().getColorSpace(), false, false, Transparency.OPAQUE, DataBuffer.TYPE_BYTE);
// tell the writer to only use the first 3 bands (skip alpha)
param.setSourceBands(new int[] {0, 1, 2});
// although the java documentation says that SampleModel can be null, an exception is thrown in that case
// therefore a 1*1 SampleModel that is compatible to cm is created:
param.setDestinationType(new ImageTypeSpecifier(cm, cm.createCompatibleSampleModel(1, 1)));
-----
If I replace this with the following it all works well, but this uses far too much memory due to the allocation of another BufferedImage:
-----
BufferedImage buffered = new BufferedImage(bi.getWidth(null), bi.getHeight(null), BufferedImage.TYPE_INT_RGB);
buffered.createGraphics().drawImage(bi, 0, 0, null);
bi = buffered;
-----
Does anyone have experiences with this? What exactly am I doing wrong?
Best
Jürg Lehni
=========================================================================== To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message "signoff JAVA2D-INTEREST". For general help, send email to [EMAIL PROTECTED] and include in the body of the message "help".