问题
I have a code that turns a byte array into BufferedImage using ImageIO.
public void readImage(byte[] imageBytes) {
ByteArrayInputStream inputStream = new ByteArrayInputStream(imageBytes);
BufferedImage bufferedImage = null;
try {
bufferedImage = ImageIO.read(inputStream);
} catch (Exception e) {
e.printStackTrace();
}
// do something with bufferedImage
}
But I found that for certain jpeg images, it throws a CMMException, every time.
Here's the stack trace:
java.awt.color.CMMException: Cannot get color transform
at sun.java2d.cmm.lcms.LCMS.createNativeTransform(Native Method)
at sun.java2d.cmm.lcms.LCMSTransform.<init>(LCMSTransform.java:103)
at sun.java2d.cmm.lcms.LCMS.createTransform(LCMS.java:75)
at java.awt.image.ColorConvertOp.filter(ColorConvertOp.java:552)
at com.sun.imageio.plugins.jpeg.JPEGImageReader.acceptPixels(JPEGImageReader.java:1251)
at com.sun.imageio.plugins.jpeg.JPEGImageReader.readImage(Native Method)
at com.sun.imageio.plugins.jpeg.JPEGImageReader.readInternal(JPEGImageReader.java:1219)
at com.sun.imageio.plugins.jpeg.JPEGImageReader.read(JPEGImageReader.java:1022)
at javax.imageio.ImageIO.read(ImageIO.java:1438)
at javax.imageio.ImageIO.read(ImageIO.java:1342)
And here's the photo that's causing trouble
I searched on Google for a solution, and found a post acknowledging the problem and recommending to use JAI for cases where ImageIO fails. But I'm having doubts, as the post was from 4 years ago, and I can't seem to find much information about JAI, leading me to believe that that's not the ideal solution. Is there any other way to convert byte array into buffered image without ImageIO or JAI? And if JAI is still a solid solution today, could someone show me how to do that using JAI?
Thanks in advance!
回答1:
First of all, you can use my TwelveMonkeys JPEG plugin for ImageIO, it will read this JPEG. No need to change your code. From what I remember, the issue was that it contains a Corbis RGB ICC color profile, using an outdated or broken ICC profile format. My reader will patch the ICC profile at runtime, and read the image just fine.
Further, the LCMS references in the stack trace indicates you are either on OpenJDK or, Java 8. For Java 8 at least, there is a switch
-Dsun.java2d.cmm=sun.java2d.cmm.kcms.KcmsServiceProvider
to re-enable the Kodak CMS (used in all Sun/Oracle JREs pre Java 8), after LittleCMS was chosen as the default from Java 8. There are minor differences in how these color management systems handle ICC profiles, so setting this switch might help in certain cases.
Update: I just tried to read the image, and Java version 1.7.0_60 could read the image, however the colors are slightly off (it gets a purple tint, like in Chrome), because the ICC profile is ignored. This might be good enough for you. If not, use the TwelveMonkeys JPEG plugin. :-)
来源:https://stackoverflow.com/questions/24688780/read-byte-array-into-buffered-image-without-imageio