001 package railo.runtime.text.pdf; 002 003 import java.awt.image.BufferedImage; 004 import java.io.ByteArrayInputStream; 005 import java.io.File; 006 import java.io.FileOutputStream; 007 import java.io.IOException; 008 import java.io.RandomAccessFile; 009 import java.nio.ByteBuffer; 010 import java.nio.channels.FileChannel; 011 import java.util.Set; 012 013 import railo.commons.io.IOUtil; 014 import railo.commons.io.res.Resource; 015 import railo.runtime.exp.ExpressionException; 016 import railo.runtime.exp.PageException; 017 import railo.runtime.img.Image; 018 019 import com.sun.pdfview.PDFFile; 020 import com.sun.pdfview.PDFPage; 021 022 public class PDF2ImagePDFRenderer extends PDF2Image { 023 024 public PDF2ImagePDFRenderer(){ 025 PDFFile.class.getName();// this is needed, that the class throws a error when the PDFRenderer.jar is not in the enviroment 026 } 027 028 @Override 029 public Image toImage(byte[] input, int pageNumber) throws IOException { 030 031 File file = File.createTempFile("pdf2img", "pdf"); 032 033 try{ 034 copy(input,file); 035 PDFFile pdffile = toPDFFile(file); 036 037 // draw a single page to an image 038 PDFPage page = pdffile.getPage(pageNumber); 039 040 return toImage(page,(int)page.getBBox().getWidth(),(int)page.getBBox().getHeight(),false); 041 042 043 } 044 finally{ 045 deleteEL(file); 046 } 047 } 048 049 private static Image toImage(PDFPage page, int width, int height,boolean transparent) { 050 int w = (int)page.getBBox().getWidth(); 051 int h = (int)page.getBBox().getHeight(); 052 java.awt.Rectangle rect = new java.awt.Rectangle(0,0,w,h); 053 054 BufferedImage bi = Image.toBufferedImage(page.getImage( 055 width, height, //width & height 056 rect, // clip rect 057 null, // null for the ImageObserver 058 !transparent, // fill background with white 059 true // block until drawing is done 060 )); 061 062 return new Image(bi); 063 } 064 065 @Override 066 public void writeImages(byte[] input, Set pages, Resource outputDirectory, 067 String prefix, String format, int scale, boolean overwrite, 068 boolean goodQuality, boolean transparent) throws PageException, 069 IOException { 070 071 072 File file = File.createTempFile("pdf2img", "pdf"); 073 try{ 074 copy(input,file); 075 PDFFile pdf = toPDFFile(file); 076 077 Resource res; 078 int count = pdf.getNumPages(); 079 080 for(int page=1;page<=count;page++) { 081 if(pages!=null && !pages.contains(Integer.valueOf(page)))continue; 082 res=createDestinationResource(outputDirectory,prefix,page,format,overwrite); 083 //res=outputDirectory.getRealResource(prefix+"_page_"+page+"."+format); 084 writeImage(pdf,page,res,format,scale,overwrite,goodQuality, transparent); 085 } 086 } 087 finally{ 088 deleteEL(file); 089 } 090 } 091 092 private static void writeImage(PDFFile pdf, int pageNumber, Resource destination,String format, int scale, 093 boolean overwrite, boolean goodQuality, boolean transparent) throws PageException, IOException { 094 095 PDFPage page = pdf.getPage(pageNumber); 096 097 if(scale<1) throw new ExpressionException("scale ["+scale+"] should be at least 1"); 098 099 int width = (int)page.getBBox().getWidth(); 100 int height = (int)page.getBBox().getHeight(); 101 if(scale!=100){ 102 double s=(scale)/100d; 103 width= (int)((width)*s); 104 height= (int)((height)*s); 105 106 107 } 108 Image img=toImage(page, width, height,transparent); 109 img.writeOut(destination,format, overwrite, 1f); 110 } 111 112 private PDFFile toPDFFile(File file) throws IOException { 113 RandomAccessFile raf = new RandomAccessFile(file, "r"); 114 FileChannel channel = raf.getChannel(); 115 ByteBuffer buf = channel.map(FileChannel.MapMode.READ_ONLY, 0, channel.size()); 116 return new PDFFile(buf); 117 118 } 119 120 private void deleteEL(File file) { 121 try{ 122 if(!file.delete())file.deleteOnExit(); 123 } 124 catch(Throwable t){} 125 } 126 127 private void copy(byte[] input, File file) throws IOException { 128 ByteArrayInputStream bais = new ByteArrayInputStream(input); 129 FileOutputStream fos = new FileOutputStream(file); 130 IOUtil.copy(bais, fos, true,true); 131 132 } 133 134 }