Java 8 ImageIO 在 Linux 中错误地读取 JPEG

标签 java image-processing java-8 javax.imageio

我正在尝试读取用户上传的 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) 返回不同的值(value)观。

Linux 中的颜色处理在 Java 8u05 和 8u11 上有所不同,8u05 是“偏红”的,8u11 如上所示。

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

这也会影响当时导出的所有图像(实际上是本网站上的所有图像)。

谁能提供一些关于如何让它工作的建议(除了等待 JDK 的修复)?也许推荐替代库,可以在这里使用(EJB,数据存储在 MongoDB 中,因此使用 InputStreams 获取数据 - 无文件系统访问)。

谢谢!

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

最佳答案

您可以尝试使用我的 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,因为它们最适合文件。不过,可能可以使用临时文件。

关于Java 8 ImageIO 在 Linux 中错误地读取 JPEG,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25187942/

相关文章:

matlab - 使用riesz变换分析后的相移图像内容

java - 为什么 Arrays.fill() 不再在 HashMap.clear() 中使用?

java - 使用 Java Stream 多次处理结果

java - HTML5(canvas + JavaScript)中是否有等效的graphstream(Java)

java - 我的应用程序使用 AWT,尽管其构建的 jar 使用 Swing。为什么?

java - Android 中的膨胀和腐 eclipse

java - 在 WSL 上安装 tomcat 9

JavaFx 在 FXML 中包含自定义组件

java - 多窗口 Java 应用程序

image-processing - 绘图机器人的算法-有什么提示吗?