/* * regain/Thumbnailer - A file search engine providing plenty of formats (Plugin) * Copyright (C) 2011 Come_IN Computerclubs (University of Siegen) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Contact: Come_IN-Team <come_in-team@listserv.uni-siegen.de> */ package de.uni_siegen.wineme.come_in.thumbnailer.thumbnailers; import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics2D; import java.awt.image.BufferedImage; import java.awt.image.ImagingOpException; import java.io.File; import java.io.IOException; import java.util.List; import javax.imageio.ImageIO; import org.apache.commons.io.FileUtils; import org.apache.pdfbox.pdfviewer.PageDrawer; import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.pdmodel.PDPage; import org.apache.pdfbox.pdmodel.common.PDRectangle; import de.uni_siegen.wineme.come_in.thumbnailer.FileDoesNotExistException; import de.uni_siegen.wineme.come_in.thumbnailer.ThumbnailerException; import de.uni_siegen.wineme.come_in.thumbnailer.util.ResizeImage; /** * Renders the first page of a PDF file into a thumbnail. * * Performance note: This takes about 2-3 seconds per file. * (TODO : Try to override PDPage.convertToImage - this is where the heavy lifting takes place) * * Depends on: * <li>PDFBox (>= 1.5.0) */ public class PDFBoxThumbnailer extends AbstractThumbnailer { private static final Color TRANSPARENT_WHITE = new Color(255, 255, 255, 0); @Override public void generateThumbnail(File input, File output) throws IOException, ThumbnailerException { FileDoesNotExistException.check(input); if (input.length() == 0) throw new FileDoesNotExistException("File is empty"); FileUtils.deleteQuietly(output); PDDocument document = null; try { try { document = PDDocument.load(input); } catch (IOException e) { throw new ThumbnailerException("Could not load PDF File", e); } BufferedImage tmpImage = writeImageFirstPage(document, BufferedImage.TYPE_INT_RGB); if (tmpImage.getWidth() == thumbWidth) { ImageIO.write(tmpImage, "PNG", output); } else { ResizeImage resizer = new ResizeImage(thumbWidth, thumbHeight); resizer.resizeMethod = ResizeImage.NO_RESIZE_ONLY_CROP; resizer.setInputImage(tmpImage); resizer.writeOutput(output); } } finally { if( document != null ) { try { document.close(); } catch (IOException e) {} } } } /** * Loosely based on the commandline-Tool PDFImageWriter * @param document * @param imageType * @return * @throws IOException */ private BufferedImage writeImageFirstPage(PDDocument document, int imageType) throws IOException { List<?> pages = document.getDocumentCatalog().getAllPages(); PDPage page = (PDPage)pages.get(0); // resolution: Unfortunately, the resolution is in integer in the call ... so we approximate by taking slightly less (rounding down). /* Before: PDRectangle rect = page.getMediaBox(); float resolution = (thumb_width / rect.getWidth() * 72); page.convertToImage(imageType, (int) resolution); */ // Here is the main work: BufferedImage image = convertToImage(page, imageType, thumbWidth, thumbHeight); return image; } /* */ private BufferedImage convertToImage(PDPage page, int imageType, int thumbWidth, int thumbHeight) /* */ throws IOException /* */ { /* 707 */ PDRectangle mBox = page.findMediaBox(); /* 708 */ float widthPt = mBox.getWidth(); /* 709 */ float heightPt = mBox.getHeight(); /* 711 */ int widthPx = thumbWidth; // Math.round(widthPt * scaling); /* 712 */ int heightPx = thumbHeight; // Math.round(heightPt * scaling); /* 710 */ float scaling = thumbWidth / widthPt; // resolution / 72.0F; /* */ /* 714 */ Dimension pageDimension = new Dimension((int) widthPt, (int) heightPt); /* */ /* 716 */ BufferedImage retval = new BufferedImage(widthPx, heightPx, imageType); /* 717 */ Graphics2D graphics = (Graphics2D)retval.getGraphics(); /* 718 */ graphics.setBackground(TRANSPARENT_WHITE); /* 719 */ graphics.clearRect(0, 0, retval.getWidth(), retval.getHeight()); /* 720 */ graphics.scale(scaling, scaling); /* 721 */ PageDrawer drawer = new PageDrawer(); /* 722 */ drawer.drawPage(graphics, page, pageDimension); /* */ try /* */ { /* 728 */ int rotation = page.findRotation(); /* 729 */ if ((rotation == 90) || (rotation == 270)) /* */ { /* 731 */ int w = retval.getWidth(); /* 732 */ int h = retval.getHeight(); /* 733 */ BufferedImage rotatedImg = new BufferedImage(w, h, retval.getType()); /* 734 */ Graphics2D g = rotatedImg.createGraphics(); /* 735 */ g.rotate(Math.toRadians(rotation), w / 2, h / 2); /* 736 */ g.drawImage(retval, null, 0, 0); /* */ } /* */ } /* */ catch (ImagingOpException e) /* */ { /* 741 */ //log.warn("Unable to rotate page image", e); /* */ } /* */ /* 744 */ return retval; /* */ } /** * Get a List of accepted File Types. * Only PDF Files are accepted. * * @return MIME-Types */ public String[] getAcceptedMIMETypes() { return new String[]{ "application/pdf" }; } }