使用javax.imageio.ImageIO读取JPEG图片时出现异常java.awt.color.CMMException: General CMM error517

目录

    • 问题描述
        • 背景
        • 异常
    • 解决
        • 重现
        • 紧急处理
        • 解决方法
          • 第一种:变更JDK版本
          • 第二种:去掉引入的twelvemonkeys图片读取插件

问题描述

背景

由于业务需要,生产环境需要将用户上传的图片压缩。
使用javax.imageio.ImageIO.read(java.io.File input) 方法读取图片。代码如下:

BufferedImage img = ImageIO.read(file);

此处需要说明我们生产环境的JDK版本为1.6.0_45。
该功能在生产环境已经使用了2年。之前出现过一次问题,是读取CMYK模式的图片时,会抛出异常“Unsupported Image Type”。
由于系统中很多地方都使用了这样的读取图片方式,我的解决方法尽量没有去改代码。是引入了四个jar包:common-lang-3.0.2.jar,imageio-core-3.0.2.jar,imageio-jpeg-3.0.2.jar,imageio-metadata-3.0.2.jar,然后在web.xml文件中添加如下配置

    
    <listener>
        <display-name>ImageIO service provider loader/unloaderdisplay-name>
        <listener-class>com.twelvemonkeys.servlet.image.IIOProviderContextListenerlistener-class>
    listener>

当时已经解决,并且测试通过。

异常

生产使用中发现读取个别图片时,发下如下异常:

Exception in thread "main" java.awt.color.CMMException: General CMM error517
 	at sun.java2d.cmm.kcms.CMM.checkStatus(CMM.java:180)
 	at sun.java2d.cmm.kcms.CMM.createTransform(CMM.java:134)
 	at java.awt.image.ColorConvertOp.filter(ColorConvertOp.java:540)
 	at com.twelvemonkeys.imageio.plugins.jpeg.JPEGImageReader.readImageAsRasterAndReplaceColorProfile(Unknown Source)
 	at com.twelvemonkeys.imageio.plugins.jpeg.JPEGImageReader.read(Unknown Source)
 	at javax.imageio.ImageIO.read(ImageIO.java:1448)
 	at javax.imageio.ImageIO.read(ImageIO.java:1308)

解决

重现

我将用户上传的图片导出,然后在本地写了一个简单的Test,模拟生产的环境和操作,对所有图片进行压缩。压缩到其中一个图片的时候,出现了上述异常。移出该图片之后,压缩正常执行。

紧急处理

为不影响用户使用,我使用光影魔术手(因为免费)将出现异常的图片另存为了一个副本文件。发现副本文件可以压缩了,就使用副本文件替换了生产上的图片。我还试了使用windows的画图另存,然而画图并没有解决问题。
使用javax.imageio.ImageIO读取JPEG图片时出现异常java.awt.color.CMMException: General CMM error517_第1张图片

解决方法

第一种:变更JDK版本

使用搜索引擎查询了这个异常,只找到JDK1.8以上可以解决这个问题,并没有找到低版本的JDK怎么处理1。我更改了我本地Test的JDK版本做了验证,执行结果如下:

JDK版本 执行结果
jdk1.6.0_45 异常
jdk1.7.0_45 异常
jdk1.8.0_25 正常

这种方法风险太大,而且一个大系统要升级版本可能就需要投入很多资源,解决一个小功能,投入这么多显然不划算。

第二种:去掉引入的twelvemonkeys图片读取插件

由于使用twelvemonkeys插件之前没有遇到过这种异常,我想会不会跟这个有关。
我取消引入之后,发现出问题的图片可以正常读取了。
对比如下图:
使用javax.imageio.ImageIO读取JPEG图片时出现异常java.awt.color.CMMException: General CMM error517_第2张图片
红框中为引入的插件加载的JPEGImageReader
使用javax.imageio.ImageIO读取JPEG图片时出现异常java.awt.color.CMMException: General CMM error517_第3张图片
没引入twelvemonkeys插件,读取正常

那么我的解决方法就是取消引入twelvemonkeys插件,直接修改代码。使用这个链接中提供的方法读取CMYK图片。
我们新版本的系统即将使用1.8的JDK,我就不这么搞了。


  1. openjdk的bug描述. ↩︎

你可能感兴趣的:(ImageIO,Java,JPEG)