Last active
September 13, 2015 07:33
-
-
Save JoelGeraci-Datalogics/1e00f1d45764e29de5d4 to your computer and use it in GitHub Desktop.
Convert TIFF to PDF Using the Datalogics PDF Java Toolkit
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* 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