Page 1 of 1

Conversion from PDF to PNG under Imagick

Posted: 2011-05-03T17:16:53-07:00
by Chuchk
On my server I have the latest versions of GhostScript Image Magick and the Imagick extension installed. On the command line I can convert PDFs to PNGs(or any other image file) without a problem.

However when I tried to achieve this through the Imagick plugin I get no such luck. in fact when I try to do the imageWrite function from an Imagick object execution of the PHP script just stops and the truncated document is served, other conversions work fine.

Any ideas on how to fix this?

Re: Conversion from PDF to PNG under Imagick

Posted: 2011-05-03T19:51:04-07:00
by DJ Mike
By coincidence a WebTV user asked me about making an online PDF converter using Imagick just the other day. The full discussion is here: http://eclecticdjs.com/forum/viewtopic.php?f=15&t=897

What I came up with doesn't use imageWrite(). Instead it uses

header('Content-Type: image/png');

and echo's the image. The script comes in two parts. A form to input the URL of the pdf and generate a drop menu & "Previous" & "Next" links for navigation.

Code: Select all

<?php
# version 24
$self = $_SERVER[PHP_SELF];
$url = $_GET[url];
$page = $_GET[page];
$previous = $page-1;
$next = $page+1;
?>
<html>
<head>
<style type="text/css">
body { background-color:#fad888; }
h1 { text-align:center; color:blue}
</style>
</head>
<body bgcolor="fad888">
<form action="<?php echo "$self"; ?>">
<h1>DJ Mike's Online PDF to PNG Converter</h1>
<center>
URL: <input type="text" name="url" value="<?php echo $_GET[url]; ?>">
<input type="submit"><br>
<?php
 ############### if only URL submitted
if($url )
 {
 $blob = file_get_contents("$url");
 $image = new imagick();
 $image->readImageBlob("$blob");
 $pages = $image->getNumberImages();
 echo "$pages pages<br>";

 # drop menu to select page
 echo "Select Page: <select name=\"page\">\n";
  for ( $x=1; $x<$pages+1; $x++)
   {
    # make option selected if it matches selected page 
    if ( $page == $x ) { $selected = " selected";}
    echo "<option value=\"$x\"$selected>$x</option>\n";
    # reset $selected for next option
    $selected = "";
   }
 echo "</select>\n";
  }
echo "<br>";
    ######################### if page specified
if ( $url && $_GET[page] )
  {
  if ($previous>1) 
   {
    # link to previous page
    echo "<a href=$self?url=$url&page=$previous><</a>&nbsp;";
   }
  echo " Page $page "; # this page number
  if ($next<$pages+1) 
   {
    # link to next page
    echo "&nbsp;<a href=$self?url=$url&page=$next>></a>";
   }
echo "</center>";

# display selected page
echo "<center><a href=\"viewer_001.php?url=$url&page=$page\"><img src=\"viewer_001.php?url=$url&page=$page\"></a></center>\n";
  }
###################
/* If URL specified and page not specified show thumbs of
first 5 pages or if less than 5 pages show thumbs of all */
elseif ($url)
 {
 $show = min($pages, 5);
 echo "<center>";
 for ($x=1; $x<$show+1; $x++ )
  { echo "<a href=\"viewer_001.php?url=$url&page=$x\">\n<img src=\"viewer_001.php?url=$url&page=$x&t=yes\"></a>"; }
 echo "</center>\n";
 }
?>
</form>
</body>
</html>
Part 2 reads the PDF, selects the page from the form's input and displays either the full image or a thumbnail. This is the part that should interest you.

Code: Select all

<?php
# viewer
$url = $_GET[url];
$page = $_GET[page];

# if no URL then send nothing to browser
if ( !$url  ) { exit; }

############### if URL and page submitted
if ( $url && $page )
 {
 header('Content-Type: image/png');
 $blob = file_get_contents("$url");
 $image = new imagick();
 $image->readImageBlob("$blob");
 $image->setFormat("png");
 $x = 1;
 foreach ( $image as $frame ) # loop through pages 
  {
   if ( $x == $page ) # if current page = page requested
    {
     if ( $_GET[t] == "yes") # if thumbnail
       {
        $image->thumbnailImage(100, 0);
        echo $image;
        exit;
       }
     echo $frame;
     exit;
    }
   $x++; 
  }
 exit;
 } 
?>
Notice that $image in an image sequence, not a single image. You have to loop through the sequence and pull out the page you want or in your case, use imageWrite() to write each image. I'm guessing that by "truncated document" you mean that you got just the first page.

Re: Conversion from PDF to PNG under Imagick

Posted: 2011-05-03T20:23:00-07:00
by fmw42
Chuchk wrote:On my server I have the latest versions of GhostScript Image Magick and the Imagick extension installed. On the command line I can convert PDFs to PNGs(or any other image file) without a problem.

However when I tried to achieve this through the Imagick plugin I get no such luck. in fact when I try to do the imageWrite function from an Imagick object execution of the PHP script just stops and the truncated document is served, other conversions work fine.

Any ideas on how to fix this?

Perhaps PHP does not know where Ghostscript is located.

Re: Conversion from PDF to PNG under Imagick

Posted: 2011-05-04T03:53:10-07:00
by Chuchk
DJ Mike wrote:
Notice that $image in an image sequence, not a single image. You have to loop through the sequence and pull out the page you want or in your case, use imageWrite() to write each image. I'm guessing that by "truncated document" you mean that you got just the first page.
I tried to run your script on my server, it didn't work but maybe I set it up wrong, I saved the first block of code as index.php and put it in a folder and then the second block as viewer_001.php.

also do you think my problem is that I didn't step through the pages of the PDF(even though they are all one page documents)?

fmw42 wrote:Perhaps PHP does not know where Ghostscript is located.
This has been my theory though I have no idea how to fix it

Re: Conversion from PDF to PNG under Imagick

Posted: 2011-05-04T10:43:43-07:00
by Bonzo
I have no idea how to get php to recognise ghostscript and have always been lucky as it has always just worked.

Is it an Imagick or Imagemagick problem - can you convert a pdf using exec() ?

Code: Select all

<?php
$array=array();
echo "<pre>";
exec("convert input.pdf output.png 2>&1", $array); 
echo "<br>".print_r($array)."<br>"; 
echo "</pre>";
?>

Re: Conversion from PDF to PNG under Imagick

Posted: 2011-05-04T23:08:46-07:00
by DJ Mike
I tried to run your script on my server, it didn't work but maybe I set it up wrong, I saved the first block of code as index.php and put it in a folder and then the second block as viewer_001.php.
The other guy who tested it had a problem with it the first time. The next day it did. We never figured out why. I had a problem but it was caused by my using a 3 Meg pdf over and over while working out the navigation. My administrator said I filled up Imagick's temp memory and it was having problems deleting the temp files. I'm still trying to think of a way to avoid that before I make it public.
also do you think my problem is that I didn't step through the pages of the PDF(even though they are all one page documents)?
No, if they were only one page you should have had no problem. Also, after some thought I realized that since you are writing the files you wouldn't need to step through the pages like I did even if they were muli-page. What you would do is use Imagick::writeImages instead of Imagick::writeImage.

Imagick::writeImages
http://www.php.net/manual/en/function.i ... images.php

When I used that to make animations and I made the second argument FALSE Imagick::writeImages wrote each frame as a separate file.

Code: Select all

$im->writeImages("out.png", FALSE); 

Re: Conversion from PDF to PNG under Imagick

Posted: 2011-05-04T23:24:26-07:00
by DJ Mike
I have not used exec() to use Imagemagick. In to line from Bonzo's code:

exec("convert input.pdf output.png 2>&1", $array);

what does 2>&1 do?

Re: Conversion from PDF to PNG under Imagick

Posted: 2011-05-05T07:47:04-07:00
by Bonzo
According to the internet:
it means 2(stderr) is redirected to &1. & tells the address (fd) of 1(stdout).
It is to do with my error reporting; from memory the array is not populated without it.

Re: Conversion from PDF to PNG under Imagick

Posted: 2011-05-05T10:40:07-07:00
by Bonzo
I have just tried the error reporting and without the 2>&1 the array is not populated.

Re: Conversion from PDF to PNG under Imagick

Posted: 2011-05-07T08:25:17-07:00
by byron
What do you get when you try this? This is what I started out with in DJ Mike's forum.

Code: Select all

<?php
$url = "../imagick/fw4.pdf";

$extract = pathinfo($url);
$new_name = ($extract['filename']);

$image = new imagick($url);
$x=0;
foreach( $image as $temp )
{
$frame_name = "$new_name.frame_$x.png";
$image->setFormat("png");
$image->writeImage("$frame_name"); 
echo "<a href=\"$frame_name\"><img src=\"$frame_name\"></a>"; 
$x++;
}
?>