Page 1 of 1

Output images to array

Posted: 2012-06-13T08:58:41-07:00
by jackson2
I'm attempting to use Imagick to convert a multipage PDF into PNG images, using an array as input and also storing the resulting images in an array. I figured out how to use readimageblob() to load the PDF, and getimageblob() to output to a string, but imagick is only returning the last page of these PDFs. This is the code I'm using:

Code: Select all

function PdfToImg3($pdf_in) {
        $img_array = array();
        $im = new imagick();
        $im->readimageblob($pdf_in);
        $num_pages = $im->getnumberimages();
        $im->setimageformat('png');
        for($x = 1;$x <= $im->getnumberimages(); $x++) {
            $im->previousimage();
            $img_array[$x] = $im->getimageblob();
        }
        return $img_array;
    }
I've tried using nextimage(), using one image at a time, several different PDFs of different versions and page numbers, and a thousand different versions of this code. I can't save these files to disk, I need them as strings/arrays, but ImageMagick absolutely refuses to output ANYTHING but the last page. It will even insert the last page over and over into the created array, for as many pages there are in the PDF.

Suggestions?

Re: Output images to array

Posted: 2012-06-13T10:43:18-07:00
by DJ Mike
Converting PDF Files
http://eclecticdjs.com/forum/viewtopic.php?f=15&t=897

Conversion from PDF to PNG under Imagick
viewtopic.php?f=18&t=18675&p=72199&hili ... ike#p72199

I didn't want it outputting files so I had it generate images on the fly but that approach had a problem. When several users tried inputting large PDF's it had to generate an image for each page and it created so much server load that it locked up my online tool.

Code: Select all

    <?php
    $self = $_SERVER[PHP_SELF];
    $url = $_GET[url];
    $page = $_GET[page];
    $previous = $page-1;
    $next = $page+1;
    ?>
    <html>
    <body>
    <form>
    <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>";
     echo "Select Page: <select name=\"page\">\n";
      for ( $x=0; $x<$pages; $x++)
       {
        $page = $x+1; 
        echo "<option value=\"$page\">$page</option>\n";
       }
     echo "</select>\n";
      }
    echo "<br>";
    if ( $url && $_GET[page] )
      {
      if ($previous>1) 
       {
        echo "<a href=$self?url=$url&page=$previous><</a>&nbsp;";
       }
      if ($next<$page) 
       {
        echo "&nbsp;<a href=$self?url=$url&page=$next>></a>";
       }
    echo "</center>";
      $page = $_GET[page]; # reset page number
      echo "<center><a href=\"viewer_001.php?url=$url&page=$page\"><img src=\"viewer_001.php?url=$url&page=$page\"></a></center>\n";
      }

    ?>
    </form>
    </body>
    </html>

Re: Output images to array

Posted: 2012-06-13T12:01:26-07:00
by jackson2
DJ Mike: That is almost what I'm lo0oking for, but I've gotten that far with the code I'm using. What I can't do is get ImageMagick to return anything but a page at a time. nextImage() and previousImage seem to have no effect whatsoever. seIteratorIndex(0); allows me to retrieve the first page, but then not the second page unless I change it to setIteratorIndex(1);, but again only one at a time. I've tried making a for/foreach loop that update setIteratorIndex($x); but that doesn't work either, it only returns one of the pages as blank.

It is baffling to me that there is no support on this particular topic, populating an array with output from image Magick seems like a very useful, if not important ability and none of the methods that seem to facilitate that ability work. For multi-page PDFs and when not saving directly to disk like it's 1996, the imagick object seems almost useless.

Re: Output images to array

Posted: 2012-06-13T13:09:05-07:00
by jackson2
I found a way to achieve what I need, but it's ugly, inefficient and I'm sure slow but there didn't seem to be any other way.

Code: Select all

function PdfToImg3($pdf_in) {
        $img_array = array();
        $im = new imagick();
        $im->readimageblob($pdf_in);
        $num_pages = $im->getnumberimages();
        $i = 0;
        for($x = 1;$x <= $num_pages; $x++) {
            $im = new imagick();
            $im->readimageblob($pdf_in);
            $im->setiteratorindex($i);
            $im->setimageformat('png');
            $img_array[$x] = $im->getimageblob();
            $im->destroy();
            $i++;
        }
        $im->destroy();
        return $img_array;
    }
Produces an array named $img_array, with the pages of the incoming PDF residing within keys of $img_array as strings of PNG image data.

There MUST be a better way, why won't nextImage() work? Why can't I use setIteratorIndex without reinitializing/(creating new?) imagick objects each time? I must be missing something, but there are gaping holes in the documentation and Google nor StackOverflow know anything about this being done successfully.

Re: Output images to array

Posted: 2012-06-13T13:18:58-07:00
by Bonzo
Imagick is not written or supported by the Imagemagick developers; the main person involved in it stopped answering any comments on his blog in 2009.
What documentation there is is confusing and an example will work in one version and not another; basicaly I think it is dying.

Re: Output images to array

Posted: 2012-06-13T13:23:03-07:00
by jackson2
Bonzo wrote:Imagick is not written or supported by the Imagemagick developers; the main person involved in it stopped answering any comments on his blog in 2009.
What documentation there is is confusing and an example will work in one version and not another; basicaly I think it is dying.
Well, poop.

Re: Output images to array

Posted: 2012-06-14T09:58:55-07:00
by DJ Mike
Another approach would be to create a directory and fill it with PNG's and a TOC page.

Re: Output images to array

Posted: 2012-06-15T11:46:50-07:00
by jackson2
DJ Mike: Yeah, unfortunately I can't write anything to disk in this app, ever, for security reasons. I'm crossing my fingers that once this gets pushed onto the production machine, that the slight increase in headroom from moving outside a VM will help.