我有一个代码,使用ImageIO将字节数组转换为BufferedImage。
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
}
但我发现对于某些jpeg图像,每次都会抛出CMMException。
这是堆栈跟踪:
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)
这是造成问题的照片
我在Google上搜索了一个解决方案,发现了一个确认问题的帖子,并建议在ImageIO出现故障的情况下使用JAI。但是我怀疑,因为这篇帖子来自4年前,我似乎无法找到关于JAI的更多信息,让我相信这不是理想的解决方案。有没有其他方法可以在没有ImageIO或JAI的情况下将字节数组转换为缓冲图像?如果JAI今天仍然是一个可靠的解决方案,有人可以告诉我如何使用JAI吗?
提前致谢!
答案 0 :(得分:1)
首先,您可以将我的TwelveMonkeys JPEG plugin用于ImageIO,它将read this JPEG。无需更改代码。根据我的记忆,问题是它包含Corbis RGB ICC颜色配置文件,使用过时或损坏的ICC配置文件格式。我的读者将在运行时修补ICC配置文件,并仔细阅读图像。
此外,堆栈跟踪中的LCMS引用表明您使用的是OpenJDK或Java 8.至少对于Java 8,有一个开关
在Java 8中选择LittleCMS作为默认值之后,-Dsun.java2d.cmm=sun.java2d.cmm.kcms.KcmsServiceProvider
重新启用柯达CMS(在Java 8之前的所有Sun / Oracle JRE中使用)。这些颜色管理系统处理ICC配置文件的方式略有不同,因此在某些情况下设置此开关可能会有所帮助
更新:我只是试图读取图像,Java版本1.7.0_60可以读取图像,但颜色稍微偏离(它会像Chrome一样呈现紫色),因为ICC配置文件被忽略。这对你来说可能已经足够了。如果没有,请使用TwelveMonkeys JPEG插件。 : - )