ImageIO
| Language | Java (part of the JDK, java.desktop module) |
|---|---|
| License | GPL v2 with Classpath Exception (OpenJDK) |
| Repository | github.com/openjdk/jdk |
| Documentation | javax.imageio API, PNG metadata format |
| Depends on | nothing (built into the JDK) |
| Read / write | yes / yes, all color types and bit depths, all standard chunks through the metadata API |
ImageIO is the image I/O API of the Java standard library. It reads and writes PNG, JPEG, GIF, BMP, WBMP and TIFF without any dependency. ImageIO.read returns a java.awt.image.BufferedImage that you can draw on with Graphics2D.
For simple load and save it’s one line. Metadata (text chunks, pHYs, iCCP) goes through IIOMetadata, a DOM tree that is verbose but complete. ImageIO loads the whole image into memory; for very large PNG files use PNGJ. ImageIO isn’t available on Android.
Installation#
Nothing to install: javax.imageio is in every JDK. In a modular project add requires java.desktop; to module-info.java.
Basic usage: read and write a PNG#
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
public class PngExample {
public static void main(String[] args) throws IOException {
BufferedImage image = ImageIO.read(new File("in.png"));
if (image == null) {
throw new IOException("not a supported image");
}
System.out.println(image.getWidth() + " x " + image.getHeight()
+ ", alpha: " + image.getColorModel().hasAlpha());
// set the top-left pixel to opaque red (ARGB)
image.setRGB(0, 0, 0xFFFF0000);
if (!ImageIO.write(image, "png", new File("out.png"))) {
throw new IOException("no PNG writer");
}
}
}
How to get PNG width and height without decoding#
An ImageReader reads the header on request, without decoding pixels:
import javax.imageio.ImageIO;
import javax.imageio.ImageReader;
import javax.imageio.stream.ImageInputStream;
import java.io.File;
import java.util.Iterator;
try (ImageInputStream in = ImageIO.createImageInputStream(new File("in.png"))) {
Iterator<ImageReader> readers = ImageIO.getImageReaders(in);
if (readers.hasNext()) {
ImageReader reader = readers.next();
try {
reader.setInput(in);
System.out.println(reader.getWidth(0) + " x " + reader.getHeight(0));
} finally {
reader.dispose();
}
}
}
How to resize a PNG#
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
static BufferedImage resize(BufferedImage src, int width, int height) {
BufferedImage dst = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
Graphics2D g = dst.createGraphics();
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
g.drawImage(src, 0, 0, width, height, null);
g.dispose();
return dst;
}
How to set PNG compression level#
Since Java 9 the PNG writer accepts a compression quality: 0.0f is the smallest file (DEFLATE level 9), 1.0f is no compression:
import javax.imageio.IIOImage;
import javax.imageio.ImageIO;
import javax.imageio.ImageWriteParam;
import javax.imageio.ImageWriter;
import javax.imageio.stream.ImageOutputStream;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
static void writeSmallest(BufferedImage image, File file) throws IOException {
ImageWriter writer = ImageIO.getImageWritersByFormatName("png").next();
ImageWriteParam param = writer.getDefaultWriteParam();
param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
param.setCompressionQuality(0.0f);
try (ImageOutputStream out = ImageIO.createImageOutputStream(file)) {
writer.setOutput(out);
writer.write(null, new IIOImage(image, null, null), param);
} finally {
writer.dispose();
}
}
How to read PNG text chunks#
Text chunks are in the native metadata tree (javax_imageio_png_1.0) under tEXt, zTXt and iTXt:
import javax.imageio.ImageIO;
import javax.imageio.ImageReader;
import javax.imageio.metadata.IIOMetadata;
import javax.imageio.stream.ImageInputStream;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import java.io.File;
try (ImageInputStream in = ImageIO.createImageInputStream(new File("in.png"))) {
ImageReader reader = ImageIO.getImageReadersByFormatName("png").next();
reader.setInput(in);
IIOMetadata metadata = reader.getImageMetadata(0);
Node root = metadata.getAsTree("javax_imageio_png_1.0");
NodeList entries = ((Element) root).getElementsByTagName("tEXtEntry");
for (int i = 0; i < entries.getLength(); i++) {
Element e = (Element) entries.item(i);
System.out.println(e.getAttribute("keyword") + ": " + e.getAttribute("value"));
}
reader.dispose();
}
How to convert PNG to JPEG#
The JPEG writer fails on images with alpha. Draw onto an RGB image with a white background first:
import javax.imageio.ImageIO;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;
BufferedImage png = ImageIO.read(new File("in.png"));
BufferedImage rgb = new BufferedImage(png.getWidth(), png.getHeight(), BufferedImage.TYPE_INT_RGB);
Graphics2D g = rgb.createGraphics();
g.setColor(Color.WHITE);
g.fillRect(0, 0, png.getWidth(), png.getHeight());
g.drawImage(png, 0, 0, null);
g.dispose();
ImageIO.write(rgb, "jpg", new File("out.jpg"));
Tips#
ImageIO.readreturnsnull(not an exception) when no reader recognizes the file.- Call
ImageIO.setUseCache(false)on servers to keep ImageIO from writing temporary cache files to disk. - TwelveMonkeys ImageIO adds plugins for more formats (WebP, PSD, ICO, PICT) that work with the same
ImageIO.readcall.