TwelveMonkeys ImageIO (TIFF)
| Language | Java 8+ |
|---|---|
| License | BSD 3-Clause |
| Repository | github.com/haraldk/TwelveMonkeys |
| Documentation | README |
| Depends on | common-lang, common-io, common-image, imageio-core, imageio-metadata (pulled in by Maven) |
| Read / write | yes / yes, multi-page, BigTIFF, strips and tiles, LZW, Deflate, PackBits, JPEG (new and old style), CCITT, CMYK with ICC profiles |
TwelveMonkeys adds and improves format plugins for the standard javax.imageio API. Its TIFF plugin reads many files the JDK’s own plugin rejects: BigTIFF, old-style JPEG, CMYK and YCbCr with ICC profiles, unusual bit depths and broken files from scanners. It also writes TIFF and BigTIFF. You use it through the same ImageIO calls as the built-in plugin; once the jar is on the classpath, TwelveMonkeys registers its reader and writer ahead of the JDK’s.
It also works on Java 8, where the JDK has no TIFF support at all.
Installation#
Maven:
<dependency>
<groupId>com.twelvemonkeys.imageio</groupId>
<artifactId>imageio-tiff</artifactId>
<version>3.15.0</version>
</dependency>
Gradle:
implementation("com.twelvemonkeys.imageio:imageio-tiff:3.15.0")
In web applications, register com.twelvemonkeys.servlet.image.IIOProviderContextListener (from servlet) or call ImageIO.scanForPlugins(), otherwise the plugin may not be found.
Basic usage: read a TIFF and save as PNG#
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"));
if (img == null) {
System.err.println("no reader for this file");
return;
}
ImageIO.write(img, "png", new File("out.png"));
}
}
How to write a TIFF with LZW compression#
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"); // "None", "PackBits", "ZLib", "Deflate", "JPEG", "CCITT RLE", "CCITT T.4", "CCITT T.6"
try (ImageOutputStream ios = ImageIO.createImageOutputStream(out)) {
writer.setOutput(ios);
writer.write(null, new IIOImage(img, null, null), param);
} finally {
writer.dispose();
}
}
How to write a BigTIFF file#
Ask for the BigTIFF writer instead of tiff:
ImageWriter writer = ImageIO.getImageWritersByFormatName("BigTIFF").next();
Reading needs nothing special: the reader detects BigTIFF from the header.
How to read every page of a multi-page TIFF#
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++) {
System.out.println("page " + i + ": " + reader.getWidth(i) + " x " + reader.getHeight(i));
BufferedImage page = reader.read(i);
// ... use page ...
}
reader.dispose();
}
}
How to write a multi-page TIFF#
ImageWriter writer = ImageIO.getImageWritersByFormatName("tiff").next();
try (ImageOutputStream ios = ImageIO.createImageOutputStream(new File("pages.tif"))) {
writer.setOutput(ios);
writer.prepareWriteSequence(null);
for (BufferedImage page : pages) {
writer.writeToSequence(new IIOImage(page, null, null), null);
}
writer.endWriteSequence();
} finally {
writer.dispose();
}
Tips#
- Read metadata with
reader.getImageMetadata(i). TwelveMonkeys supports the same native TIFF metadata format (javax_imageio_tiff_image_1.0) as the JDK, plus the standard format. - Add
imageio-jpegtoo for better JPEG-in-TIFF and CMYK JPEG support.