4

i have a loaded image from disk (stored as a BufferedImage), which i display correctly on a JPanel but when i try to re-save this image using the command below, the image is saved in a reddish hue.

ImageIO.write(image, "jpg", fileName);

Note! image is a BufferedImage and fileName is a File object pointing to the filename that will be saved which end in ".jpg".

I have read that there were problems with ImageIO methods in earlier JDKs but i'm not on one of those versions as far as i could find. What i am looking for is a way to fix this issue without updating the JDK, however having said that i would still like to know in what JDK this issue was fixed in (if it indeed is still a bug with the JDK i'm using).

Thanks.

skaffman
  • 398,947
  • 96
  • 818
  • 769
Coder
  • 1,375
  • 2
  • 20
  • 45
  • Ok i found some more information. I tried saving the image as a png file and the colours are correct. So it's the jpg encoder that seems to be incorrect. It's really important for me to save the image as a jpg file as png files are large. Anybody have any further information? Is there maybe another mechanism to save the image as a jpg file, perhaps through the Toolkit? – Coder May 02 '10 at 17:41

3 Answers3

5

Ok, solved my problem, it seems that i need to convert the image to BufferedImage.TYPE_INT_RGB for some reason. I think the alpha channels might not be handled correctly at some layer.

Coder
  • 1,375
  • 2
  • 20
  • 45
  • Great to hear you have found a solution. As you know, I suggested changing the buffered image type in my answer, but without knowing the specifics of your image, I could not say with certainty which image type would work. – mdma May 02 '10 at 21:17
  • Yeah for sure, thanks again. I'm not sure how this whole voting thing works (i'm new to this forum) if that's what you are suggesting, but you have one point assigned for your answer. I don't know what a good place for this is, but this seems kind of appropriate to put here. As I have said, i just joined, but so far i'm really impressed with how polite and responsive this community is. It's a pleasure to be part of it. – Coder May 02 '10 at 22:28
  • +1 for helpful feedback. I would urge you to accept @mdma's answer, as it first identified the underlying problem. Of course, you can up-vote any answer you found useful, too. – trashgod May 03 '10 at 00:53
3

I would first start by investigating if it is the BifferedImage color model that is the problem or the jpeg encoding. You could try changing the image type (3rd argument in the constructor), to see if that produces a difference, and also use the JPEGCodec directly to save the jpeg.

E.g.

 BufferedImage bufferedImage = ...;  // your image
 out = new FileOutputStream ( filename );
 JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder ( out );
 JPEGEncodeParam param = encoder.getDefaultJPEGEncodeParam ( bufferedImage );
 encoder.setJPEGEncodeParam ( param );
 encoder.encode ( bufferedImage );
 out.close();

EDIT: changed text, it's the image type you want to change. See the link to the constructor.

mdma
  • 56,943
  • 12
  • 94
  • 128
  • Thanks for the suggestion. could you provide some code snippets please? If by using the codec directly, you mean Iterator writers = ImageIO.getImageWritersBySuffix("jpeg");, then i already tried that and it's the same behaviour. – Coder May 02 '10 at 14:32
  • I mean use the codec by using the snippet above to save your image to JPEG. – mdma May 02 '10 at 14:38
  • Thanks again, i tried what you suggested (copied your code exactly) and i get the same behaviour. So does that mean that the encoder is the problem? – Coder May 02 '10 at 14:49
  • We cannot conclude anything so far (the encoder may not be the problem, ir it exhibits the problem in both JPEGEncoder and ImageIO - makes sence since ImageIO probably uses JPEGEncoder internally.) Your next step is to try tweaking the BufferedImage. – mdma May 02 '10 at 16:02
  • tweaking the buffered image, how? – Coder May 02 '10 at 16:43
  • This method results in error with Java7: package com.sun.image.codec.jpeg does not exist; although there are some solutions this class can be deprecated in future and is not a good candidate to be used. – Zon Oct 25 '13 at 17:49
1

Another approach is to render the image in a TYPE_INT_ARGB buffer, has a DirectColorModel with alpha, as outlined below and suggested here.

private BufferedImage process(BufferedImage old) {
    int w = old.getWidth();
    int h = old.getHeight();
    BufferedImage img = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
    Graphics2D g2d = img.createGraphics();
    g2d.drawImage(old, 0, 0, null);
    g2d.dispose();
    return img;
}
Community
  • 1
  • 1
trashgod
  • 203,806
  • 29
  • 246
  • 1,045