Skip to content

Instantly share code, notes, and snippets.

@JoelGeraci-Datalogics
Last active September 13, 2015 07:33
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JoelGeraci-Datalogics/1e00f1d45764e29de5d4 to your computer and use it in GitHub Desktop.
Save JoelGeraci-Datalogics/1e00f1d45764e29de5d4 to your computer and use it in GitHub Desktop.
Convert TIFF to PDF Using the Datalogics PDF Java Toolkit
/*
* Copyright Datalogics, Inc. 2015
*/
package pdfjt.cookbook.imaging;
import java.awt.image.BufferedImage;
import java.io.File;
import java.net.URL;
import java.util.Iterator;
import javax.imageio.ImageIO;
import javax.imageio.ImageReader;
import javax.imageio.metadata.IIOMetadata;
import javax.imageio.metadata.IIOMetadataFormatImpl;
import javax.imageio.metadata.IIOMetadataNode;
import org.w3c.dom.NodeList;
import pdfjt.util.SampleFileServices;
import com.adobe.internal.io.ByteWriter;
import com.adobe.pdfjt.core.types.ASMatrix;
import com.adobe.pdfjt.core.types.ASRectangle;
import com.adobe.pdfjt.pdf.document.PDFDocument;
import com.adobe.pdfjt.pdf.document.PDFOpenOptions;
import com.adobe.pdfjt.pdf.document.PDFSaveFullOptions;
import com.adobe.pdfjt.pdf.document.PDFVersion;
import com.adobe.pdfjt.pdf.graphics.PDFExtGState;
import com.adobe.pdfjt.pdf.graphics.PDFRectangle;
import com.adobe.pdfjt.pdf.graphics.xobject.PDFXObjectImage;
import com.adobe.pdfjt.pdf.page.PDFPage;
import com.adobe.pdfjt.services.imageconversion.ImageManager;
/*
* Overview:
* Start by creating a new PDF document that will be used to add the
* images to. We start with a blank first page, add the first page of
* the multi-page TIFF and then loop through the rest of the pages. The
* goal is to create a series of PDF pages where the only page content
* is the corresponding image page from the multipage TIFF and the
* resolution of the PDF page and the original resolution of the TIFF are
* the same... or very close.
*/
public class tiff2pdf {
private static final String inputURL = "http://dev.datalogics.com/cookbook/imaging/input.tif";
private static final String outputDir = "cookbook/Imaging/output";
private static final String outputFilename = "PDF_from_TIFF.pdf";
private static final Double mmPerIn = 25.4; //millimeters per inch
/**
* @param args
*/
public static void main(String[] args) throws Exception {
ImageReader reader = null;
Iterator<ImageReader> imageReaders = ImageIO.getImageReadersByFormatName("TIFF");
if (imageReaders.hasNext()) {
reader = imageReaders.next();
}
else {
System.out.println("A TIFF Reader isn't available");
System.exit(0);
}
reader.setInput(ImageIO.createImageInputStream(new URL(inputURL).openStream()));
//Get the first page of the multipage TIFF
BufferedImage bufferedImage = reader.read(0);
/*
* Get the image metadata so we can get the pixel density and use it to
* calculate the height and width of the correct size PDF page in points
* such that the resolution of the image on the page matches the
* original resolution in the TIFF.
*/
Double pixelsPerMM = getPixelsPerMM(reader.getImageMetadata(0));
Double pageWidth = Math.floor(pixelsPerMM/mmPerIn*72*bufferedImage.getWidth());
Double pageHeight = Math.floor(pixelsPerMM/mmPerIn*72*bufferedImage.getHeight());
/*
* Create a PDF document with the first page being the same size first
* image in the TIFF
*/
PDFDocument pdfDocument = PDFDocument.newInstance(new ASRectangle(new double[] { 0, 0, pageWidth, pageHeight }),
PDFOpenOptions.newInstance());
// Convert the BufferedImage to a PDFXObjectImage
PDFXObjectImage image = ImageManager.getPDFImage(bufferedImage, pdfDocument);
/*
* Create a default external graphics state which describes how graphics
* are to be rendered on a device.
*/
PDFExtGState pdfExtGState = PDFExtGState.newInstance(pdfDocument);
/*
* Create a transformation matrix which maps positions from user
* coordinates to device coordinates. There is no transform taking place
* here though but it is a required parameter.
*/
ASMatrix asMatrix = new ASMatrix(pageWidth, 0, 0, pageHeight, 0, 0);
/*
* Now add the image to the first PDF page using the graphics state and
* the transformation matrix.
*/
ImageManager.insertImageInPDF(image,
pdfDocument.requirePages().getPage(0), // the first page of the document
pdfExtGState,
asMatrix);
System.out.println("Page 1 image added.");
// Now do the above for every page in the TIFF adding a new blank PDF for each image
int pages = reader.getNumImages(true);
for (int pageNum = 1; pageNum < pages; pageNum++) {
bufferedImage = reader.read(pageNum);
pixelsPerMM = getPixelsPerMM(reader.getImageMetadata(pageNum));
pageWidth = Math.floor(pixelsPerMM/mmPerIn*72*bufferedImage.getWidth());
pageHeight = Math.floor(pixelsPerMM/mmPerIn*72*bufferedImage.getHeight());
image = ImageManager.getPDFImage(bufferedImage, pdfDocument);
// Create a new blank PDF Page
PDFPage newPage = PDFPage.newInstance(pdfDocument, PDFRectangle.newInstance(pdfDocument,0, 0, pageWidth, pageHeight));
// Add the blank PDF page to the pages tree
pdfDocument.requirePages().appendKid(newPage);
// Add the image to the blank page.
ImageManager.insertImageInPDF(image,
newPage,
PDFExtGState.newInstance(pdfDocument),
new ASMatrix(pageWidth, 0, 0, pageHeight, 0, 0));
System.out.println("Page "+(pageNum+1)+" image added.");
}
/*
* Save the file
*/
ByteWriter outputWriter = SampleFileServices.getRAFByteWriter(outputDir + File.separator + outputFilename);
pdfDocument.save(outputWriter, PDFSaveFullOptions.newInstance(PDFVersion.v1_7));
outputWriter.close();
}
private static Double getPixelsPerMM(IIOMetadata metadata) {
//This code assumes square pixels so it only gets the horizontal measurement
IIOMetadataNode standardTree = (IIOMetadataNode) metadata.getAsTree(IIOMetadataFormatImpl.standardMetadataFormatName);
IIOMetadataNode dimension = (IIOMetadataNode) standardTree.getElementsByTagName("Dimension").item(0);
NodeList pixelSizes = dimension.getElementsByTagName("HorizontalPixelSize");
IIOMetadataNode pixelSize = (IIOMetadataNode) pixelSizes.item(0);
return Double.parseDouble(pixelSize.getAttribute("value"));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment