使用imagick使用PHP将PDF转换为JPG可以使用flat pdf,但是当有多个图层时会失败

时间:2015-06-22 05:07:44

标签: php pdf imagick

我有一个内部作业管理上传页面,用于pdf上传。该脚本将pdf的副本保存到一个目录,然后使用imagick生成用于在另一个页面上显示的jpg副本。使用该脚本上传的大多数PDF都可以完美地工作(虽然有点慢并且内存消耗很大但仍然按预期工作)。我们从事服务业务,很多上传都是pdf绘图集。从cad导出的图纸通常有一大堆图层,这些文件失败并带有以下信息:

  

致命错误:未捕获的异常' ImagickException'消息' Postscript代表失败了`../../Dropbox/Job_Docs/15-0273 La Bella,Cassandra / 15-0273 La Bella,Cassandra-layout 6-22-2015 55876fa96aa00.pdf':No这样的文件或目录@ pdf.c / ReadPDFImage / 611'在/home/solargai/public_html/dash3/upload.php:79堆栈追踪:#0 /home/solargai/public_html/dash3/upload.php(79):Imagick-> __ construct(' ../。 ./Dropbox/J...')在第79行的/home/solargai/public_html/dash3/upload.php中抛出#1 {main}

因此,如果我将其中一个问题pdf保存到我的桌面,然后通过pdf打印机(在这种情况下为cutepdf)重新保存,那么尝试再次上传它可以正常工作。所以这当然是为什么我假设它是层...因为当我使用pdf打印机时它们被剥离并变平。

起初我认为文档的大小是相关的,但后来我意识到我可以循环几乎100页而不会失败(绘图集通常大约15页左右)。

    <?php

set_time_limit(0);
ignore_user_abort(1);

session_start();



$uuid = uniqid();
$today = date("n-j-Y");

$jobname = $_POST['jobname'];
$_SESSION['jobname'] = $jobname;
$uploadType = $_POST['uploadType'];
$writeSTATE = $_POST['writeSTATE'];
$fileName = $jobname."-".$uploadType." ".$today." ".$uuid;

$fileNamePDF = $fileName.".pdf";
$path = "../dash2/jobinfoDOCS/".$jobname."/".$uploadType."/";
$DOCSpath = "../../Dropbox/Job_Docs/".$jobname."/";

//////remove directory
if($writeSTATE == "overwrite") {

        $filesD = glob($path . '*', GLOB_MARK);
        foreach ($filesD as $fileD) {
            if (substr($fileD, -1) == '/')
                delTree($fileD);
            else
                unlink($fileD);
        }
        rmdir($path);

}
if (!file_exists($path)) {
    mkdir($path, 0777, true);
    //echo "created folder for path: " . $path;
}
if (!file_exists($DOCSpath)) {
    mkdir($DOCSpath, 0777, true);
    //echo "created folder for path: " . $DOCSpath;
}



//echo "upload type: " . $_POST['uploadType'] . "<br>";
//echo "path: " . $path . "<br>";

//echo $_FILES['layout']['tmp_name'];
   if (is_uploaded_file($_FILES['layout']['tmp_name'])) {
      if ($_FILES['layout']['type'] != "application/pdf") {
         //echo "<p>Class notes must be uploaded in PDF format.</p>";
      } else {
         $name = $_POST['name'];
         $result = move_uploaded_file($_FILES['layout']['tmp_name'], $DOCSpath.$fileNamePDF);

///write pdf to jpg 

       //  if ($result == 1) echo "<p>File successfully uploaded.</p>";
         //else echo "<p>There was a problem uploading the file.</p>";
      } #endIF
   } #endif

$fi = new FilesystemIterator($path, FilesystemIterator::SKIP_DOTS);
//printf("There were %d Files", iterator_count($fi));
$fileCOUNT = iterator_count($fi);
//echo $fileCOUNT;

$PDFpath = $DOCSpath.$fileNamePDF;

$img = new imagick($PDFpath);
$img = $img->flattenImages();
$img->setResolution(175,175);
$number = $img->getnumberimages();
for($i=0;$i<$number;++$i)
{
$count = $i + $fileCOUNT;
    $JPGpath = $path.$count."--".$fileName.".jpg";
//echo $PDFpath."AND".$JPGpath;
$img->readImage("{$PDFpath}[".$i."]");
$img->writeImage("{$JPGpath}");
}
header("location:index.php");
?>

我尝试添加&#34; flattenImages&#34;在&#34;新的想象力&#34;那对任何事都没有帮助。我也尝试隔离函数并使用文件tmp为imagick函数创建。还有很多其他的东西我也尝试了,而且我现在整个周末一直在搞乱这个问题,我现在只是陷入困境所以任何帮助都会非常感激。

如果有助于说明导致问题的分层pdf的链接如下: https://www.dropbox.com/s/unauyb0rzpk0nup/drawing_with_layers.pdf?dl=0

然后这里是通过可爱的pdf编剧器成功上传的副本 https://www.dropbox.com/s/dv0bt7x222s93mi/no_layers.pdf?dl=0

2 个答案:

答案 0 :(得分:4)

Imagick调用ImageMagick库来完成它所有的图像处理。 Image Magick库本身不处理所有图像,它可以将它们的渲染委托给另一个库来处理它们。对于PDF文件,它通常委托给GhostScript库。

从命令行,如果运行convert -list configure,您应该能够在DELEGATES条目下查看ImageMagick正在使用的代理。

看起来你遇到了Ghostscript中的错误。尝试使用以下命令直接调用GS版本8.70来转换PDF:

  

gs -q -dQUIET -dSAFER -dBATCH -dNOPAUSE -dNOPROMPT   -dMaxBitmap = 500000000 -dAlignToPixels = 0 -dGridFitTT = 1 -sDEVICE = pngalpha -dTextAlphaBits = 4 -dGraphicsAlphaBits = 4 -r150 -sOutputFile = foo-%d.png drawing_with_layers.pdf

给出错误:

  

GPL Ghostscript 8.70:字体ArialNarrow-Bold的一些字形   需要获得专利的True Type口译员。 GPL Ghostscript 8.70:有些   字体ArialNarrow的字形需要获得专利的True Type   翻译。错误:/ failaccess在--run--操作数堆栈中:
  --dict:8/17(L) - F4 56.954 --dict:5/5(L) - --dict:5/5(L) - ArialMT --dict:11/12(ro)( G) - --ntringtringval - CIDFontObject
  --dict:6/6(L) - --dict:6/6(L) - 178279 --dict:6/6(L) - --nostringval-- PDFCIDFontName ArialMT执行堆栈:%interp_exit。 runexec2 --nntringval-- --nostringval--
  --nostringval-- 2%stopped_push --nostringval-- --nostringval-- --nostringval-- false 1%stopped_push 1862 1 3%oparray_pop 1861 1 3%oparray_pop 1845 1 3
  %oparray_pop --nostringval-- --nostringval-- 2 1 13
  --nostringval--%for_pos_int_continue --nostringval---nostringval---nostringval---nostringval--%array_continue --nostringval-- false 1%stopped_push --nostringval--%loop_continue --nostringval-- --nostringval-- --nostringval--
  --nostringval---nostringval---nostringval--%array_continue --nostringval---nostringval---nostringval---nostringval---nostringval-- Dictionary stack: - dict:1154 / 1684(ro)(G) - --dict:1/20(G) - - dict:75/200(L) - - dict:75/200(L) - - dict: 106/127(ro)(G) - --dict:286/300(ro)(G) - --dict:22/25(L) - - dict:4/6(L) - --dict:21/40(L) - --dict:1/1(ro)(G) - 当前分配模式是本地GPL Ghostscript 8.70:不可恢复的错误,   退出代码1

升级到GhostScript 9.16不会显示此问题,并且PDF已成功转换。

(顺便说一句,你的PDF没有背景图层,尽管有些文字被反锯齿为白色。)

答案 1 :(得分:0)

是的,你是对的。经过一周的撞击我的头后,终于让它工作了。我切换到他们的虚拟专用服务器产品。将默认包ghostscript 8.7升级到9.16。然后在尝试排除依赖关系大约10个小时之后,意识到如果我使用exec命令调用imagick,我可以直接引用更新的imagemagick / ghostscript安装。这就是诀窍....最后!再次谢谢你的帮助!

这就是我最终的工作:

$pdf = 'sample5.pdf';
$save = 'output5.jpg';
exec('/usr/local/ImageMagick-6.9.1-6/bin/convert "'.$pdf.'" -colorspace RGB -resize 800 "'.$save.'"', $output, $return_var);