Web Trenches

Alternative for CFPDF thumbnails in Lucee



Creating PDF thumbnails with Lucee has been broken since version 5, and possibly longer.

https://dev.lucee.org/t/cfpdf-action-thumbnail-not-working-on-lucee-5/1389
https://luceeserver.atlassian.net/browse/LDEV-967

Here is a function that should help you if you really need to get it working.

<cfscript>
	// Creates a jpg thumbnail from a PDF file
    // thumbnailFromPDF()
    // returns the file name of the JPG that it creates.
    // arguments
    // - pdfFile (required), This is the physical file path to the PDF
    // - destination (optional), Location to save the thumbbail, defaults to same location as original.
    // - width (optional), width of the resulting image, defaults to 200px
    // - page (optional), page number to use for the thumbnail, defaults to page 1.
	function thumbnailFromPDF(required string pdfFile,string destination = '',string width = '200', string page = 1) {
		// Java libraries needed
		var BufferedImage = createObject("java","java.awt.image.BufferedImage");
		var ImageWriter = createObject("java","org.apache.pdfbox.util.PDFImageWriter");	
		
		// load the pdf into PDFBox
		var document = createObject("java","org.apache.pdfbox.pdmodel.PDDocument").load("#arguments.pdffile#");	

		// get the base paths file names needed
		var basefile = listlast(arguments.pdffile,server.separator.file);
		var basefilename = replacenocase(basefile,".pdf","","ALL");
		var basepath = replacenocase(arguments.pdfFile,basefile,"");
		if (arguments.destination IS '') {
			arguments.destination = basepath;
		} 
		if (right(arguments.destination,1) Neq server.separator.file) {
			arguments.destination = arguments.destination & server.separator.file;
		}
		var returnfileprefix = "#arguments.destination##basefilename#_"; //includes dest path
		var returnfilename = "#basefilename#_#arguments.page#.jpg";

		//check file extension
		if (right(arguments.pdfFile,4) Neq ".pdf") {
			cfthrow(message="File does not appear to be a PDF file.");
		}

		//write the image of page 1. This writes a file called 1.jpg. There is prefix argument and in this case we use the file name as the prefix.
		// arguments... writeImage(document,image type,start page, end page, prefix to <page number>.jpg, java color profile, resolution)
		imageWriter.writeImage(document, JavaCast("string","jpg"), JavaCast("string",""), arguments.page, arguments.page, JavaCast("string",returnfileprefix), BufferedImage.TYPE_INT_RGB, 200);
		// close document object, no longer needed
		document.close();

		// resize the image
		cfimage(action="resize",source="#arguments.destination##returnfilename#",destination="#arguments.destination##returnfilename#",overwrite="true",width=arguments.width);

		return returnfilename;
	};
</cfscript>

Example of how to use this…

<cfscript>
pdfFile = "c:\path\to\my\file\name.pdf";
// make a thumbnail of page 1 in the images folder, with a width of 50
thumbnail = thumbnailFromPDF(pdffile,expandpath('/images'),50,1);
</cfscript>
<cfoutput><img src="/images/#thumbnail#" /></cfoutput>

Hopefully the Lucee team will fix cfpdf and this won’t be necessary in the future.

6 Replies to “Alternative for CFPDF thumbnails in Lucee”

  1. Great stuff. Just a few suggestions.

    1) Add PDDocument.close(); and document.close(); after imageWriter.writeImage. (You can workaround the first one by skipping var PDDocument… and using var document = createObject(“java”,”org.apache.pdfbox.pdmodel.PDDocument”).load(“#arguments.pdffile#”); instead.)
    2) Use server.separator.file instead of “\” so that it works on Windows and Unix-based systems.

  2. This is a great start, thank you for putting this together. Unfortunately, it does not seem to work when there are embedded fonts in the PDF. The text will be missing when rendering the image.

    I was looking for a workaround by possibly using `org.apache.pdfbox.rendering.PDFRenderer`, but it does not seem to be included anymore.

  3. When I wrote this, it was intended to be a stopgap while Lucee fixed the issue. It is a limited solution, and you are correct that it will not work with embedded fonts. Unfortunately, almost five years later the Lucee bug is not resolved.

Leave a Reply

Your email address will not be published. Required fields are marked *