java 判断cmyk,用于检测CMYK图像的JAI ImageIO的纯Java替代品

first I'd like to explain the situation/requirements that lead to the question:

In our web application we can't support CMYK images (JPEG) since IE 8 and below can't display them.

Thus we need to detect when someone wants to upload such an image and deny it.

Unfortunately, Java's ImageIO won't read those images or would not enable me to get the detected color space. From debugging it seems like JPEGImageReader internally gets the color space code 11 (which would mean JCS_YCCK) but I can't safely access that information.

When querying the reader for the image types I get nothing for CMYK, so I might assume no image types = unsupported image.

I converted the source CMYK image to RGB using an imaging tool in order to test whether it would then be readable (I tried to simulate the admin's steps when getting the message "No CMYK supported"). However, JPEGImageReader would not read that image, since it assumes (comment in the source!)3-component RGB color space but the image header reports 4 components (maybe RGBA or ARGB) and thus an IllegalArgumentException is thrown.

Thus, ImageIO is not an option since I can't reliably get the color space of an image and I can't tell the admin why an otherwise fine image (it can be displayed by the browser) would not be accepted due to some internal error.

This led me to try JAI ImageIO whose CLibJPEGImageReader does an excellent job and correctly reads all my test images.

However, since we're deploying our application in a JBoss that might host other applications as well, we'd like to keep them as isolated as possible. AFAIK, I'd need to install JAI ImageIO to the JRE or otherwise make the native libs available in order to use them, and thus other applications might get access to them as well, which might cause side effects (at least we'd have to test a lot to ensure that's not the case).

That's the explanation for the question, and here it comes again:

Is there any pure Java alternative to JAI ImageIO which reliably detects and possibly converts CMYK images?

Thanks in advance,

Thomas

解决方案

I found a solution that is ok for our needs: Apache Commons Sanselan. This library reads JPEG headers quite fast and accurate (at least all my test images) as well as a number of other image formats.

The downside is that it won't read JPEG image data, but I can do that with the basic JRE tools.

Reading JPEG images for conversion is quite easy (the ones that ImageIO refuses to read, too):

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

BufferedImage sourceImg = decoder.decodeAsBufferedImage();

Then if Sanselan tells me the image is actually CMYK, I get the source image's raster and convert myself:

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;

}

This give quite good results in the RGB images not being too bright or dark. However, I'm not sure why multiplying with k prevents the brightening. The JPEG is actually decoded in native code and the CMYK->RGB conversion I got states something different, I just tried the multiply to see the visual result.

If anybody could shed some light on this, I'd be grateful.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值