package com.revolsys.raster.io.format.pdf;
import java.awt.Graphics2D;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.List;
import org.apache.pdfbox.cos.COSDictionary;
import org.apache.pdfbox.cos.COSName;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import com.revolsys.geometry.model.BoundingBox;
import com.revolsys.logging.Logs;
import com.revolsys.raster.JaiGeoreferencedImage;
import com.revolsys.spring.resource.Resource;
public class PdfImage extends JaiGeoreferencedImage {
public PdfImage(final Resource imageResource) {
setImageResource(imageResource);
setRenderedImage(newBufferedImage());
if (!hasGeometryFactory()) {
loadProjectionFile();
}
if (!hasBoundingBox()) {
loadWorldFile();
}
}
@Override
public String getWorldFileExtension() {
return "pfw";
}
protected BufferedImage newBufferedImage() {
final Resource imageResource = getImageResource();
try {
final File file = Resource.getOrDownloadFile(imageResource);
// TODO password support
final PDDocument document = PDDocument.loadNonSeq(file, null, null);
@SuppressWarnings("unchecked")
final List<PDPage> pages = document.getDocumentCatalog().getAllPages();
if (pages.isEmpty()) {
throw new RuntimeException("PDF file " + imageResource + " doesn't contain any pages");
} else {
if (pages.size() > 1) {
Logs.warn(this, "PDF file " + imageResource + " doesn't contais more than 1 page");
}
final PDPage page = pages.get(0);
final COSDictionary pageDictionary = page.getCOSDictionary();
final Rectangle2D mediaBox = PdfUtil.findRectangle(pageDictionary, COSName.MEDIA_BOX);
final int resolution = 72;
BufferedImage image = page.convertToImage(BufferedImage.TYPE_INT_ARGB, resolution);
final COSDictionary viewport = PdfUtil.getPageViewport(pageDictionary);
if (viewport != null) {
final Rectangle2D bbox = PdfUtil.findRectangle(viewport, COSName.BBOX);
if (bbox != null) {
final double boxX = bbox.getX();
final double boxY = bbox.getY();
final int boxWidth = (int)bbox.getWidth();
final int boxHeight = (int)bbox.getHeight();
final BufferedImage viewportImage = new BufferedImage(boxWidth, boxHeight,
BufferedImage.TYPE_INT_ARGB);
final Graphics2D graphics = (Graphics2D)viewportImage.getGraphics();
final double translateY = -(mediaBox.getHeight() - (boxHeight + boxY));
graphics.translate(-boxX, translateY);
graphics.scale(1, 1);
graphics.drawImage(image, 0, 0, null);
graphics.dispose();
image = viewportImage;
}
final BoundingBox boundingBox = PdfUtil.getViewportBoundingBox(viewport);
setBoundingBox(boundingBox);
setResolution(boundingBox.getWidth() / image.getWidth());
}
return image;
}
} catch (final IOException e) {
throw new RuntimeException("Error loading PDF file " + imageResource, e);
}
}
}