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.

2 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.

Leave a Reply

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