PDF to JPG Imagic page selection

2019-07-18 21:13发布

问题:

Loads of answers on how to do it for a command line

convert /path/to/file/file.pdf[3] output.jpg

great... but what if I am using in memory processing, I am generating PDF with PDFlib and then output its buffer to a function that I want to generate jpg preview of selected page. How? My code :

    [...]
    $buf = $pdf->get_buffer();

    //$buff is just a PDF stored in a string now.

    $im = new Imagick();
    $im->readimageblob($buf);

    $im->setImageFormat("jpg");
    $im->setimagecompressionquality(60);

    $len = strlen($im);
    header("Content-type: image/jpeg");
    header("Content-Length: $len");      
    header("Content-Disposition: inline; filename=test.jpg");

    echo $im;

This creates a jpeg but always returns last page of the PDF. I want to be able to choose which one will be converted. Is it doable without saving temporary files and using command line (exec('convert /path/to/file/file.pdf[3] output.jpg')) syntax?

Let me add that I tried

    $im->readimageblob($buf[2]);

and it did not work :)

回答1:

It's not good news unfortunately, but I can definitively say that, as of time of writing, the ImageMagick (and PHP libraries) don't support the page notation that you're trying to use. (For people from the future finding this: I'm checking php-imagick-3.0.1 and imagemagick-6.6.0.4).

I'm trying to do the exact same thing as you, and I've just spent the last few hours trawling through the source, trying to figure out what it does and how it gets the pages, and it looks like it simply won't use it when reading from a stream (ie. the readBlob() call).

As such, I'm just going to be putting it in a temporary file and reading it from there instead. Not as elegant, but it'll work.



回答2:

version 3.0.1 being on the last image or first image in imagic object

$image_obj = new Imagick("test.pdf"); then you on last image in $image_obj

if you use

fp_pdf = fopen("test.pdf", 'rb');
$image_obj = new Imagick();
$image_obj -> readImageFile($fp_pdf);

then you on the first image in $image_obj

In second case to switch to last image you can do

fp_pdf = fopen("test.pdf", 'rb');
$image_obj = new Imagick();
$image_obj -> readImageFile($fp_pdf,2); // 2 can be any positive number?

then you on the last image in $image_obj

echo $image_obj->getNumberImages() // Returns the number of images in the object

then

   if ($image_obj->hadPreviousImage)
       $image_obj->previousImage() //Switch to the previous image in the object
    }

or

if ($image_obj->hasNextImage()) {
   $image_obj->nextImage())  //Switch to the next image in the object
}

e.g. if you have 6 images total and you need 4th then do from the end

$image_obj->previousImage()
$image_obj->previousImage()
$image_obj->setImageFormat("png");
header("Content-Type: image/png");
echo $image_obj;

EDIT: Another find is that you can

foreach($image_obj as $slides) {
    echo "<br>".$Obj_img->getImageWidth();
    //or wehatever you need to do.
}

EDIT 2: Very simple solution would be to use this function $image_obj->setIteratorIndex(4) count starts with zero.



回答3:

For the ones who is still searching for solution of reading specific page number from blob, please check this question Creating array populated by images from a PDF using PHP and ImageMagick

$img_array = array();
$im = new imagick();
$im->setResolution(150,150);
$im->readImageBlob($pdf_in);
$num_pages = $im->getNumberImages();
for($i = 0;$i < $num_pages; $i++) 
{
    $im->setIteratorIndex($i);
    $im->setImageFormat('jpeg');
    $img_array[$i] = $im->getImageBlob();
}
$im->destroy();


回答4:

I'm loading the PDF binary into memory from Amazon S3 and then selecting the specific page I want using setIteratorIndex() followed by getImage()

function get_image_from_pdf($pdf_bytes, $page_num){
    $im = new \Imagick();
    $im->setResolution(150, 150);
    $im->readImageBlob($pdf_bytes);
    $im->setIteratorIndex($page_num);
    $im = $im->getImage();
    $im->setImageFormat('png');
    return $im->getImageBlob();
}