Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

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
                @Rui - It seems in Eclipse's preferences that I have openjdk installed, but sun jdk is the default checked one. is there a way I can check for sure?
– Karan
                Aug 7, 2010 at 23:27
                @Karan: If Sun's JDK is the default, that shouldn't be the problem. What kind of data is mapBufferTiles[row][col]? it should be a BufferedImage.
– Rui Vieira
                Aug 7, 2010 at 23:40

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.

As for the pink tint issue, i just converted the transparent pixels to white ones as per: stackoverflow.com/questions/464825/… – Karan Aug 8, 2010 at 0:12 End of 2nd paragraph - shouldn't "..as thus the red tint." be "..and thus the red tint."? – Andrew Thompson Aug 21, 2012 at 0:05 BTW, OpenJDK does have a native JPEG encoder. And if you try to save 32-bit-color file - it fails. And Sun JDK does not fail, but form tinted file. Not sure what is better. – Andrey Regentov Apr 25, 2013 at 11:02 @AndreyRegentov Possibly now, but I'm pretty sure at the time of writing (2010), it didn't. – Rui Vieira Sep 30, 2013 at 13:48 Thanks for this information! This is slightly tangential, but I'm running Arch Linux and trying to use Apophysis-J + OpenJDK v7 (a fun fractal creation app), but I couldn't get the render function output a valid .jpg file -- I couldn't find any documentation either (which is why I'm commenting here for posterity sake), but turns out the fix is easy -- just output the rendered file as a .png and it works fine. Hope this helps someone out there. Thanks again for this info, saved me some frustration! – hypervisor666 Dec 30, 2013 at 5:40 You're right!!! I created a new BufferedImage of TYPE_3BYTE_BGR and used getRGB() from BufferedImage of TYPE_INT_ARGB and setRGB() on new BufferedImage and then called ImageIO.write() and it works on Linux. – Peter Quiring Sep 10, 2013 at 14:32 can some please tell me what he means? I read the image like ImageIO.read(new File(path)); and theres no image type arguments? – centenond Aug 18, 2018 at 18:00 @PeterQuiring could you share how did you do that? As centenond mentions, there's no arguments to specify the image type, and according to javadoc the image type is automatically determined from a system registry. How can you affect this? – jotadepicas Aug 29, 2019 at 19:47

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;
                I'm hitting this issue because I'm reading PNGs with alpha, and trying to write to JPG (well, not me, I'm dealing with a legacy code that does this...). Can you suggest a workaround for this scenario? Thanks!
– jotadepicas
                Aug 29, 2019 at 19:45

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();
                I can confirm this works for the BufferedImages extracted from the ImageSegments of NITF files.
– Benjamin
                Apr 21, 2020 at 18:40

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 How to convert from CMYK to RGB in Java correctly? how to solve this.

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.