ImageIO (TIFF)
| Language | Java 9+ |
|---|---|
| License | GPL v2 with Classpath Exception (part of OpenJDK) |
| Repository | github.com/openjdk/jdk |
| Documentation | javax.imageio.plugins.tiff, TIFF metadata format |
| Depends on | nothing (built into the JDK) |
| Read / write | yes / yes, multi-page, strips and tiles, LZW, Deflate, PackBits, JPEG, CCITT; no BigTIFF |
Since Java 9 the JDK includes a TIFF plugin for javax.imageio (it came from the Java Advanced Imaging project). ImageIO.read and ImageIO.write handle TIFF like PNG or JPEG. For multi-page files, compression and tags, use an ImageReader / ImageWriter directly, and the classes in javax.imageio.plugins.tiff (TIFFDirectory, TIFFField, BaselineTIFFTagSet).
The plugin doesn’t read BigTIFF or old-style JPEG compression. For those, add TwelveMonkeys.
Installation#
Nothing to install: use JDK 9 or later.
Basic usage: read a TIFF and save as PNG#
Java
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
public class TiffToPng {
public static void main(String[] args) throws IOException {
BufferedImage img = ImageIO.read(new File("in.tif")); // first page
if (img == null) {
System.err.println("not a supported image");
return;
}
System.out.println(img.getWidth() + " x " + img.getHeight());
ImageIO.write(img, "png", new File("out.png"));
}
}
How to write a TIFF with LZW compression#
Java
import javax.imageio.*;
import javax.imageio.stream.ImageOutputStream;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
static void writeTiff(BufferedImage img, File out) throws IOException {
ImageWriter writer = ImageIO.getImageWritersByFormatName("tiff").next();
ImageWriteParam param = writer.getDefaultWriteParam();
param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
param.setCompressionType("LZW"); // also "Deflate", "PackBits", "JPEG", "CCITT T.6" (1-bit)
try (ImageOutputStream ios = ImageIO.createImageOutputStream(out)) {
writer.setOutput(ios);
writer.write(null, new IIOImage(img, null, null), param);
} finally {
writer.dispose();
}
}
How to read all pages of a multi-page TIFF#
Java
import javax.imageio.*;
import javax.imageio.stream.ImageInputStream;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
static void readPages(File file) throws IOException {
try (ImageInputStream iis = ImageIO.createImageInputStream(file)) {
ImageReader reader = ImageIO.getImageReaders(iis).next();
reader.setInput(iis);
int pages = reader.getNumImages(true);
for (int i = 0; i < pages; i++) {
BufferedImage page = reader.read(i);
ImageIO.write(page, "png", new File("page-" + i + ".png"));
}
reader.dispose();
}
}
How to write a multi-page TIFF#
Java
static void writePages(java.util.List<BufferedImage> pages, File out) throws IOException {
ImageWriter writer = ImageIO.getImageWritersByFormatName("tiff").next();
ImageWriteParam param = writer.getDefaultWriteParam();
param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
param.setCompressionType("Deflate");
try (ImageOutputStream ios = ImageIO.createImageOutputStream(out)) {
writer.setOutput(ios);
writer.prepareWriteSequence(null);
for (BufferedImage page : pages) {
writer.writeToSequence(new IIOImage(page, null, null), param);
}
writer.endWriteSequence();
} finally {
writer.dispose();
}
}
How to read TIFF tags#
TIFFDirectory turns the image metadata into a list of tags:
Java
import javax.imageio.plugins.tiff.*;
// reader set up as above
TIFFDirectory dir = TIFFDirectory.createFromMetadata(reader.getImageMetadata(0));
TIFFField software = dir.getTIFFField(BaselineTIFFTagSet.TAG_SOFTWARE);
if (software != null) System.out.println("Software: " + software.getAsString(0));
TIFFField compression = dir.getTIFFField(BaselineTIFFTagSet.TAG_COMPRESSION);
System.out.println("Compression: " + compression.getAsInt(0));
for (TIFFField f : dir.getTIFFFields()) {
String name = f.getTag() != null ? f.getTag().getName() : "unknown";
System.out.println(f.getTagNumber() + " " + name + " = " + f.getValueAsString(0));
}
Tips#
reader.getWidth(i)andreader.getHeight(i)read the size of pageiwithout decoding pixels.- Use
param.setTiling(512, 512, 0, 0)afterparam.setTilingMode(ImageWriteParam.MODE_EXPLICIT)to write a tiled TIFF. - CCITT compressions need a 1-bit image (
BufferedImage.TYPE_BYTE_BINARY).