代码之家  ›  专栏  ›  技术社区  ›  Alexander Terekhov

Java 8 ImageIO在Linux中错误读取JPEG

  •  6
  • Alexander Terekhov  · 技术社区  · 10 年前

    我正在尝试读取用户上传的JPEG图像(任意),以在服务器应用程序中创建缩略图。 系统在Windows7/Oracle Java 8u11中运行正常,但我在CentOS服务器上的颜色模型有问题:

    原始图像为:

    http://studio-st.ru/media/portfolio/image/45

    在Windows下的开发工作站上生成的缩略图是绝对正确的

    Linux下的结果是颜色偏移(在Java 8u05上为红色,在Java 8u11上为颜色偏移)。此处未显示,因为原始示例在现场,现在已修复。

    更深入的调查表明,问题是在读取图像时-Windows和Linux上的ImageIO.read(inputStream)返回的图像对象具有完全相同的参数,但是对于相同的图像(仅读取),颜色探针getRGB(x,y)返回的值不同。

    在Java 8u05&8u11,8u05为“红色”,8u11如上所示。

    这与alpha通道无关-这个特定的源图像是JPEG Type 5(Type_3BYTE_BGR),从Adobe Lightroom导出并转换为sRGB,没有任何其他技巧。

    这也会影响当时导出的所有图像(事实上,该站点上的所有图像)。

    有人能就如何使其工作提供一些建议吗(除了等待JDK的修复程序)?也许建议您使用另一个库,它可以在这里使用(EJB,存储在MongoDB中的数据,所以数据是使用InputStreams获取的-无文件系统访问)。

    谢谢

    更新日期: 问题似乎是Java8的新颜色管理模块——它不理解这种图像格式。切换到传统CMM解决了这个问题。请在下面的正确评论中查看详细信息。

    1 回复  |  直到 10 年前
        1
  •  4
  •   Harald K    10 年前

    你可以试试用我的 JPEGImageReader plugin 对于ImageIO,它处理颜色转换的方式与默认的JPEGImageReader稍有不同,因此 可以 帮助(对不起,附近没有我的工作电脑,所以我现在无法测试自己)。如果没有帮助,我想修复它。我可以将您的图像用于测试用例吗?:-)

    另一件可能有帮助的事情是指定:

    -Dsun.java2d.cmm=sun.java2d.cmm.kcms.KcmsServiceProvider
    

    在命令行上(或设置 sun.java2d.cmm 相应地使用其他手段的系统属性)。颜色管理模块(CMM)从Sun/Kodak的传统CMM转换为Java 8中的最新开源Little CMS。设置此系统属性将重新启用Java pre 8中的传统颜色管理。

    正如您提到的没有磁盘访问,它几乎排除了JMagick或im4j,因为它们最适合处理文件。不过,也许可以使用临时文件。