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
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.
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:
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.*.
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.