JAI ImageIO的纯Java替代品,用于检测CMYK图像
首先,我想解释一下导致这个问题的情况/要求:
在我们的Web应用程序中,由于IE 8及更低版本无法显示它们,因此我们不支持CMYK图像(JPEG)。因此,我们需要检测何时有人要上传此类图像并拒绝它。
不幸的是,Java的ImageIO无法读取这些图像,或者使我无法获得检测到的色彩空间。通过调试,似乎在JPEGImageReader
内部获得了颜色空间代码11(这意味着JCS_YCCK
),但是我无法安全地访问该信息。
当向阅读器查询图像类型时,我没有得到CMYK的信息,因此我可能会假设no image types = unsupported image
。
我使用成像工具将源CMYK图像转换为RGB,以便测试它是否可读(我在收到“不支持CMYK”消息时尝试模拟管理员的步骤)。但是,JPEGImageReader
将不会读取该图像,因为它
假定
(在源中有注释!)3分量RGB颜色空间,但是图像标头报告了4个分量(可能是RGBA或ARGB),因此IllegalArgumentException
抛出。
因此,ImageIO不是一个选择,因为我无法可靠地获取图像的色彩空间,而且我也无法告诉管理员为什么由于某些内部原因而无法接受原本不错的图像(可以由浏览器显示)错误。
这使我尝试使用JAI ImageIO,CLibJPEGImageReader
它的性能出色并且可以正确读取我所有的测试图像。
但是,由于我们将应用程序部署在可能还托管其他应用程序的JBoss中,因此我们希望将它们保持尽可能的隔离。AFAIK,我需要将JAI
ImageIO安装到JRE或以其他方式提供本机库才能使用它们,因此其他应用程序也可能会访问它们,这可能会引起副作用(至少我们会进行大量测试以确保不是这种情况)。
这就是问题的解释,这里又来了:
提前致谢,
汤玛士
回答:
我找到了可以满足我们需求的解决方案: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转换表示的状态有所不同,我只是尝试了乘法以查看视觉效果。
如果有人能对此有所启示,我将不胜感激。
以上是 JAI ImageIO的纯Java替代品,用于检测CMYK图像 的全部内容, 来源链接: utcz.com/qa/409495.html