Mark Stephens Mark has been working with Java and PDF since 1999 and is a big NetBeans fan. He enjoys speaking at conferences. He has an MA in Medieval History and a passion for reading.

Odd coloured JPEGs in Java with ImageIO

1 min read

One of the best features about Java is the amount of low-level complexity it removes, allowing you to focus on developing the application. However, this does sometimes hide some important issues.

We found one of these with the ImageIO class which offers a whole series of methods to save an image as a Tiff, a PNG or a JPEG. All the complexity is hidden and you can save out the image in one line of code (magic). Unfortunately, it also hides an interesting feature…

ImageIO will happily save all kinds of images, including images with transparency (ARGB). And it will save it as a JPEG, even though JPEGs do not really support transparency. The problem comes when you try to view the JPEG. Java understands this hybrid image so it will load back correctly, but very few other tools do.

Because it has 4 bands (RGB are three and then transparency makes the fourth), most JPEG tools assume it must be in the CMYK colorspace and interpret the colors as CMYK. CMYK works completely differently to RGB so the image comes out looking wrong (often with a nasty red tint). Unfortunately, there is no way that a JPEG Decoder can spot this has happened – it is a bug in the way  ImageIO works. You can manually fix it by removing any alpha component from your BufferedImage before you save it in ImageIO with the following code

private static BufferedImage convertARGBToRGB(BufferedImage image) {
int[] pixels = ((DataBufferInt) image.getRaster().getDataBuffer()).getData();
BufferedImage result = new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_INT_RGB);
int[] pixelsOut = ((DataBufferInt) result.getRaster().getDataBuffer()).getData();
System.arraycopy(pixels, 0, pixelsOut, 0, pixels.length);
return result;
}

In our JDeli image library (which provides a complete JPG Converter), we have actually added a flag to read the JPEG correctly for you if you know the file is broken

try {
 Map map = new HashMap();
 map.put("DECODE_4_COMPONENTS_AS_ARGB","TRUE");
 BufferedImage image = JDeli.read(new File(“path/file.jpeg”), map); 
} catch (IOException e) {
 // Deal with read error here.
}

 

So while Java makes life much easier most of the time, there are some interesting gotchas out there…

Did you know...

IDRsolutions offers a whole range of online file converters to convert PDF and Microsoft Excel, Word and Office Documents to HTML5, SVG or image formats?

It is free to use for single file conversions and also includes Developer links if you want to use our commercial software for bulk conversions. Find out more on this page

Mark Stephens Mark has been working with Java and PDF since 1999 and is a big NetBeans fan. He enjoys speaking at conferences. He has an MA in Medieval History and a passion for reading.

How to read HEIC image files in Java with…

In this article, I will explain how to read HEIC files into Java as a BufferedImage. ImageIO does not read HEIC file types so...
Mark Stephens
1 min read

How to convert WMF files to SVG in java…

This article will show you how to convert WMF files into SVG files using our JDeli Java Image library. What is WMF? WMF is...
Amy Pearson
1 min read

How to write WebP images in Java

In this article, I will walk you through how to write out images as WebP images in Java. ImageIO does not support WebP images...
Mark Stephens
1 min read

Leave a Reply

Your email address will not be published. Required fields are marked *

IDRsolutions Ltd 2020. All rights reserved.