java转成图片_【JAVA】将PDF转化成图片

这个Java示例展示了如何将PDF转换为最高质量的图像。可以使用命令行运行此程序,通过指定PDF文件路径和输出图像类型。该程序利用JPedal库,允许调整设置以自定义转换过程。
摘要由CSDN通过智能技术生成

1 /**

2 * Example to convert PDF to highest possible quality images3 * Also consider org.jpedal.examples.images.ConvertPagesToImages for faster if quality less important4 *5 * Useful blog article athttp://www.jpedal.org/PDFblog/2009/07/pdf-to-image-quality/

6 *7 * It can run from jar directly using the command8 *9 * java -cp libraries_needed org/jpedal/examples/images/ConvertPagesToHiResImages pdfFilepath inputValues10 *11 * where inputValues is 2 values12 *13 * First Parameter: The full path including the name and extension of the target PDF file.14 * Second Parameter: The output image file type. Choices are tif, jpg and png.15 *16 * See alsohttp://www.jpedal.org/javadoc/org/jpedal/constants/JPedalSettings.htmlfor settings to customise17 */

18

19 /**

20 * ===========================================21 * Java Pdf Extraction Decoding Access Library22 * ===========================================23 *24 * Project Info:http://www.jpedal.org

25 * (C) Copyright 1997-2012, IDRsolutions and Contributors.26 *27 * This file is part of JPedal28 *29 This source code is copyright IDRSolutions 201230

31

32 *33 * ---------------34 * ConvertPagesToHiResImages.java35 * ---------------36 */

37

38 importjava.awt.Graphics2D;39 importjava.awt.image.BufferedImage;40 importjava.io.BufferedOutputStream;41 importjava.io.File;42 importjava.io.FileOutputStream;43 importjava.io.IOException;44 importjava.io.OutputStream;45 import java.util.*;46

47 importjavax.imageio.IIOImage;48 importjavax.imageio.ImageIO;49 importjavax.imageio.ImageTypeSpecifier;50 importjavax.imageio.metadata.IIOMetadata;51 importjavax.imageio.plugins.jpeg.JPEGImageWriteParam;52 importjavax.imageio.stream.ImageOutputStream;53

54 importcom.sun.imageio.plugins.jpeg.JPEGImageWriter;55 importorg.jpedal.PdfDecoder;56 importorg.jpedal.color.ColorSpaces;57 importorg.jpedal.exception.PdfException;58 importorg.jpedal.fonts.FontMappings;59 importorg.jpedal.objects.PdfPageData;60 importorg.jpedal.utils.LogWriter;61 importorg.jpedal.io.ColorSpaceConvertor;62 importorg.jpedal.io.JAIHelper;63 importorg.jpedal.constants.JPedalSettings;64 importorg.jpedal.constants.PageInfo;65 importorg.w3c.dom.Element;66

67 public classConvertPagesToHiResImages {68

69 private static boolean debug = false;70

71 /**correct separator for OS*/

72 final static String separator = System.getProperty( "file.separator");73

74 //only used if between 0 and 1

75 private float JPEGcompression=-1f;76

77 publicConvertPagesToHiResImages() {}78

79 public static void main(String[] args) throwsException {80

81 /*

82 * Change these variables83 */

84 String fileType,pdfFile;85

86 if(args!=null && args.length>1){87

88 pdfFile = args[0];89 fileType= args[1];90

91 //open the file

92 if(pdfFile.toLowerCase().endsWith(".pdf") && (fileType.equals("jpg") || fileType.equals("jpeg") || fileType.equals("png") || fileType.equals("tiff") || fileType.equals("tif"))){93 newConvertPagesToHiResImages(fileType, pdfFile);94 }else{ //open the directory

95

96 File testDir=newFile(pdfFile);97

98 if(testDir.isDirectory()){99

100 /**

101 * get list of files and check directory102 */

103

104 String[] files = null;105 File inputFiles;106

107 /**make sure name ends with a deliminator for correct path later*/

108 if (!pdfFile.endsWith(separator))109 pdfFile = pdfFile +separator;110

111 try{112 inputFiles = newFile(pdfFile);113

114 files =inputFiles.list();115 } catch(Exception ee) {116 LogWriter.writeLog("Exception trying to access file " +ee.getMessage());117 }118

119 /**now work through all pdf files*/

120 for(String file : files) {121

122 if (file.toLowerCase().endsWith(".pdf"))123 new ConvertPagesToHiResImages(fileType, pdfFile +file);124 }125 }else

126 System.out.println("The file to be processed has to be a pdf and the output filetype can only be jpg,png or tiff");127 }128 }else{129 System.out.println("Not enough arguments passed in! Usage: \"C:\\examples\\1.pdf\" \"jpg\"");130 }131 }132

133 /**

134 * main constructor to convert PDF to img135 *@paramfileType136 *@parampdfFile137 *@throwsException138 */

139 public ConvertPagesToHiResImages(String fileType, String pdfFile) throwsException {140

141 long startTime=System.currentTimeMillis();142

143 String outputPath = pdfFile.substring(0, pdfFile.toLowerCase().indexOf(".pdf")) +separator;144 File outputPathFile = newFile(outputPath);145 if (!outputPathFile.exists() || !outputPathFile.isDirectory()) {146 if (!outputPathFile.mkdirs()) {147 if(debug)148 System.err.println("Can't create directory " +outputPath);149 }150 }151

152 //PdfDecoder object provides the conversion

153 final PdfDecoder decoder = new PdfDecoder(true);154

155 //mappings for non-embedded fonts to use156 //FontMappings.setFontReplacements();

157

158 decoder.openPdfFile(pdfFile);159

160 /**

161 * this process is very flaxible to we create a Map and pass in values to select what sort162 * of results we want. There is a choice between methods used and image size. Larger images use more163 * memory and are slower but look better164 */

165 Map mapValues = newHashMap();166

167 /**USEFUL OPTIONS*/

168 //do not scale above this figure

169 mapValues.put(JPedalSettings.EXTRACT_AT_BEST_QUALITY_MAXSCALING, 2);170

171 //alternatively secify a page size (aspect ratio preserved so will do best fit)172 //set a page size (JPedal will put best fit to this)

173 mapValues.put(JPedalSettings.EXTRACT_AT_PAGE_SIZE, new String[]{"2000","1600"});174

175 //which takes priority (default is false)

176 mapValues.put(JPedalSettings.PAGE_SIZE_OVERRIDES_IMAGE, Boolean.TRUE);177

178 PdfDecoder.modifyJPedalParameters(mapValues);179

180 if(debug)181 System.out.println("pdf : " +pdfFile);182

183 try{184 /**

185 * allow output to multiple images with different values on each186 *187 * Note we REMOVE shapes as it is a new feature and we do not want to break existing functions188 */

189 String separation=System.getProperty("org.jpedal.separation");190 if(separation!=null){191

192 Object[] sepValues=new Object[]{7,"",Boolean.FALSE}; //default of normal

193 if(separation.equals("all")){194 sepValues=new Object[]{PdfDecoder.RENDERIMAGES,"image_and_shapes",Boolean.FALSE,195 PdfDecoder.RENDERIMAGES + PdfDecoder.REMOVE_RENDERSHAPES,"image_without_shapes",Boolean.FALSE,196 PdfDecoder.RENDERTEXT,"text_and_shapes",Boolean.TRUE,197 7,"all",Boolean.FALSE,198 PdfDecoder.RENDERTEXT + PdfDecoder.REMOVE_RENDERSHAPES,"text_without_shapes",Boolean.TRUE199 };200 }201

202 int sepCount =sepValues.length;203 for(int seps=0;seps

205 decoder.setRenderMode((Integer) sepValues[seps]);206 extractPageAsImage(fileType, outputPath, decoder,"_"+sepValues[seps+1], (Boolean) sepValues[seps + 2]); //boolean makes last transparent so we can see white text

207 }208

209 }else //just get the page

210 extractPageAsImage(fileType, outputPath, decoder,"",false);211

212 } finally{213

214 decoder.closePdfFile();215 }216 System.out.println("time="+(System.currentTimeMillis()-startTime)/1000);217

218

219 }220

221 /**

222 * convenience method to get a page as a BufferedImage quickly223 * - for bulk conversion, use the other methods224 */

225 public static BufferedImage getHiresPage(int pageNo, intscaling, String pdfFile){226

227 BufferedImage imageToSave = null;228

229 final PdfDecoder decoder = new PdfDecoder(true);230

231 try{232 //mappings for non-embedded fonts to use233 //FontMappings.setFontReplacements();

234

235 decoder.openPdfFile(pdfFile);236

237 PdfPageData pageData =decoder.getPdfPageData();238 int width=scaling*pageData.getCropBoxWidth(pageNo);239 int height=scaling*pageData.getCropBoxHeight(pageNo);240

241 Map mapValues = newHashMap();242

243 /**USEFUL OPTIONS*/

244 //do not scale above this figure

245 mapValues.put(JPedalSettings.EXTRACT_AT_BEST_QUALITY_MAXSCALING, 2);246

247 //alternatively secify a page size (aspect ratio preserved so will do best fit)248 //set a page size (JPedal will put best fit to this)

249 mapValues.put(JPedalSettings.EXTRACT_AT_PAGE_SIZE, newString[]{String.valueOf(width),String.valueOf(height)});250

251 //which takes priority (default is false)

252 mapValues.put(JPedalSettings.PAGE_SIZE_OVERRIDES_IMAGE, Boolean.TRUE);253

254 PdfDecoder.modifyJPedalParameters(mapValues);255

256 imageToSave = decoder.getPageAsHiRes(pageNo,null,false);257

258 } catch(PdfException e) {259 e.printStackTrace();260 } finally{261

262 decoder.closePdfFile();263 }264 returnimageToSave;265 }266

267 /**

268 * actual conversion of a PDF page into an image269 *@paramfileType270 *@paramoutputPath271 *@paramdecoder272 *@paramprefix273 *@paramisTransparent274 *@throwsPdfException275 *@throwsIOException276 */

277 private void extractPageAsImage(String fileType, String outputPath, PdfDecoder decoder, String prefix, boolean isTransparent) throwsPdfException, IOException {278

279

280 //page range

281 int start=1, end=decoder.getPageCount();282

283 //container if the user is creating a multi-image tiff

284 BufferedImage[] multiPages = new BufferedImage[1 + (end-start)];285

286 /**

287 * set of JVM flags which allow user control on process288 */

289

290

291 //TIFF OPTIONS/

292

293 String multiPageFlag=System.getProperty("org.jpedal.multipage_tiff");294 boolean isSingleOutputFile=multiPageFlag!=null && multiPageFlag.toLowerCase().equals("true");295

296 String tiffFlag=System.getProperty("org.jpedal.compress_tiff");297 boolean compressTiffs = tiffFlag!=null && tiffFlag.toLowerCase().equals("true");298

299 //JPEG OPTIONS/300

301 //allow user to specify value

302 String rawJPEGComp=System.getProperty("org.jpedal.compression_jpeg");303 if(rawJPEGComp!=null){304 try{305 JPEGcompression=Float.parseFloat(rawJPEGComp);306 }catch(Exception e){307 e.printStackTrace();308 }309 if(JPEGcompression<0 || JPEGcompression>1)310 throw new RuntimeException("Invalid value for JPEG compression - must be between 0 and 1");311

312 }313

314 String jpgFlag=System.getProperty("org.jpedal.jpeg_dpi");315

316 ///

317

318 for (int pageNo = start; pageNo < end+1; pageNo++) {319

320 if(debug)321 System.out.println("page : " +pageNo);322

323 /**

324 * example1 - ask JPedal to return from decoding if file takes too long (time is in millis)325 * will reset after exit so call for each page326 */

327 //decoder.setPageDecodeStatus(DecodeStatus.Timeout,new Integer(20) );

328 /**

329 * example2 thread which will ask JPedal to time out and return from decoding330 * will reset after exit so call for each page331 */

332 /**

333 Thread a=new Thread(){334 public void run() {335

336 while(true){337 //simulate 2 second delay338 try {339 Thread.sleep(2000);340 } catch (InterruptedException e) {341 e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.342 }343

344 //tell JPedal to exit asap345 decoder.setPageDecodeStatus(DecodeStatus.Timeout, Boolean.TRUE);346

347 }348 }349 };350

351 //simulate a second thread352 a.start();353

354 //see code after line decoder.getPageAsHiRes(pageNo); for tracking whether JPedal timed out and returned355 /**/

356

357 /**

358 * If you are using decoder.getPageAsHiRes() after passing additional parameters into JPedal using the static method359 * PdfDecoder.modifyJPedalParameters(), then getPageAsHiRes() wont necessarily be thread safe. If you want to use360 * getPageAsHiRes() and pass in additional parameters, in a thread safe mannor, please use the method361 * getPageAsHiRes(int pageIndex, Map params) or getPageAsHiRes(int pageIndex, Map params, boolean isTransparent) and362 * pass the additional parameters in directly to the getPageAsHiRes() method without calling PdfDecoder.modifyJPedalParameters()363 * first.364 *365 * Please see org/jpedal/examples/images/ConvertPagesToImages.java.html for more details on how to use HiRes image conversion366 */

367 BufferedImage imageToSave = decoder.getPageAsHiRes(pageNo,null,isTransparent);368

369 String imageFormat = System.getProperty("org.jpedal.imageType");370 if(imageFormat!=null){371 if(isNumber(imageFormat)){372 int iFormat =Integer.parseInt(imageFormat);373 if(iFormat>-1 && iFormat<14){374 BufferedImage tempImage = newBufferedImage(imageToSave.getWidth(), imageToSave.getHeight(), iFormat);375 Graphics2D g =tempImage.createGraphics();376 g.drawImage(imageToSave, null, null);377

378 imageToSave =tempImage;379 }else{380 System.err.println("Image Type is not valid. Value should be a digit between 0 - 13 based on the BufferedImage TYPE variables.");381 }382 }else{383 System.err.println("Image Type provided is not an Integer. Value should be a digit between 0 - 13 based on the BufferedImage TYPE variables.");384 }385 }386

387 //show status flag

388 /**

389 if(decoder.getPageDecodeStatus(DecodeStatus.Timeout))390 System.out.println("Timeout on decoding");391 else392 System.out.println("Done");393 /**/

394

395 decoder.flushObjectValues(true);396

397 //System.out.println("w="+imageToSave.getWidth()+" h="+imageToSave.getHeight());398 //image needs to be sRGB for JPEG

399 if(fileType.equals("jpg"))400 imageToSave =ColorSpaceConvertor.convertToRGB(imageToSave);401

402

403 String outputFileName;404 if(isSingleOutputFile)405 outputFileName = outputPath+ "allPages"+prefix+ '.' +fileType;406 else{407 /**

408 * create a name with zeros for if more than 9 pages appears in correct order409 */

410 String pageAsString=String.valueOf(pageNo);411 String maxPageSize=String.valueOf(end);412 int padding=maxPageSize.length()-pageAsString.length();413 for(int ii=0;ii

416 outputFileName = outputPath + "page" + pageAsString +prefix + '.' +fileType;417 }418

419 //if just gray we can reduce memory usage by converting image to Grayscale

420

421 /**

422 * see what Colorspaces used and reduce image if appropriate423 * (only does Gray at present)424 *425 * Can return null value if not sure426 */

427 Iterator colorspacesUsed=decoder.getPageInfo(PageInfo.COLORSPACES);428

429 intnextID;430 boolean isGrayOnly=colorspacesUsed!=null; //assume true and disprove

431

432 while(colorspacesUsed!=null &&colorspacesUsed.hasNext()){433 nextID=(Integer) (colorspacesUsed.next());434

435 if(nextID!= ColorSpaces.DeviceGray && nextID!=ColorSpaces.CalGray)436 isGrayOnly=false;437 }438

439 //draw onto GRAY image to reduce colour depth440 //(converts ARGB to gray)

441 if(isGrayOnly){442 BufferedImage image_to_save2=newBufferedImage(imageToSave.getWidth(),imageToSave.getHeight(), BufferedImage.TYPE_BYTE_GRAY);443 image_to_save2.getGraphics().drawImage(imageToSave,0,0,null);444 imageToSave =image_to_save2;445 }446

447 //put image in array if multi-images (we save on last page in code below)

448 if(isSingleOutputFile)449 multiPages[pageNo-start] =imageToSave;450

451 //we save the image out here

452 if (imageToSave != null) {453

454 /**BufferedImage does not support any dpi concept. A higher dpi can be created455 * using JAI to convert to a higher dpi image*/

456

457 //shrink the page to 50% with graphics2D transformation458 //- add your own parameters as needed459 //you may want to replace null with a hints object if you460 //want to fine tune quality.

461

462 /**example 1 biliniear scaling463 AffineTransform scale = new AffineTransform();464 scale.scale(.5, .5); //50% as a decimal465 AffineTransformOp scalingOp =new AffineTransformOp(scale, null);466 image_to_save =scalingOp.filter(image_to_save, null);467

468 */

469

470 if(JAIHelper.isJAIused())471 JAIHelper.confirmJAIOnClasspath();472

473 if(JAIHelper.isJAIused() && fileType.startsWith("tif")){474

475 com.sun.media.jai.codec.TIFFEncodeParam params = newcom.sun.media.jai.codec.TIFFEncodeParam();476

477 if(compressTiffs)478 params.setCompression(com.sun.media.jai.codec.TIFFEncodeParam.COMPRESSION_PACKBITS);479

480 if(!isSingleOutputFile){481 BufferedOutputStream os = new BufferedOutputStream(newFileOutputStream(outputFileName));482

483 javax.media.jai.JAI.create("encode", imageToSave, os, "TIFF", params);484 }else if(isSingleOutputFile && pageNo ==end){485 OutputStream out = new BufferedOutputStream(newFileOutputStream(outputFileName));486 com.sun.media.jai.codec.ImageEncoder encoder = com.sun.media.jai.codec.ImageCodec.createImageEncoder("TIFF", out, params);487 List vector = newArrayList();488 vector.addAll(Arrays.asList(multiPages).subList(1, multiPages.length));489

490 params.setExtraImages(vector.iterator());491

492 encoder.encode(multiPages[0]);493 out.close();494 }495 }else if(isSingleOutputFile){496 //non-JAI

497 } else if ((jpgFlag != null || rawJPEGComp!=null) && fileType.startsWith("jp") &&JAIHelper.isJAIused()) {498

499 saveAsJPEG(jpgFlag, imageToSave, JPEGcompression, new BufferedOutputStream(newFileOutputStream(outputFileName)));500 } else{501

502 BufferedOutputStream bos= new BufferedOutputStream(new FileOutputStream(newFile(outputFileName)));503 ImageIO.write(imageToSave, fileType, bos);504 bos.flush();505 bos.close();506 }507 //if you just want to save the image, use something like508 //javax.imageio.ImageIO.write((java.awt.image.RenderedImage)image_to_save,"png",new java.io.FileOutputStream(output_dir + page + image_name+".png"));

509

510 }511

512 imageToSave.flush();513

514 if(debug){515 System.out.println("Created : " +outputFileName);516

517 }518 }519 }520

521 /**test to see if string or number*/

522 private static booleanisNumber(String value) {523

524 //assume true and see if proved wrong

525 boolean isNumber=true;526

527 int charCount=value.length();528 for(int i=0;i'9')){531 isNumber=false;532 i=charCount;533 }534 }535

536 returnisNumber;537 }538

539 private static void saveAsJPEG(String jpgFlag,BufferedImage image_to_save, float JPEGcompression, BufferedOutputStream fos) throwsIOException {540

541 //useful documentation athttp://docs.oracle.com/javase/7/docs/api/javax/imageio/metadata/doc-files/jpeg_metadata.html

542 //useful example program athttp://johnbokma.com/java/obtaining-image-metadata.htmlto output JPEG data543

544 //old jpeg class545 //com.sun.image.codec.jpeg.JPEGImageEncoder jpegEncoder = com.sun.image.codec.jpeg.JPEGCodec.createJPEGEncoder(fos);546 //com.sun.image.codec.jpeg.JPEGEncodeParam jpegEncodeParam = jpegEncoder.getDefaultJPEGEncodeParam(image_to_save);547

548 //Image writer

549 JPEGImageWriter imageWriter = (JPEGImageWriter) ImageIO.getImageWritersBySuffix("jpeg").next();550 ImageOutputStream ios =ImageIO.createImageOutputStream(fos);551 imageWriter.setOutput(ios);552

553 //and metadata

554 IIOMetadata imageMetaData = imageWriter.getDefaultImageMetadata(new ImageTypeSpecifier(image_to_save), null);555

556 if (jpgFlag != null){557

558 int dpi = 96;559

560 try{561 dpi =Integer.parseInt(jpgFlag);562 } catch(Exception e) {563 e.printStackTrace();564 }565

566 //old metadata567 //jpegEncodeParam.setDensityUnit(com.sun.image.codec.jpeg.JPEGEncodeParam.DENSITY_UNIT_DOTS_INCH);568 //jpegEncodeParam.setXDensity(dpi);569 //jpegEncodeParam.setYDensity(dpi);570

571 //new metadata

572 Element tree = (Element) imageMetaData.getAsTree("javax_imageio_jpeg_image_1.0");573 Element jfif = (Element)tree.getElementsByTagName("app0JFIF").item(0);574 jfif.setAttribute("Xdensity", Integer.toString(dpi));575 jfif.setAttribute("Ydensity", Integer.toString(dpi));576

577 }578

579 if(JPEGcompression>=0 && JPEGcompression<=1f){580

581 //old compression582 //jpegEncodeParam.setQuality(JPEGcompression,false);583

584 //new Compression

585 JPEGImageWriteParam jpegParams =(JPEGImageWriteParam) imageWriter.getDefaultWriteParam();586 jpegParams.setCompressionMode(JPEGImageWriteParam.MODE_EXPLICIT);587 jpegParams.setCompressionQuality(JPEGcompression);588

589 }590

591 //old write and clean592 //jpegEncoder.encode(image_to_save, jpegEncodeParam);593

594 //new Write and clean up

595 imageWriter.write(imageMetaData, new IIOImage(image_to_save, null, null), null);596 ios.close();597 imageWriter.dispose();598

599 }600 }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值