PageRenderTime 35ms CodeModel.GetById 9ms app.highlight 22ms RepoModel.GetById 1ms app.codeStats 0ms

/tools/src/main/java/org/apache/pdfbox/tools/PDFToImage.java

https://github.com/apache/pdfbox
Java | 323 lines | 263 code | 20 blank | 40 comment | 56 complexity | 3be8eae9325b8b8c4446a0ae3e0e0a83 MD5 | raw file
  1/*
  2 * Licensed to the Apache Software Foundation (ASF) under one or more
  3 * contributor license agreements.  See the NOTICE file distributed with
  4 * this work for additional information regarding copyright ownership.
  5 * The ASF licenses this file to You under the Apache License, Version 2.0
  6 * (the "License"); you may not use this file except in compliance with
  7 * the License.  You may obtain a copy of the License at
  8 *
  9 *      http://www.apache.org/licenses/LICENSE-2.0
 10 *
 11 * Unless required by applicable law or agreed to in writing, software
 12 * distributed under the License is distributed on an "AS IS" BASIS,
 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 14 * See the License for the specific language governing permissions and
 15 * limitations under the License.
 16 */
 17package org.apache.pdfbox.tools;
 18
 19import java.awt.HeadlessException;
 20import java.awt.Toolkit;
 21import java.awt.image.BufferedImage;
 22import java.io.File;
 23import java.io.IOException;
 24
 25import javax.imageio.ImageIO;
 26
 27import org.apache.pdfbox.pdmodel.PDDocument;
 28import org.apache.pdfbox.pdmodel.PDPage;
 29import org.apache.pdfbox.pdmodel.common.PDRectangle;
 30import org.apache.pdfbox.rendering.ImageType;
 31import org.apache.pdfbox.rendering.PDFRenderer;
 32import org.apache.pdfbox.tools.imageio.ImageIOUtil;
 33
 34/**
 35 * Convert a PDF document to an image.
 36 *
 37 * @author Ben Litchfield
 38 */
 39public final class PDFToImage
 40{
 41    private static final String PASSWORD = "-password";
 42    private static final String START_PAGE = "-startPage";
 43    private static final String END_PAGE = "-endPage";
 44    private static final String PAGE = "-page";
 45    private static final String IMAGE_TYPE = "-imageType";
 46    private static final String FORMAT = "-format";
 47    private static final String OUTPUT_PREFIX = "-outputPrefix";
 48    private static final String PREFIX = "-prefix";
 49    private static final String COLOR = "-color";
 50    private static final String RESOLUTION = "-resolution";
 51    private static final String DPI = "-dpi";
 52    private static final String CROPBOX = "-cropbox";
 53    private static final String TIME = "-time";
 54
 55    /**
 56     * private constructor.
 57    */
 58    private PDFToImage()
 59    {
 60        //static class
 61    }
 62
 63    /**
 64     * Infamous main method.
 65     *
 66     * @param args Command line arguments, should be one and a reference to a file.
 67     *
 68     * @throws IOException If there is an error parsing the document.
 69     */
 70    public static void main( String[] args ) throws IOException
 71    {
 72        // suppress the Dock icon on OS X
 73        System.setProperty("apple.awt.UIElement", "true");
 74
 75        String password = "";
 76        String pdfFile = null;
 77        String outputPrefix = null;
 78        String imageFormat = "jpg";
 79        int startPage = 1;
 80        int endPage = Integer.MAX_VALUE;
 81        String color = "rgb";
 82        int dpi;
 83        float cropBoxLowerLeftX = 0;
 84        float cropBoxLowerLeftY = 0;
 85        float cropBoxUpperRightX = 0;
 86        float cropBoxUpperRightY = 0;
 87        boolean showTime = false;
 88        try
 89        {
 90            dpi = Toolkit.getDefaultToolkit().getScreenResolution();
 91        }
 92        catch( HeadlessException e )
 93        {
 94            dpi = 96;
 95        }
 96        for( int i = 0; i < args.length; i++ )
 97        {
 98            if( args[i].equals( PASSWORD ) )
 99            {
100                i++;
101                if( i >= args.length )
102                {
103                    usage();
104                }
105                password = args[i];
106            }
107            else if( args[i].equals( START_PAGE ) )
108            {
109                i++;
110                if( i >= args.length )
111                {
112                    usage();
113                }
114                startPage = Integer.parseInt( args[i] );
115            }
116            else if( args[i].equals( END_PAGE ) )
117            {
118                i++;
119                if( i >= args.length )
120                {
121                    usage();
122                }
123                endPage = Integer.parseInt( args[i] );
124            }
125            else if( args[i].equals( PAGE ) )
126            {
127                i++;
128                if( i >= args.length )
129                {
130                    usage();
131                }
132                startPage = Integer.parseInt( args[i] );
133                endPage = Integer.parseInt( args[i] );
134            }
135            else if( args[i].equals(IMAGE_TYPE) || args[i].equals(FORMAT) )
136            {
137                i++;
138                imageFormat = args[i];
139            }
140            else if( args[i].equals( OUTPUT_PREFIX ) || args[i].equals( PREFIX ) )
141            {
142                i++;
143                outputPrefix = args[i];
144            }
145            else if( args[i].equals( COLOR ) )
146            {
147                i++;
148                color = args[i];
149            }
150            else if( args[i].equals( RESOLUTION ) || args[i].equals( DPI ) )
151            {
152                i++;
153                dpi = Integer.parseInt(args[i]);
154            }
155            else if( args[i].equals( CROPBOX ) )
156            {
157                i++;
158                cropBoxLowerLeftX = Float.valueOf(args[i]);
159                i++;
160                cropBoxLowerLeftY = Float.valueOf(args[i]);
161                i++;
162                cropBoxUpperRightX = Float.valueOf(args[i]);
163                i++;
164                cropBoxUpperRightY = Float.valueOf(args[i]);
165            }
166            else if( args[i].equals( TIME ) )
167            {
168                showTime = true;
169            }
170            else
171            {
172                if( pdfFile == null )
173                {
174                    pdfFile = args[i];
175                }
176            }
177        }
178        if( pdfFile == null )
179        {
180            usage();
181        }
182        else
183        {
184            if(outputPrefix == null)
185            {
186                outputPrefix = pdfFile.substring( 0, pdfFile.lastIndexOf( '.' ));
187            }
188
189            PDDocument document = null;
190            try
191            {
192                document = PDDocument.load(new File(pdfFile), password);
193
194                ImageType imageType = null;
195                if ("bilevel".equalsIgnoreCase(color))
196                {
197                    imageType = ImageType.BINARY;
198                }
199                else if ("gray".equalsIgnoreCase(color))
200                {
201                    imageType = ImageType.GRAY;
202                }
203                else if ("rgb".equalsIgnoreCase(color))
204                {
205                    imageType = ImageType.RGB;
206                }
207                else if ("rgba".equalsIgnoreCase(color))
208                {
209                    imageType = ImageType.ARGB;
210                }
211                
212                if (imageType == null)
213                {
214                    System.err.println( "Error: Invalid color." );
215                    System.exit( 2 );
216                }
217
218                //if a CropBox has been specified, update the CropBox:
219                //changeCropBoxes(PDDocument document,float a, float b, float c,float d)
220                if ( cropBoxLowerLeftX!=0 || cropBoxLowerLeftY!=0
221                        || cropBoxUpperRightX!=0 || cropBoxUpperRightY!=0 )
222                {
223                    changeCropBox(document,
224                            cropBoxLowerLeftX, cropBoxLowerLeftY,
225                            cropBoxUpperRightX, cropBoxUpperRightY);
226                }
227
228                long startTime = System.nanoTime();
229
230                // render the pages
231                boolean success = true;
232                endPage = Math.min(endPage, document.getNumberOfPages());
233                PDFRenderer renderer = new PDFRenderer(document);
234                for (int i = startPage - 1; i < endPage; i++)
235                {
236                    BufferedImage image = renderer.renderImageWithDPI(i, dpi, imageType);
237                    String fileName = outputPrefix + (i + 1) + "." + imageFormat;
238                    success &= ImageIOUtil.writeImage(image, fileName, dpi);
239                }
240
241                // performance stats
242                long endTime = System.nanoTime();
243                long duration = endTime - startTime;
244                int count = 1 + endPage - startPage;
245                if (showTime)
246                {
247                    System.err.printf("Rendered %d page%s in %dms\n", count, count == 1 ? "" : "s",
248                                      duration / 1000000);
249                }
250
251                if (!success)
252                {
253                    System.err.println( "Error: no writer found for image format '"
254                            + imageFormat + "'" );
255                    System.exit(1);
256                }
257            }
258            finally
259            {
260                if( document != null )
261                {
262                    document.close();
263                }
264            }
265        }
266    }
267
268    /**
269     * This will print the usage requirements and exit.
270     */
271    private static void usage()
272    {
273        String message = "Usage: java -jar pdfbox-app-x.y.z.jar PDFToImage [options] <inputfile>\n"
274            + "\nOptions:\n"
275            + "  -password  <password>            : Password to decrypt document\n"
276            + "  -format <string>                 : Image format: " + getImageFormats() + "\n"
277            + "  -prefix <string>                 : Filename prefix for image files\n"
278            + "  -page <number>                   : The only page to extract (1-based)\n"
279            + "  -startPage <int>                 : The first page to start extraction (1-based)\n"
280            + "  -endPage <int>                   : The last page to extract(inclusive)\n"
281            + "  -color <int>                     : The color depth (valid: bilevel, indexed, gray, rgb, rgba)\n"
282            + "  -dpi <int>                       : The DPI of the output image\n"
283            + "  -cropbox <int> <int> <int> <int> : The page area to export\n"
284            + "  -time                            : Prints timing information to stdout\n"
285            + "  <inputfile>                      : The PDF document to use\n";
286        
287        System.err.println(message);
288        System.exit( 1 );
289    }
290
291    private static String getImageFormats()
292    {
293        StringBuilder retval = new StringBuilder();
294        String[] formats = ImageIO.getReaderFormatNames();
295        for( int i = 0; i < formats.length; i++ )
296        {
297           if (formats[i].equalsIgnoreCase(formats[i]))
298           {
299               retval.append( formats[i] );
300               if( i + 1 < formats.length )
301               {
302                   retval.append( ", " );
303               }
304           }
305        }
306        return retval.toString();
307    }
308
309    private static void changeCropBox(PDDocument document, float a, float b, float c, float d)
310    {
311        for (PDPage page : document.getPages())
312        {
313            System.out.println("resizing page");
314            PDRectangle rectangle = new PDRectangle();
315            rectangle.setLowerLeftX(a);
316            rectangle.setLowerLeftY(b);
317            rectangle.setUpperRightX(c);
318            rectangle.setUpperRightY(d);
319            page.setCropBox(rectangle);
320
321        }
322    }
323}