Saving a BufferedImage as a PNG, JPEG etc

Having created a BufferedImage to represent a graphic image in Java and set pixels on that image as appropriate, a common next step is to want to save that image to disk in a common image format such as JPEG, PNG etc.

Saving a BufferedImage as a PNG

You can easily save a BufferedImage in one of these formats thanks to the static utility method ImageIO.write(). To save a BufferedImage as a PNG file, the following will suffice:

BufferedImage img = ...
File f = new File("MyFile.png");
ImageIO.write(img, "PNG", f);

Saving a BufferedImage as a JPEG

The procedure for writing an image file as a JPEG is similar:

BufferedImage img = ...
File f = new File("MyFile.jpg");
ImageIO.write(img, "JPEG", f);

(You can also specify "JPG" instead of "JPEG".)

Which format should I use: PNG or JPEG?

In general, the choice depends on (a) whether you need your image to include transparency information, and (b) whether or not it matters if pixels in the saved image differ slightly from the original in order to give greater compression.

Saving a BufferedImage in other formats

A couple of other formats are supported by the JDK as standard. You can save a BufferedImage as a GIF by specifying "GIF" as the format name to ImageIO.write(). Note that this will create a 256-colour indexed image. In other words, if your image contains more than 256 individual colours, then its quality will be degraded as each colour other than the 256 most common will be mapped to its closest neighbour of the most common 256. Due to this limitation, along with the fact that PNG offers a patent-free alternative to GIF, it is recommended only to use the GIF format when you have no alternative.

The BMP and WBMP formats are also supported as standard. The BMP format is lossless but typically results in larger files than other formats.

Error handling

As you might expect, ImageIO.write() will throw an IOException should an I/O error occur while writing the image. A quirk of this method, however, is that there are some types of error that do not actually throw an exception. This can occur if:

In these latter cases, ImageIO.write() may instead return a value of false (instead of the usual value of true which it is common to ignore) to indicate failure. So if you are being ultra-careful, it is safer to do the following "just in case":

BufferedImage img = ...
File f = new File("MyFile.jpg");
if (!ImageIO.write(img, "JPEG", f)) {
  throw new RuntimeException("Unexpected error writing image");
}

This won't solve the underlying problem, but it will prevent your program 'failing silently' at some point in the future and wasting your time with a lot of head-scratching trying to figure out what went wrong.