用于检测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,否则可以使本机库可用,以便使用它们,因此其他应用程序也可能会访问它们,这可能会导致副作用(至少我们会有测试很多,以确保不是这种情况). 这就是这个问题的解释,这里再说一遍: 提前致谢, 托马斯 解决方法
我找到了一个可以满足我们需求的解决方案:
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转换我得到了不同的东西,我只是尝试乘法来看到视觉效果. 如果有人在这方面有所作为,我将不胜感激. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |