[GeoNetwork-users] CMYK images, anyone ?

hello lists,

anyone here has experience with Java Image API ?

In Geonetwork, for the metadata preview upload, the image is handled in a
standard way. This is mostly fine but if the image is encoded in a CMYK
color scheme rather than an RGB color scheme, the exception "Unsupported
image type" is thrown.

I fiddled around a bit and now have the code like below, which does handle
the image correctly but suffers from one "minor" detail, that is, the
resulting image has wrong colors.

I attached an original image in CMYK, and the result of the code below ..

If you have advice on how to improve on this, please share !

Kind regards
Heikki Doeleman

code:

                 File uploadedFile = new File(context.getUploadDir() +
newLogo);
                 BufferedImage bufferedImage = null;
                 Iterator readers =
ImageIO.getImageReadersByFormatName("JPEG");
                 ImageReader reader = null;
                 while(readers.hasNext()) {
                        reader = (ImageReader)readers.next();
                        if(reader.canReadRaster()) {
                            break;
                        }
                 }
                 ImageInputStream input =
ImageIO.createImageInputStream(uploadedFile);
                 reader.setInput(input);

                 // if this succeeds, all is normal -- the image is not CMYK
                 try {
                     // Try reading an image (including color conversion)
                     bufferedImage = reader.read(0);
                     // scale to 40px width
                     int imgWidth = bufferedImage.getWidth();
                     int imgHeight = bufferedImage.getHeight();
                     int hardcodedWidth = 40;
                     int scaledHeight = hardcodedWidth * imgHeight /
imgWidth;
                     Image thumb =
bufferedImage.getScaledInstance(hardcodedWidth, scaledHeight,
BufferedImage.SCALE_SMOOTH);
                     BufferedImage bimg = new BufferedImage(hardcodedWidth,
scaledHeight, BufferedImage.TYPE_3BYTE_BGR);
                     Graphics2D g = bimg.createGraphics();
                     g.drawImage(thumb, 0, 0, null);
                     g.dispose();
                     String logoDir = Lib.resource.getLogosDir(context);
                     ImageIO.write(bimg, "png", new File(logoDir + "/" +
newLogo.toLowerCase()));
                 }

                 // if this happens, the image is CMYK
                 catch (IIOException x) {
                        // Try reading a Raster (no color conversion)
                        Raster raster = reader.readRaster(0, null);
                        // arbitrarily select a BufferedImage type.
                        int imageType;
                        switch(raster.getNumBands()) {
                        case 1:
                            imageType = BufferedImage.TYPE_BYTE_GRAY;
                            break;
                        case 3:
                            imageType = BufferedImage.TYPE_3BYTE_BGR;
                            break;
                        case 4:
                            imageType = BufferedImage.TYPE_4BYTE_ABGR;
                            break;
                        default:
                            throw new UnsupportedOperationException();
                        }
                        bufferedImage = new BufferedImage(raster.getWidth(),
raster.getHeight(), imageType);
                        bufferedImage.getRaster().setRect(raster);

/* also tried this, but it makes no difference ...

                        int w = raster.getWidth();
                        int h = raster.getHeight();
                        String cmykProfileName =
"C:/gndeploymenttest/web/geonetwork/ISOcoated_v2_eci.icc";
                        ICC_Profile cmykProfile =
ICC_Profile.getInstance(new FileInputStream(cmykProfileName));
                        ColorSpace cmykCS = new ICC_ColorSpace(cmykProfile);
                        BufferedImage rgbImage = new BufferedImage(w, h,
BufferedImage.TYPE_INT_RGB);
                        WritableRaster rgbRaster = rgbImage.getRaster();
                        ColorSpace rgbCS =
rgbImage.getColorModel().getColorSpace();
                        ColorConvertOp cmykToRgb = new
ColorConvertOp(cmykCS, rgbCS, null);
                        cmykToRgb.filter(raster, rgbRaster);
*/
                        String logoDir = Lib.resource.getLogosDir(context);
                        ImageIO.write(bufferedImage, "jpg", new File(logoDir
+ "/" + newLogo.toLowerCase()));

(attachments)

original_cmyk.jpg
result.jpg