如何使用Imagick、ImageMagick和PHP从PDF创建特定数量的缩略图?

如何使用Imagick、ImageMagick和PHP从PDF创建特定数量的缩略图?,php,pdf,image-processing,imagemagick,imagick,Php,Pdf,Image Processing,Imagemagick,Imagick,我想使用PHP、ImageMagick和Imagick(PHP类)创建PDF的缩略图。有些PDF只有一页,有些PDF有很多页。我想指定要创建的缩略图的数量(N),在PDF的前N个页面中每个页面一个 下面的代码可以工作,但当PDF没有足够的页面时会产生错误(因为我试图在不存在的PDF页面上实例化Imagick)。我还知道,当从命令行使用ImageMagick时,它可以为PDF中的所有页面创建缩略图。我想以最有效的方式(内存和处理器)模拟这种行为,同时控制创建的拇指数量。。。我只需要一个大PDF的前

我想使用PHP、ImageMagick和Imagick(PHP类)创建PDF的缩略图。有些PDF只有一页,有些PDF有很多页。我想指定要创建的缩略图的数量(N),在PDF的前N个页面中每个页面一个

下面的代码可以工作,但当PDF没有足够的页面时会产生错误(因为我试图在不存在的PDF页面上实例化Imagick)。我还知道,当从命令行使用ImageMagick时,它可以为PDF中的所有页面创建缩略图。我想以最有效的方式(内存和处理器)模拟这种行为,同时控制创建的拇指数量。。。我只需要一个大PDF的前N页缩略图

我研究了各种确定PDF中页面数量的方法,它们似乎都是资源密集型的。也许下面的代码是我最好的选择。它实现了我的目标,但却让我烦恼,因为它会导致一些错误。。。即使它们不会影响最终结果

以下是我目前有效的代码(当PDF少于N页时会出现错误):

private函数创建缩略图(
$num_thumbs=3//要创建多少个缩略图,默认为一个
) {
回显“\n\n正在创建缩略图…”;
$num_thumbs_created=0;
而($num_thumbs_created<$num_thumbs)
{
试一试{
//用pdf实例化imagick
$Image=new Imagick($this->file_path_pdf.['.$num_thumbs_created.]');
//定义图像文件
$Image->setImageColorspace(255);
$Image->setCompression(Imagick::COMPRESSION\u JPEG);
$Image->setCompressionQuality(60);
$Image->setImageFormat('jpg');
//调整缩略图的大小
//-相对于8.5x11调整大小(假设大多数PDF为纸张大小)
$Image->resizeImage(180232,imagick::FILTER_POINT,1);
//保存图像
$Image->writeImage(substr($this->File->path,0,-4)。'-'.$num\u thumbs\u created..jpg');
$Image->clear();
$num_thumbs_created++;
}捕获(例外$e){
echo“\n*无法创建部分或全部缩略图:”..e->getMessage();
打破
}
}   
$Image->destroy();
回应“完成”;
}

我很确定如果你打开PDF,那么
Imagick::getNumberImages
会告诉你页数。同样,在这一点上,您可以使用magick对它们进行迭代,而无需每页实例化。所有这些都是基于文档的推测。因此,您必须亲自测试并找出:

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";
}
private函数创建缩略图($num\u thumbs=3){
回显“\n\n正在创建缩略图…”;
试一试{
$Image=new Imagick($this->file\u path\u pdf);
$nbCreated=0;
如果($num_thumbs>0){
foreach($idx=>$im的图像){
如果($nbCreated<$num_thumbs){
$im->setImageColorspace(255);
$im->setCompression(Imagick::COMPRESSION\u JPEG);
$im->设置压缩质量(60);
$im->setImageFormat('jpg');
$im->resizeImage(180232,imagick::FILTER_POINT,1);
//保存图像
$im->writeImage($idx.'-'.$nbCreated..jpg');
$im->clear();
$nbCreated++;
}
其他的
{
break;//跳出循环我们已经达到极限,完成了
}
}
}
$Image->destroy();
}
捕获(例外$e){
echo“\n*无法创建部分或全部缩略图:”..e->getMessage();
$Image->destroy();
}   
回应“完成”;
}

注意,我还更改了您的尝试/捕获位置。在我看来,如果出现错误,最好同时停止创建映像,因为如果处理单个文件,每次迭代都可能抛出错误,因此在第一个异常时停止可能更有效。您可以轻松地将其包装到不同的位置,这正是我的做法。

您查看过poppler库吗?您必须运行pdfinfo命令,从输出字符串中提取页数,然后让它。。。有点迂回,但它会起作用。@MAtthew:但在这一点上,他可以从cli执行imagemagick并执行它。@prodigitalson imagemagick identify命令比poppler的pdfinfo慢得多。我同意这并不是很清晰和直截了当,但有时发出cli命令并在以后进行重构更容易。@Matthew:没错,但除非他在部署目标上获得根,否则他将无法安装非标准库。然而,ImageMagick通常安装在共享/云主机上。我在服务器上拥有根权限。我宁愿避免cli实现,如果可能的话,还必须安装另一个库。谢谢,作为一个警告,我没有对这段代码运行任何性能测试。其中一些肯定是资源密集型的,但大多数图像转换过程都是这样。我不确定它的任何其他方面是否会导致问题。我认为没有任何理由调用
getNumberImages()
,因为我们已经将缩略图的数量限制为在foreach循环中迭代Imagick对象时PDF中的页数。@t.BrianJones:是的。。。关于getNumberImages呼叫,你是对的。。。这是毫无意义的,因为我们正在做一个有限制的foreach。就性能而言。。。我认为,使用您遇到问题的实现的唯一区别在于,每次内存中可能只有一个页面,但同时您必须打开每个页面,然后销毁该页面
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";
}