Pure Java alternative to JAI ImageIO for detecting CMYK images

心不动则不痛 提交于 2019-11-30 03:41:41
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.

Codo

I've posted a pure Java solution for reading all sorts of JPEG images and converting them to RGB.

It's built on the following facts:

  • While ImageIO cannot read JPEG images with CMYK as a buffered image, it can read the raw pixel data (raster).
  • Sanselan (or Apache Commons Imaging as it's called now) can be used to read the details of CMYK images.
  • There are images with inverted CMYK values (an old Photoshop bug).
  • There are images with YCCK instead of CMYK (can easily be converted).

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.

I don't agree with your "Thus we need to detect when someone wants to upload such an image and deny it". A much more user-friendly policy would be to convert it to something else than CMYK.

The rest of your post is a bit confusing in that regards seen that you ask both for detection and conversion, which are two different things. Once again, I think converting the image is much more user-friendly.

No need to write in bold btw:

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

Pure Java I don't know, but ImageMagick works fine to convert CMYK image to RGB ones. Calling ImageMagick on the server-side from Java really isn't complicated. I used to do it manually by calling an external process but nowadays there are wrappers like JMagick and im4java.

tsmets

Beware of another post as the Java 7 does not allow to use directly Sun's implementation without special parameters as indicated in import com.sun.image.codec.jpeg.*.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!