Convert PDF to JPG with PHP using imagick works with flat pdf but fails when multiple layers are present

I have an internal job management download page for downloading PDFs. The script saves a copy of the pdf file to one directory and then a copy of the jpg is created using imagick, which is used to display on another page. Most PDFs loaded with the script work fine (albeit a bit slow and the memory consumed ... but still works as intended). We work in the service industry and many of the downloads are drawing sets. Drawings exported from cad usually have a whole bunch of layers and these documents fail with the following message:

Fatal error: Throw "ImagickException" with message "Postscript delegate failed" .. /../Dropbox/Job_Docs/15-0273 La Bella, Cassandra / 15-0273 La Bella, Cassandra-layout 6-22-2015 55876fa96aa00. pdf ': No such file or directory @ pdf.c / ReadPDFImage / 611' in / home / solargai / public _html / dash3 / upload.php: 79 Stack trace: # 0 / home / solargai / public_html / dash3 / upload. php (79): Imagick -> __ construct ('../../ Dropbox / J ...') # 1 {main} thrown into / home / solargai / public _html / dash3 / upload.php on line 79

So, if I save one of these pdf issues to my desktop and then save it again via a pdf printer (cutec in this case), try downloading it again, it works great. So of course I am assuming they are layers ... because they are removed and flattened when I use a PDF printer.

At first I thought the document size was related, but then I realized that I could go through almost 100 pages without crashing (a set of drawings is usually 15 pages or so).

    <?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");
?>

      

I tried adding "flattenImages" underneath "new imagination" and it didn't help anything. I also tried to isolate the function and use tmp files to create the imagick function. There were a bunch of other things I tried too, and I have been messing around with all the weekends at the moment and I just got stuck so any help would be greatly appreciated.

If it helps illustrate the link for the layered pdf causing the problems is below: https://www.dropbox.com/s/unauyb0rzpk0nup/drawing_with_layers.pdf?dl=0

then here is a copy that downloads successfully which was launched by the cute PDF author https://www.dropbox.com/s/dv0bt7x222s93mi/no_layers.pdf?dl=0

+3


source to share


2 answers


Imagick calls the ImageMagick library to do all of the image processing. The Image Magick library does not handle all images itself, it can delegate rendering to another library to handle them. For PDF files, it usually passes the GhostScript library.

On the command line, if you run configure-list configure, you can see which delegates are being used by ImageMagick in the DELEGATES element.

It looks like you are facing an error in Ghostscript. Trying to convert PDF by calling GS version 8.70 directly with the command:

gs -q -dQUIET -dSAFER -dBATCH -dNOPAUSE -dNOPROMPT -dMaxBitmap = 500000000 -dAlignToPixels = 0 -dGridFitTT = 1 -sDEVICE = pngalpha -dTextAlphaBits = 4 -dGraphitsOnline-drawing. pdf



gives error:

GPL Ghostscript 8.70: Certain glyphs in the ArialNarrow-Bold font require a proprietary True Type interpreter. GPL Ghostscript 8.70: Certain ArialNarrow Font Glyphs require a patented True Type translator. Error: / invalidaccess in --run - Stack operand:
--dict: 8/17 (L) - F4 56.954 - dict: 5/5 (L) - --dict: 5/5 (L) - ArialMT - dict: 11/12 (ro) (G) - --nostringval-- CIDFontObject
--dict: 6/6 (L) - --dict: 6/6 (L) - 178279 --dict: 6/6 (L ) - --nostringval-- PDFCIDFontName ArialMT Stacking stack:% interp_exit. runexec2 --nostringval-- --nostringval

--nostringval-- 2% stop_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% stop_push --nostringval -% loop_continue --nostringval-- --nostringval-- --nostringval

--nostringval-- -nostringval-- -nostringval -% array_continue --nostringval-- -nostringval-- -nostringval-- -nostringval-- -nostringval-- Dictionary glass: -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) - Current allocation mode is GPL local Ghostscript 8.70: Fatal error exit code 1

Upgrading to GhostScript 9.16 does not show this issue and the PDF converts successfully.

(By the way, your PDF doesn't have a background layer, even though some of the text is anti-aliased to white).

+4


source


Yes, you were right. Finally, he started working a week later, banging his head against a wall. I switched to their virtual server. Updated the default ghostscript package from 8.7 to 9.16. Then, after about 10 hours trying to figure out the dependencies, I realized that if I call imagick using the exec command, I can link directly to the updated imagemagick / ghostscript installation. That did the trick .... FINALLY! Thanks again for your help!

Here's what I finally got:



$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);

      

0


source







All Articles