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