/* * Copyright 2006-2017 ICEsoft Technologies Canada Corp. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the * License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an "AS * IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either * express or implied. See the License for the specific language * governing permissions and limitations under the License. */ import org.icepdf.core.exceptions.PDFException; import org.icepdf.core.exceptions.PDFSecurityException; import org.icepdf.core.pobjects.Document; import org.icepdf.core.pobjects.PDimension; import org.icepdf.core.pobjects.Page; import org.icepdf.core.pobjects.graphics.WatermarkCallback; import org.icepdf.core.util.GraphicsRenderingHints; import org.icepdf.ri.util.FontPropertiesManager; import org.icepdf.ri.util.PropertiesManager; import javax.imageio.ImageIO; import java.awt.*; import java.awt.geom.AffineTransform; import java.awt.geom.Rectangle2D; import java.awt.image.BufferedImage; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.util.ArrayList; import java.util.ResourceBundle; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; /** * The <code>WatermarkPageCapture</code> class is an example of how to save page * captures to disk with a watermark. A file specified at the command line is * opened and every page in the document is captured as an image and saved to * disk as a PNG graphic file. Each page with be water marked with "This Page X" * where X is the page number. * * @since 5.1.0 */ public class WatermarkPageCapture { public static void main(String[] args) { // Get a file from the command line to open String filePath = args[0]; // read/store the font cache. ResourceBundle messageBundle = ResourceBundle.getBundle( PropertiesManager.DEFAULT_MESSAGE_BUNDLE); PropertiesManager properties = new PropertiesManager(System.getProperties(), ResourceBundle.getBundle(PropertiesManager.DEFAULT_MESSAGE_BUNDLE)); new FontPropertiesManager(properties, System.getProperties(), messageBundle); // start the capture WatermarkPageCapture pageCapture = new WatermarkPageCapture(); pageCapture.capturePages(filePath); } public void capturePages(String filePath) { // open the url Document document = new Document(); // setup two threads to handle image extraction. ExecutorService executorService = Executors.newFixedThreadPool(4); try { // open the document document.setFile(filePath); // attache a watermark document.setWatermarkCallback(new MyWatermarkCallback()); // create a list of callables. int pages = document.getNumberOfPages(); java.util.List<Callable<Void>> callables = new ArrayList<Callable<Void>>(pages); for (int i = 0; i <= pages; i++) { callables.add(new CapturePage(document, i)); } executorService.invokeAll(callables); executorService.submit(new DocumentCloser(document)).get(); } catch (InterruptedException e) { System.out.println("Error parsing PDF document " + e); } catch (ExecutionException e) { System.out.println("Error parsing PDF document " + e); } catch (PDFException ex) { System.out.println("Error parsing PDF document " + ex); } catch (PDFSecurityException ex) { System.out.println("Error encryption not supported " + ex); } catch (FileNotFoundException ex) { System.out.println("Error file not found " + ex); } catch (IOException ex) { System.out.println("Error handling PDF document " + ex); } executorService.shutdown(); } /** * Sample watermark call that writes some text on each page. */ public class MyWatermarkCallback implements WatermarkCallback { // to avoid memory leaks be careful not to save an instance of page in // your implementation public void paintWatermark(Graphics g, Page page, int renderHintType, int boundary, float userRotation, float userZoom) { Graphics2D g2 = (Graphics2D) g; // setup the graphics context and a 45 degree rotation effect. Rectangle2D.Float mediaBox = page.getPageBoundary(boundary); AffineTransform af = new AffineTransform(); af.scale(1, -1); af.rotate(-45.0 * Math.PI / 180.0, mediaBox.getWidth() / 2.0, -mediaBox .getHeight() / 2.0); g2.transform(af); // apply transparency g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.75f)); // ICEpdf red. g2.setColor(new Color(186, 0, 0)); // draw Some text. String footerText = "This Page " + (page.getPageIndex() + 1); g2.setFont(new java.awt.Font("Dialog", java.awt.Font.BOLD, 36)); FontMetrics fontMetrics = g2.getFontMetrics(); Rectangle2D fontBounds = fontMetrics.getStringBounds(footerText.toCharArray(), 0, footerText.length(), g2); int x = (int) (mediaBox.x + (mediaBox.width - fontBounds.getWidth()) / 2.0); int y = -(int) (mediaBox.y - (mediaBox.height - fontBounds.getHeight()) / 2.0); g2.drawString(footerText, x, y); } } /** * Captures images found in a page parse to file. */ public class CapturePage implements Callable<Void> { private Document document; private int pageNumber; private float scale = 1f; private float rotation = 0f; private CapturePage(Document document, int pageNumber) { this.document = document; this.pageNumber = pageNumber; } public Void call() { try { Page page = document.getPageTree().getPage(pageNumber); page.init(); PDimension sz = page.getSize(Page.BOUNDARY_CROPBOX, rotation, scale); int pageWidth = (int) sz.getWidth(); int pageHeight = (int) sz.getHeight(); BufferedImage image = new BufferedImage(pageWidth, pageHeight, BufferedImage.TYPE_INT_RGB); Graphics g = image.createGraphics(); page.paint(g, GraphicsRenderingHints.PRINT, Page.BOUNDARY_CROPBOX, rotation, scale); g.dispose(); // capture the page image to file System.out.println("Capturing page " + pageNumber); File file = new File("imageCapture_" + pageNumber + ".png"); ImageIO.write(image, "png", file); image.flush(); } catch (Throwable e) { e.printStackTrace(); } return null; } } /** * Disposes the document. */ public class DocumentCloser implements Callable<Void> { private Document document; private DocumentCloser(Document document) { this.document = document; } public Void call() { if (document != null) { document.dispose(); System.out.println("Document disposed"); } return null; } } }