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:
One of images after read and write:
ImageIO can write multiple images, image metadata, and determine quality vs. size tradeoffs.
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.
ImageIO provides ImageReader and ImageWriter plug-ins for the Graphics Interchange Format (GIF) image format.
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, .
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With