JPEG image with wrong colors

I found a solution now, that works, at least if my resulting image is also a JPEG: First I read the image (from byte array imageData), and most important, I also read the metadata.

InputStream is = new BufferedInputStream(new ByteArrayInputStream(imageData));
Image src = null;
Iterator<ImageReader> it = ImageIO.getImageReadersByMIMEType("image/jpeg");
ImageReader reader = it.next();
ImageInputStream iis = ImageIO.createImageInputStream(is);
reader.setInput(iis, false, false);
src = reader.read(0);
IIOMetadata imageMetadata = reader.getImageMetadata(0);

Now i'd do some converting (i.e. shrink in size) ... and at last I'd write the result back as a JPEG image. Here it is most important to pass the metadata we got from the original image to the new IIOImage.

Iterator<ImageWriter> iter = ImageIO.getImageWritersByMIMEType("image/jpeg");
ImageWriter writer = iter.next();
ImageWriteParam iwp = writer.getDefaultWriteParam();
iwp.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
iwp.setCompressionQuality(jpegQuality);
ImageOutputStream imgOut = new MemoryCacheImageOutputStream(out);
writer.setOutput(imgOut);
IIOImage image = new IIOImage(destImage, null, imageMetadata);
writer.write(null, image, iwp);
writer.dispose();

Unfortunately, if I'd write a PNG image, I still get the wrong colors (even if passing the metadata), but I can live with that.


I had a similar problem.I had to use:

Image image = java.awt.Toolkit.getDefaultToolkit().getImage(path);

instead of

Image image = javax.imageio.ImageIO.read(new File(path));

I had similar problems, the BufferedImage returned is a rendition based if there is transparent pixel, which will be set true for most png/gif type of files. But when converting to jpeg this flag should be set to false. You need possibly to write a method, where the conversion is properly handled. i.e.:

public static BufferedImage toBufferedImage(Image image) {
...
}

Otherwise that "marunish" overtone becomes the saved result. :)



I was running into this issue, and I actually found a third party library that handled this for me. https://github.com/haraldk/TwelveMonkeys

Literally all I had to do was include this in my maven dependencies and the jpegs that were coming out in weird colors started getting read in normally. I didn't even have to change a line of code.


I had a similar problem when trying to convert an image from a byte array to Base64. It appears the problem is caused by images with an alpha channel. When saving an image with an alpha channel, the alpha channel is saved too and some external programs that are used to read the image interpret the 4 channels as CMYK.

Found a simple workaround, by removing the alpha channel of the BufferedImage. This may be stupid but it sure worked for me.

//Read the image from a byte array
BufferedImage bImage = ImageIO.read(new ByteArrayInputStream(byteArray));

//Get the height and width of the image
int width = bImage.getWidth();
int height = bImage.getHeight();

//Get the pixels of the image to an int array 
int [] pixels=bImage.getRGB(0, 0,width,height,null,0,width);

//Create a new buffered image without an alpha channel. (TYPE_INT_RGB)
BufferedImage copy = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);

//Set the pixels of the original image to the new image
copy.setRGB(0, 0,width,height,pixels,0,width);