'PDFThumbnails', 'version' => '1.5', 'author' => '[http://landofbile.com bile]', 'url' => 'http://landofbile.com/software/mediawiki-extensions/', 'description' => 'Generate thumbnails for PDFs just as SVGs'); $wgMediaHandlers['application/pdf'] = 'PdfHandler'; $wgPDFThumbType = array('jpg', 'image/jpg'); $wgPDFConverters = array('ImageMagick' => '$path/convert -background white -thumbnail $widthx$height\! $input[$page] JPG:$output'); $wgPDFConverter = 'ImageMagick'; $wgPDFConverterPath = ''; $wgPDFMaxSize = 2048; $wgPDFDPI = 300; class PdfHandler extends ImageHandler { function isEnabled() { global $wgPDFConverters, $wgPDFConverter; if ( !isset( $wgPDFConverters[$wgPDFConverter] ) ) { wfDebug( "\$wgPDFConverter is invalid, disabling PDF rendering.\n" ); return false; } else { return true; } } function mustRender() { return true; } function normaliseParams( $image, &$params ) { global $wgPDFMaxSize; if ( !parent::normaliseParams( $image, $params ) ) { return false; } # Don't make an image bigger than wgMaxPDFSize $params['physicalWidth'] = $params['width']; $params['physicalHeight'] = $params['height']; if ( $params['physicalWidth'] > $wgPDFMaxSize ) { $srcWidth = $image->getWidth( $params['page'] ); $srcHeight = $image->getHeight( $params['page'] ); $params['physicalWidth'] = $wgPDFMaxSize; $params['physicalHeight'] = File::scaleHeight( $srcWidth, $srcHeight, $wgPDFMaxSize ); } return true; } function doTransform($image, $dstPath, $dstUrl, $params, $flags = 0 ) { global $wgPDFConverters, $wgPDFConverter, $wgPDFConverterPath; if (!$this->normaliseParams($image, $params)) { return new TransformParameterError( $params ); } $clientWidth = $params['width']; $clientHeight = $params['height']; $physicalWidth = $params['physicalWidth']; $physicalHeight = $params['physicalHeight']; $srcPath = $image->getPath(); $page = $params['page'] - 1; if($page < 0) $page = 0; if ( $flags & self::TRANSFORM_LATER ) { return new ThumbnailImage($image, $dstUrl, $clientWidth, $clientHeight, $dstPath, $params['page']); } if ( !wfMkdirParents( dirname( $dstPath ) ) ) { return new MediaTransformError('thumbnail_error', $clientWidth, $clientHeight, wfMsg( 'thumbnail_dest_directory')); } $status = $this->rasterize($srcPath, $dstPath, $physicalWidth, $physicalHeight, $page); if( $status === true ) { return new ThumbnailImage($image, $dstUrl, $clientWidth, $clientHeight, $dstPath, $params['page']); } else { return $status; // MediaTransformError } } /* * Transform an PDF file to ... * This function can be called outside of thumbnail contexts * @param string $srcPath * @param string $dstPath * @param string $width * @param string $height * @returns TRUE/MediaTransformError */ public function rasterize($srcPath, $dstPath, $width, $height, $page) { global $wgPDFConverters, $wgPDFConverter, $wgPDFConverterPath; $err = false; if (isset($wgPDFConverters[$wgPDFConverter])) { $cmd = str_replace( array( '$path/', '$width', '$height', '$input', '$output', '$page'), array( $wgPDFConverterPath ? wfEscapeShellArg("$wgPDFConverterPath/") : "", intval($width), intval($height), wfEscapeShellArg($srcPath), wfEscapeShellArg($dstPath), intval($page)), $wgPDFConverters[$wgPDFConverter] ) . " 2>&1"; wfProfileIn( 'convert' ); wfDebug( __METHOD__.": $cmd\n" ); $err = wfShellExec( $cmd, $retval ); wfProfileOut( 'convert' ); } $removed = $this->removeBadFile( $dstPath, $retval ); if ( $retval != 0 || $removed ) { wfDebugLog( 'thumbnail', sprintf( 'thumbnail failed on %s: error %d "%s" from "%s"', wfHostname(), $retval, trim($err), $cmd ) ); return new MediaTransformError( 'thumbnail_error', $width, $height, $err ); } return true; } function getImageSize($file, $path) { global $wgPDFDPI; if(method_exists($file, 'getMetadata')) { $metadata = $file->getMetadata(); } else { $metadata = $this->getMetadata($file,$path); } $metadata = json_decode($metadata); $width = $metadata->width / 72 * $wgPDFDPI; $height = $metadata->height / 72 * $wgPDFDPI; return array($width,$height,'PDF',"width=${width}","height=${height}"); } function getThumbType( $ext, $mime ) { global $wgPDFThumbType; return $wgPDFThumbType; } function getLongDesc($file) { $metadata = json_decode($file->getMetadata()); global $wgLang; return sprintf('(%.1fin x %.1fin, pages: %d, color: %s, file size: %s)', $metadata->width / 72, $metadata->height / 72, $metadata->pages, $metadata->color, $wgLang->formatSize($file->getSize())); } function isMetadataValid($file,$metadata) { if(isset($metadata) && !empty($metadata)) return true; return false; } function getParamMap() { return array( 'img_width' => 'width', 'img_page' => 'page', ); } function makeParamString( $params ) { $page = isset( $params['page'] ) ? $params['page'] : 1; if ( !isset( $params['width'] ) ) { return false; } return "page{$page}-{$params['width']}px"; } function parseParamString( $str ) { $m = false; if ( preg_match( '/^page(\d+)-(\d+)px$/', $str, $m ) ) { return array( 'width' => $m[2], 'page' => $m[1] ); } else { return false; } } function getScriptParams( $params ) { return array( 'width' => $params['width'], 'page' => $params['page'], ); } function isMultiPage($file) { return true; if($this->pageCount($file) > 1) return true; return false; } function pageCount($file) { $metadata = json_decode($file->getMetadata()); return $metadata->pages; } function getMetadata($image, $path) { $metadata = array(); $cmd = sprintf('pdf2dsc %s /dev/stdout', $path); $output = wfShellExec($cmd, $retval); preg_match('/%%DocumentMedia: (\S*) (\S*) (\S*) (\S*) (\S*) (\S*)/', $output, $matches); $metadata['medianame'] = $matches[1]; $metadata['width'] = $matches[2]; $metadata['height'] = $matches[3]; $metadata['weight'] = $matches[4]; $metadata['color'] = $matches[5]; $metadata['type'] = $matches[6]; preg_match('/%%Pages: (\S*)/',$output,$matches); $metadata['pages'] = $matches[1]; return json_encode($metadata); } function getMetadataType($file) { return 'json'; } function getPageDimensions($file, $page) { global $wgPDFDPI; $md = json_decode($file->getMetadata()); return array('width' => intval($md->width / 72 * $wgPDFDPI), 'height' => intval($md->height / 72 * $wgPDFDPI)); } }