ImageIO not able to write a JPEG file

JavaImageJpegjavax.imageio

Java Problem Overview


I have a BufferedImage I'm trying to write to a jpeg file, but my Java program throws an exception. I'm able to successfully save the same buffer to a gif and png. I've tried looking around on Google for solutions, but to no avail.

Code:

   File outputfile = new File("tiles/" + row + ":" + col + ".jpg");
   try {
	   ImageIO.write(mapBufferTiles[row][col], "jpg", outputfile);
   } catch (IOException e) {
	   	outputfile.delete();
   		throw new RuntimeException(e);
   }

Exception:

 Exception in thread "main" java.lang.RuntimeException: javax.imageio.IIOException: Invalid argument to native writeImage
 at MapServer.initMapBuffer(MapServer.java:90)
 at MapServer.<init>(MapServer.java:24)
 at MapServer.main(MapServer.java:118)
 Caused by: javax.imageio.IIOException: Invalid argument to native writeImage
 at com.sun.imageio.plugins.jpeg.JPEGImageWriter.writeImage(Native Method)
 at com.sun.imageio.plugins.jpeg.JPEGImageWriter.writeOnThread(JPEGImageWriter.java:1055)
 at com.sun.imageio.plugins.jpeg.JPEGImageWriter.write(JPEGImageWriter.java:357)
 at javax.imageio.ImageWriter.write(ImageWriter.java:615)
 at javax.imageio.ImageIO.doWrite(ImageIO.java:1602)
 at javax.imageio.ImageIO.write(ImageIO.java:1526)
 at MapServer.initMapBuffer(MapServer.java:87)
 ... 2 more

Java Solutions


Solution 1 - Java

OpenJDK does not have a native JPEG encoder, try using Sun's JDK, or using a library (such as JAI

AFAIK, regarding the "pinkish tint", Java saves the JPEG as ARGB (still with transparency information). Most viewers, when opening, assume the four channels must correspond to a CMYK (not ARGB) and thus the red tint.

If you import the image back to Java, the transparency is still there, though.

Solution 2 - Java

I had the same issue in OpenJDK 7 and I managed to get around this exception by using an imageType of TYPE_3BYTE_BGR instead of TYPE_4BYTE_ABGR using the same OpenJDK.

Solution 3 - Java

2019 answer: Make sure your BufferedImage does not have alpha transparency. JPEG does not support alpha, so if your image has alpha then ImageIO cannot write it to JPEG.

Use the following code to ensure your image does not have alpha transparancy:

static BufferedImage ensureOpaque(BufferedImage bi) {
    if (bi.getTransparency() == BufferedImage.OPAQUE)
        return bi;
    int w = bi.getWidth();
    int h = bi.getHeight();
    int[] pixels = new int[w * h];
    bi.getRGB(0, 0, w, h, pixels, 0, w);
    BufferedImage bi2 = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
    bi2.setRGB(0, 0, w, h, pixels, 0, w);
    return bi2;
}

Solution 4 - Java

Here is some code to illustrate @Thunder idea to change the image type to TYPE_3BYTE_BGR

try {
  BufferedImage input = ImageIO.read(new File("input.png"));
  System.out.println("input image type=" + input.getType());
  int width = input.getWidth();
  int height = input.getHeight();
  BufferedImage output = new BufferedImage(width, height, BufferedImage.TYPE_3BYTE_BGR);
  int px[] = new int[width * height];
  input.getRGB(0, 0, width, height, px, 0, width);
  output.setRGB(0, 0, width, height, px, 0, width);
  ImageIO.write(output, "jpg", new File("output.jpg"));
} catch (Exception e) {
  e.printStackTrace();
}

Solution 5 - Java

You get the same error

Caused by: javax.imageio.IIOException: Invalid argument to native writeImage
at com.sun.imageio.plugins.jpeg.JPEGImageWriter.writeImage(Native Method)
at com.sun.imageio.plugins.jpeg.JPEGImageWriter.writeOnThread(JPEGImageWriter.java:1055)

if you are using a not supported Color Space (in my case CYMK). See https://stackoverflow.com/q/3123574/868941 how to solve this.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionKaranView Question on Stackoverflow
Solution 1 - JavaRui VieiraView Answer on Stackoverflow
Solution 2 - JavaThunderView Answer on Stackoverflow
Solution 3 - JavaAdam Gawne-CainView Answer on Stackoverflow
Solution 4 - JavaPeter QuiringView Answer on Stackoverflow
Solution 5 - JavarmullerView Answer on Stackoverflow