用于检测CMYK图像的JAI ImageIO的纯Java替代品

前端之家收集整理的这篇文章主要介绍了用于检测CMYK图像的JAI ImageIO的纯Java替代品前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
首先我想解释导致问题的情况/要求:

在我们的网络应用程序中,我们不能支持CMYK图像(JPEG),因为IE 8及更低版本无法显示它们.
因此,我们需要检测有人想要上传这样的图像并拒绝它.

不幸的是,Java的ImageIO不会读取这些图像,也不会使我无法获取检测到的颜色空间.从调试看来,JPEGImageReader内部获取颜色空间代码11(这将意味着JCS_YCCK),但是我无法安全地访问该信息.

查询读者的图像类型时,我没有为CMYK任何内容,所以我可能假设没有图像类型=不支持的图像.

我使用成像工具将源CMYK图像转换为RGB,以测试是否可以读取(我尝试在获取消息“不支持CMYK”时模拟管理员的步骤).但是,JPEGImageReader不会读取该图像,因为它假定(在源代码中注释)3分量RGB颜色空间,但是图像头部会报告4个组件(可能是RGBA或ARGB),因此会抛出IllegalArgumentException异常.

因此,ImageIO不是一个选项,因为我无法可靠地获取图像的颜色空间,我无法告诉管理员为什么否则可以由于某些内部的内部图像(浏览器可以显示)可以被接受错误.

这导致我尝试JAI ImageIO,他的CLibJPEGImageReader做的很好,正确地读取我所有的测试图像.

然而,由于我们将应用程序部署在可能承载其他应用程序的JBoss中,我们希望尽可能地将它们隔离开来. AFAIK,我需要将JAI ImageIO安装到JRE,否则可以使本机库可用,以便使用它们,因此其他应用程序也可能会访问它们,这可能会导致副作用(至少我们会有测试很多,以确保不是这种情况).

这就是这个问题的解释,这里再说一遍:
是否有任何纯Java替代JAI ImageIO可靠地检测和可能转换CMYK图像?

提前致谢,

托马斯

解决方法

我找到了一个可以满足我们需求的解决方案: Apache Commons Sanselan.这个库读取JPEG头文件非常快速和准确(至少我所有的测试图像)以及一些其他的图像格式.

缺点是它不会读取JPEG图像数据,但我可以使用基本的JRE工具.

读取JPEG图像进行转换是非常容易的(ImageIO也拒绝读取):

JPEGImageDecoder decoder = JPEGCodec.createJPEGDecoder(new FileInputStream( new File(pFilename) ) );
BufferedImage sourceImg = decoder.decodeAsBufferedImage();

那么如果Sanselan告诉我图像其实是CMYK,我得到源图像的光栅并转换自己:

for( /*each pixel in the raster,which is represented as int[4]*/ )
{  
   double k = pixel[3] / 255.0;

   double r = (255.0 - pixel[0])*k;
   double g = (255.0 - pixel[1])*k;
   double b = (255.0 - pixel[2])*k;
}

这在RGB图像不会太亮或暗的情况下给出了相当不错的结果.但是,我不知道为什么与k相乘会阻止增亮. JPEG实际上是以本地代码解码,CMYK-> RGB转换我得到了不同的东西,我只是尝试乘法来看到视觉效果.

如果有人在这方面有所作为,我将不胜感激.

猜你在找的Java相关文章