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 :)
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.
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.
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();
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();
}