How can I create a specific number of thumbnails from a PDF using Imagick, ImageMagick, and PHP?

落爺英雄遲暮 提交于 2020-01-03 04:51:06

问题


I'd like to use PHP, ImageMagick, and Imagick ( PHP Class ) to create thumbnails of a PDF. Some PDFs will only have one page, and some will have many. I'd like to specify a number ( N ) of thumbnails to create, one for each of the first N pages in the PDF.

The code below works, but produces errors when the PDF doesn't have enough pages ( because I'm trying to instantiate Imagick on a PDF page that doesn't exist ). I also know that ImageMagick can create thumbnails for all the pages in a PDF when used from the command line. I'd like to mimic that behavior in the most efficient way ( memory and processor ), while controlling the number of thumbs created ... I only need a thumbnail for the first N pages in large PDFs.

I've looked at various methods to determine the number of pages in a PDF, and they all seem to be resource intensive. Perhaps the code below is my best bet. It accomplishes my goal, but bothers me because it results in some errors ... even though they don't affect the ultimate outcome.

Here is my code that currently works ( with errors when the PDF has fewer than N pages ):

private function create_thumbnails(
    $num_thumbs = 3     // how many thumbnails to create, defaults to one
) {

    echo "\n\n    creating thumbnails ... ";

    $num_thumbs_created = 0;
    while( $num_thumbs_created < $num_thumbs )
    {

        try {

            // instantiate imagick with the pdf
            $Image = new Imagick( $this->file_path_pdf . '[' . $num_thumbs_created . ']' );

            // define image file
            $Image->setImageColorspace( 255 );
            $Image->setCompression( Imagick::COMPRESSION_JPEG );
            $Image->setCompressionQuality( 60 );
            $Image->setImageFormat( 'jpg' );

            // size the thumbnail
            //  - resized relative to 8.5x11 ( assuming most pdfs are paper sized )
            $Image->resizeImage( 180, 232, imagick::FILTER_POINT, 1 );

            // save image
            $Image->writeImage( substr( $this->File->path, 0, -4 ) . '-' . $num_thumbs_created . '.jpg' );
            $Image->clear();

            $num_thumbs_created++;

        } catch( Exception $e ) {

            echo "\n  * failed to create some or all thumbnails: " . $e->getMessage();
            break;

        }

    }   

    $Image->destroy();

    echo "done";

}

回答1:


Im pretty sure if you open a PDF then Imagick::getNumberImages will give you the number of pages. Likewise at that point you can iterate over them with magick without have to instantiate per page. All this is speculation based on the documentation though. So youll have to test and find out for yourself:

private function create_thumbnails( $num_thumbs = 3) {

    echo "\n\n    creating thumbnails ... ";

    try {
        $Image = new Imagick( $this->file_path_pdf);
        $nbCreated = 0;
        if($num_thumbs > 0) {
           foreach($Image as $idx => $im) {
              if($nbCreated < $num_thumbs) {
                $im->setImageColorspace( 255 );
                $im->setCompression( Imagick::COMPRESSION_JPEG );
                $im->setCompressionQuality( 60 );
                $im->setImageFormat( 'jpg' );

                $im->resizeImage( 180, 232, imagick::FILTER_POINT, 1 );

                // save image
                $im->writeImage( $idx . '-' . $nbCreated . '.jpg' );
                $im->clear();

                $nbCreated++;
              }
              else 
              {
                 break; // pop out of loop we have reach our limit and are done
              }
           }

        }

        $Image->destroy();
    }
    catch( Exception $e ) {
       echo "\n  * failed to create some or all thumbnails: " . $e->getMessage();
       $Image->destroy();    
    }   

    echo "done";
}

Note i also changed where you have your try/catch. IMO its better to bail and stop creating images all together if there is an error because if youre dealing with a single file chances are the error will be thrown on each iteration, so its probably more efficient to stop on the first exception. You could easily wrap it in a different location, thats just how i would do it.



来源:https://stackoverflow.com/questions/13261189/how-can-i-create-a-specific-number-of-thumbnails-from-a-pdf-using-imagick-image

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!