multi-page tiff handling with ImageIO

Who has ever had the task to serve image/tiff images via http will sooner or later come across this issue.

“The image won’t automatically open on windows systems.”

Sure one could come up and alter registry HKEY_CLASSES_ROOT\.tif on Windows systems but IMHO this is not an acceptable solution. Assume you’ve got multipage tiff (eg. automatically generated by some scan device) and the only thing the user is interested in is viewing the content online, not caring about raw data format.

One way would be wrapping image raw data with a pdf document having one image per page. Which is actually what we’re goint to do in this post.

All we need are 2 libraries and a little bit of glue code.

dependencies {
  compile group: 'com.sun.media', name: 'jai_imageio', version: '1.1' 
  compile group: 'com.lowagie', name: 'itext', version: '4.2.0'
}

First one will add required extensions to javax.imageio.* as by default there are no Image Readers for tiff. Second one is used for PDF creation.

So what, we’re going to do is

  1. Load image reader for desired format (tiff in our case)
  2. Load image from resource
  3. Read image contents
  4. Scale image to fit into page and add it to PDF

The snipplet below will do the trick.

public void writeMultipageTiffAsPdfToStream(URL imageUrl, OutputStream outputStream) throws IOException, DocumentException {
  //get image reader for tiff
  ImageReader reader = getTiffImageReader();
  reader.setInput(openImageInputStream(imageUrl));

  //create A4 PDF Document and write content to stream
  Document doc = new Document(PageSize.A4, 0, 0, 0, 0);
  PdfWriter.getInstance(doc, outputStream);
  doc.open();

  //add one page to pdf for each image in multipage tiff
  int pages = reader.getNumImages(true);
  for (int imageIndex = 0; imageIndex < pages; imageIndex++) {
    //read image at index
    BufferedImage bufferedImage = reader.read(imageIndex);
    //convert to pdf document image
    Image image = Image.getInstance(bufferedImage, null);
    //scale to fit to page
    image.scaleToFit(PageSize.A4.getWidth(), PageSize.A4.getHeight());
    doc.add(image);
  }
  
  doc.close();
}

private ImageReader getTiffImageReader() {
  Iterator<ImageReader> imageReaders = ImageIO.getImageReadersByFormatName("TIFF");
  if (!imageReaders.hasNext()) {
    throw new UnsupportedOperationException("No TIFF Reader found!");
  }
  return imageReaders.next();
}

private ImageInputStream openImageInputStream(URL url) throws IOException {
  return ImageIO.createImageInputStream(url.openStream());
}


Christoph Strobl is Sortware Architect at pagu.at mainly working on Enterprise Solutions for an Austrian Telecommunication Company. He’s passionate about architecture, design, implementation and testing having special interest in topics related to spring, web and search.

Ein Gedanke zu „multi-page tiff handling with ImageIO

  1. Pingback: Splitting a multipage TIFF image into individual images (Java) - Code Utility - Code Utility

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht.