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)