PDF to JPG problem

OS: Windows Server 2012
Java Version: 11.0.6
Tomcat Version: Apache Tomcat/9.0.31
Lucee Version: Lucee 5.3.8.3-SNAPSHOT

Hey,

I’m currently trying to make a thumbnail of a PDF file. I noticed that the cfpdf tag doesn’t work well, and thus did not generate a image file. Now I’m using code I found here: link but I’m getting an error:

No matching Method for writeImage(org.apache.pdfbox.pdmodel.PDDocument, string, string, numeric, numeric, string, numeric, numeric) found for org.apache.pdfbox.util.PDFImageWriter

this is strange because when I writedump the function itself I get:

boolean writeImage(org.apache.pdfbox.pdmodel.PDDocument, java.lang.String, java.lang.String, int, int, java.lang.String, int, int)

I’m calling it like this:

imageWriter.writeImage(document, JavaCast(“string”,“jpg”), JavaCast(“string”,""), arguments.page, arguments.page, JavaCast(“string”,returnfileprefix), BufferedImage.TYPE_INT_RGB, 200);

or without the last two arguments. Am I doing something wrong? I have the feeling the parameters are not correct but I tried a lot of things and still the same error. Some help would be appreciated!

Thanks!

I’m not sure what the issue is but it could be to do with the version of PDF Box you’re using, which I assume is the one Lucee loads? i.e. you’re not loading it separately?

For my own thumbnail workaround I’m using pdfbox-app-2.0.19 and the PDFRenderer class. This isn’t exactly how I’m doing it, but should give you an idea:

pdfBoxJarPath = ExpandPath( "/library/pdfBox/2_0/pdfbox-app-2.0.19.jar" );
// create a test pdf (or supply an existing path)
pdfPath = ExpandPath( "thumbtest.pdf" );
document overwrite="true" format="pdf" filename=pdfPath{ WriteOutput( "Bonjour Monde" ) };
try{
	pdfFile = CreateObject( "java", "java.io.FileInputStream" ).init( JavaCast( "string", pdfPath ) );
	reader = CreateObject( "java", "org.apache.pdfbox.pdmodel.PDDocument", pdfBoxJarPath );
	pdf = reader.load( pdfFile );
	pageNumber = 0; //use the first page
	renderer = CreateObject( "java", "org.apache.pdfbox.rendering.PDFRenderer", pdfBoxJarPath ).init( pdf );
	imageType = CreateObject( "java", "org.apache.pdfbox.rendering.ImageType", pdfBoxJarPath )[ "RGB" ];
	dpi = 72;
	bufferedImage = renderer.renderImageWithDPI( JavaCast( "int", pageNumber ), JavaCast( "float", dpi ), imageType );
	// create, resize and write out a CFML image object
	image = ImageNew( bufferedImage );
	ImageScaleToFit( image, 100, "", "highestQuality" );
	ImageWrite( image, ExpandPath( "thumb.jpg" ) );
}
finally{
	pdfFile.close();
	pdf.close();
}

If you are using PDFBox 2.x.x, that example code will no longer work as the PDFImageWriter class was removed with that release. This is noted here: https://pdfbox.apache.org/2.0/migration.html under the PDF Rendering section.

1 Like

Thanks, Tony. I knew there must have been a reason why I switched to PDFRenderer :slightly_smiling_face:

1 Like

Thanks for providing an example as I did not have one handy other than saying it won’t work :sweat_smile:

This creates a png image from a pdf…

<cffunction name="PDFpageToImage" output="false">
    
  <cfargument name="filebytes" required="true">
  <cfargument name="pageNo" default="0">
  <cfargument name="dpi" default="72">
  
  <cfscript>
    /* creates a 72dpi base64 png image of pdf page input as bytes (could also pass in filename)
	   for byteArray return, do return after baos.close() and doc.close()
	   'org.apache.pdfbox.app' is in bundles directory :)
	*/
    var PDDocument = CreateObject("java", "org.apache.pdfbox.pdmodel.PDDocument", "org.apache.pdfbox.app", "2.0.18");
    var PDFRenderer = CreateObject("java", "org.apache.pdfbox.rendering.PDFRenderer", "org.apache.pdfbox.app", "2.0.18");
	var ImageIO = CreateObject("java", "javax.imageio.ImageIO");
	
	
	var doc = PDDocument.init().load(arguments.filebytes);
    //var doc = PDDocument.init().load(arguments.filename);
       
	var renderer = PDFRenderer.init(doc);
	
	var image = renderer.renderImageWithDPI(arguments.pageNo, arguments.dpi);
		
	var baos = createObject("java","java.io.ByteArrayOutputStream").init();
	
	ImageIO.write(image, "PNG", baos);
	
	baos.flush();
	
	var imageInBytes = baos.toByteArray();
	
	baos.close();
	
	doc.close();
		
	var Base64 = CreateObject("java", "java.util.Base64");
		
	var b64 = Base64.getEncoder().encodeToString(imageInBytes);
			
	return b64;
	
	//output: 'res' is the returned base64 (b64)
	//dataurl = "data:image/png;base64,#res#"; see pagetoimage.cfm
	
  </cfscript>
  
</cffunction>

Thanks guys, yes we have multiple PDF jar files so that’s probably it. Thanks for the code examples for clearing it up!

That’s why the bundles directory is awesome! You can have multiple versions of a jar file and they are all separate. (I mention this in case anyone has not tried the bundles directory).