【问题标题】:Saving Each PDF Page to an Image Using Imagick使用 Imagick 将每个 PDF 页面保存到图像
【发布时间】:2025-11-24 11:55:02
【问题描述】:

我在下面有以下将本地 PDF 文件转换为图像的 php 函数。简而言之,我希望将每个 PDF 页面转换为单独的图像。

该函数将 PDF 转换为图像 - 但仅限于最后一页。我希望将 PDF 的 每一页 转换为图像并编号。不仅仅是 PDF 的最后一页。

目前,此函数将example.pdf最后页转换为example-0.jpg。我确定问题在于for 方法。我错过了什么?

$file_name = 'example.pdf'; // using just for this example, I pull $file_name from another function

function _create_preview_images($file_name) {

    // Strip document extension
    $file_name = basename($file_name, '.pdf');

    // Convert this document
    // Each page to single image
    $img = new imagick('uploads/'.$file_name.'.pdf');

    // Set background color and flatten
    // Prevents black background on objects with transparency
    $img->setImageBackgroundColor('white');
    $img = $img->flattenImages();

    // Set image resolution
    // Determine num of pages
    $img->setResolution(300,300);
    $num_pages = $img->getNumberImages();

    // Compress Image Quality
    $img->setImageCompressionQuality(100);

    // Convert PDF pages to images
    for($i = 0;$i < $num_pages; $i++) {         

        // Set iterator postion
        $img->setIteratorIndex($i);

        // Set image format
        $img->setImageFormat('jpeg');

        // Write Images to temp 'upload' folder     
        $img->writeImage('uploads/'.$file_name.'-'.$i.'.jpg');
    }

    $img->destroy();
}

【问题讨论】:

  • 我不知道是否发生了变化,但上次我生成 pdf 缩略图时是 $img = new imagick('file.pdf[0]'); 只获取第一页。
  • 是的...我知道这一点。但我不想要第一页、中间页或最后一页 - 我想要将所有页面转换为单个图像。
  • 我知道,我想说的是 PDF 不能像其他多图像格式那样工作,所以可能你必须获取页数并在循环中创建新的 imagick 实例,将[$i] 附加到文件名。
  • 你看过所有代码了吗……这正是我想要做的……
  • 此方法不适用于多页 PDF。 $img-&gt;flattenImages(); 将所有页面相互合并并将文件导出为单个图像,无论页面数量如何。有关具有黑色背景的多页 PDF 的解决方案,请参阅*.com/q/26793063/2028547

标签: php codeigniter pdf imagemagick imagick


【解决方案1】:

似乎大部分我的代码是正确的。问题是,我错误地使用了$img-&gt;flattenImages();。这merges 将一系列图像合并为一个图像。就像 Photoshop 在导出 jpg 时如何将所有可见图层拼合为图像一样。

我删除了上面的行,各个文件都按预期写入。

【讨论】:

  • 我没有遵循 $img = new imagick('uploads/'.$file_name.'.pdf'); - 你肯定传入文件名,并将其传递给构造函数吗?如果您的文件名没有路径,并且在上传目录中,我可以看到它可能有效。无论如何,如果它对其他人有帮助,我将这一行替换为 $img = new imagick(); $img->readImage($file_name); (在通过调用 basename 修剪扩展名的行之前)
【解决方案2】:
 /* convert pdf file to list  image files */
                if($_FILES['file_any']['type']=='application/pdf'){
                    $file_name = str_replace(substr($url,0,strpos($url,$_FILES['file_any']['name'])),'',$url);
                    $basename = substr($file_name,0,strpos($file_name,'.'));
                    $abcd = wp_upload_dir();
                    $delpath = $abcd['path'];
                    $savepath = $abcd['url'];
                    $dirpath = substr($savepath,(strpos($savepath,'/upl')+1));

                    $file_name = basename($file_name, '.pdf');
                    $img = new imagick($delpath.'/'.$file_name.'.pdf');

                    $img->setImageBackgroundColor('white');
                    $img->setResolution(300,300);
                    $num_pages = $img->getNumberImages();
                    $img->setImageCompressionQuality(100);
                    $imageurl = NULL;
                    $imagedelurl = NULL;
                    for($i = 0;$i < $num_pages; $i++) {         
                        $imageurl[]=$savepath.'/'.$basename.'-'.$i.'.jpg';
                        $imagedelurl[] = $delpath.'/'.$basename.'-'.$i.'.jpg';
                        // Set iterator postion
                        $img->setIteratorIndex($i);

                        // Set image format
                        $img->setImageFormat('jpeg');

                        // Write Images to temp 'upload' folder     
                        $img->writeImage($delpath.'/'.$file_name.'-'.$i.'.jpg');
                    }
                    $img->destroy();
                }

【讨论】:

    【解决方案3】:

    没有循环有一个更简单的方法,只需使用$img-&gt;writeImages($filename,false);,它就会为每个 PDF 页面创建一个文件。正如你所说,如果你先flatten图片,它只会节省一页。

    【讨论】:

      【解决方案4】:

      先安装

      图像魔术

      在您的系统或服务器中 然后创建

      pdf图片

      文件夹并将pdf文件放入此文件夹然后运行代码并上传文件

      <?php
          $file_name = $_FILES['pdfupload']['name']; // using just for this example, I pull $file_name from another function
          //echo strpos($file_name,'.pdf');
          $basename = substr($file_name,0,strpos($file_name,'.'));
          //echo $_FILES['pdfupload']['type'];
          //if (isset($_POST['submit'])){
          if($_FILES['pdfupload']['type']=='application/pdf'){
      
              // Strip document extension
              $file_name = basename($file_name, '.pdf');
              // Convert this document
              // Each page to single image
              $img = new imagick('pdfimage/'.$file_name.'.pdf');
      
              // Set background color and flatten
              // Prevents black background on objects with transparency
              $img->setImageBackgroundColor('white');
              //$img = $img->flattenImages();
      
              // Set image resolution
              // Determine num of pages
              $img->setResolution(300,300);
              $num_pages = $img->getNumberImages();
      
              // Compress Image Quality
              $img->setImageCompressionQuality(100);
              $images = NULL;
              // Convert PDF pages to images
              for($i = 0;$i < $num_pages; $i++) {         
                  $images[]=$basename.'-'.$i.'.jpg';
                  // Set iterator postion
                  $img->setIteratorIndex($i);
      
                  // Set image format
                  $img->setImageFormat('jpeg');
      
                  // Write Images to temp 'upload' folder     
                  $img->writeImage('pdfimage/'.$file_name.'-'.$i.'.jpg');
              }
              echo "<pre>";
              print_r($images);
              $img->destroy();
          }
          //}
      ?>
      

      【讨论】: