Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jpeg image color gets drastically changed after just ImageIO.read() and ImageIO.write()

I have been using ImageIO.read() and ImageIO.write() methods in javax.imageio.ImageIO for reading and writing images, and I found that some images' color gets changed weirdly.

Even if I change my code to do nothing but just read images and write them (with jpeg, png, gif), all those new images have the same issue.

Do I need to add any other code before/after ImageIO.read/write methods?

Here is the code I used:

    File f = new File("obw.jpg");
    BufferedImage bi = ImageIO.read(f);
    FileOutputStream fos2 = new FileOutputStream("obw2.jpg");
    ImageIO.write(bi, "JPG", fos2);
    FileOutputStream fos3 = new FileOutputStream("obw3.gif");
    ImageIO.write(bi, "GIF", fos3);
    FileOutputStream fos4 = new FileOutputStream("obw4.png");
    ImageIO.write(bi, "PNG", fos4);

My environment:

    java version "1.6.0_35"
    MacOSX 10.8.2

Original Image: enter image description here

One of images after read and write:

enter image description here

like image 350
UGO Avatar asked Oct 25 '12 15:10

UGO


People also ask

What does ImageIO write do?

ImageIO can write multiple images, image metadata, and determine quality vs. size tradeoffs.

Can ImageIO read JPG?

imageio package. Image I/O has built-in support for GIF, PNG, JPEG, BMP, and WBMP. Image I/O is also extensible so that developers or administrators can "plug-in" support for additional formats. For example, plug-ins for TIFF and JPEG 2000 are separately available.

What is the use of ImageIO class?

ImageIO provides ImageReader and ImageWriter plug-ins for the Graphics Interchange Format (GIF) image format.

What is ImageIO in Java?

ImageIO is a utility class which provides lots of utility method related to images processing in Java. Most common of them is reading form image file and writing images to file in java. You can write any of . jpg, . png, .


1 Answers

Your problem is that ImageIO is misinterpreting the YCbCr data in your JPEG as RBG data. The relevant Java bugs are 4712797 and 4776576, which Oracle wrongly claims were fixed in Java 1.4, but in reality still afflict some Java 5, 6, and 7 JVMs.

In a project I work on, we've dealt with this problem by loading a specially-constructed test JPEG with a single black pixel to see if ImageIO loads it properly. If the pixel comes up green, then ImageIO is misinterpreting the image data, so when we load JPEGs later and we detect the sort of JPEG which causes the problem, we also apply a color correction. (The kind of JPEG which triggers the problem in JVMs which exhibit it has a particular kind of subsampling and no JFIF marker.)

Here's some LGPLv2-licensed code which deals with the problem. The need for code like this to work around dozen-year-old bugs when the whole rest of the world manages to load JPEGs properly is one of the reasons I want Java to die in a fire.

like image 185
uckelman Avatar answered Oct 12 '22 01:10

uckelman