PHP: Imagick converting multi-page pdf into single image issue - php

I am trying to convert a multi-page pdf into a single image with all pages in the pdf stacked. I am trying to use the Imagick() class. I found similar questions but none have helped the issue. Here is the code I am using.
$img = new Imagick();
$img->setResolution(300, 300);
$img->readImage(example.pdf);
$img->resetIterator();
$imga = $img->appendImages(true);
$imga->setImageFormat('jpg');
$imga->writeImage("pdfs.jpg");
Only the last page of the pdf is saved in the jpg file the other pages are not.
I am using ImageMagick-7.0.10, PHP 7.3.12 and I am on Windows 10.

You,have to add the index of the pdf page you want.
For the first page :
$img->readImage(example.pdf[0]);
I'm looking to generate animated gif with multipage pdf... not done yet !

Related

Convert the first n pages of a pdf file to a single png Image file using PHP ImageMagick library

I'm working with the PHP ImageMagick Library to convert uploaded pdf files to single png files so I can display the pdf as a single image on my Laravel webpage. So far I'm able to convert an entire pdf to a single image with this code:
<?php
$imagick = new Imagick();
$file = new File;
// other lines of code
// ...
$imgPath = Storage::path($file->file_path);
$imgSavePath = Storage::path('uploads/buffer/'.Str::beforeLast($file->name, '.').'.png');
$imagick->readImage($imgPath);
$imagick->resetIterator();
$imagick = $imagick->appendImages(true);
$imagick->writeImages($imgSavePath, true);
This works by producing a single png image. However, I find this to be resource intensive (storage wise) and time consuming because I'm delivering the functionality through an ajax call.
I want my web application to convert only the first n pages of the pdf (say first 5 pages) into a single image to act as a preview on the site - thereafter the user can download the entire pdf to view on their local system. The function should work regardless of the number of pages in an uploaded pdf document.
So far, I only find in the documentation where I can read a page at a particular index from the Imagick object and convert to an image using:
...
$imgPath = Storage::path($file->file_path);
$index = 5;
$imagick->readImage($imgPath. '[' . $index . ']');
However, I'm finding it difficult to refactor this so that the application can read the first n pages.
Intuitively, the readImage() function seems to work in a similar way as the command line syntax. Thanks to the hint from #MarkSetchell in the comments:
<?php
$imagick = new Imagick();
$file = new File;
// other lines of code
// ...
$imgPath = Storage::path($file->file_path);
$imgSavePath = Storage::path('uploads/buffer/'.Str::beforeLast($file->name, '.').'.png');
$imagick->readImage($imgPath.'[0-4]'); // read only the first 5 pages
$imagick->resetIterator();
$imagick = $imagick->appendImages(true);
$imagick->writeImages($imgSavePath, true);
I'm using ImageMagick 6.9.10-68 and PHP 8.1.12

PHP Imagick annotateImage fails on some images

I have a PHP script which generates images from PDF pages using PHP Imagick. In which i write a piece of data on top of the image using annotateImage function and take it as output. This is failing recently on some PDF images being selected. I mean when a specific PDF is being given as input to this program the annotateImage function fails to write data where on many other PDF files it is performing well...
this is the following code which run on a loop to generate this images...
$imagick->setResolution(200,200);
$imagick->readImage('files/pdffile.pdf[1]');
$imagick->annotateImage($draw_small, 1250, 100, 10, 'Hello header');
$imagick = $imagick->flattenImages();
$file = fopen("/outputfile.jpg", 'w+');
chmod($folder_in_action."/outputfile.jpg", 0755);
fclose($file);
$imagick->writeImage('/outputfile.jpg');
$imagick->clear();
The code works well and get the exact PDF page as image in the folder but the annotateImage does not works on specific PDF files and so the output comes with no 'Hello header' message.
The same code works perfect on most of the PDF's where i get the specific PDF page with 'Hello header' message written on top as image...
So could not able to guess what could be the issue...
PDF file which does not allow annotateImage to write text is here:
http://wikisend.com/download/143652/notworking.pdf
PDF which is working (usually most of the pdf files are working properly...)
http://wikisend.com/download/215044/working.pdf

PDF Image thumbnail preview in laravel 5.1?

I have file module, where I want to list all files,with thumbnail preview.
as like follows,
I am storing files in storage folder,which is not accessible via http.
So How can I provide thumbnail preview for docs especially image and PDF.
Is there any package availabe in laravel 5.1?
The preview image of a PDF file is usually the first page of the PDF file.
You can use ImageMagick to obtain that first page of the PDF file.
<?php
$imagick = new imagick('sample.pdf[0]'); // 0 specifies the first page of the pdf
$imagick->setImageFormat('jpg'); // set the format of the output image
header('Content-Type: image/jpeg'); // set the header for the browser to understand
echo $imagick; // display the image
?>
You can also output (save the contents of the image in a file) and store it under a thumbnail folder with the PDF name as the file name. like ( sample.jpg )
As for a solution based on laravel, I don't think laravel has any package that can do the same
Though the question was posted quite a long ago but I'm answering because it might helps others. There is a package for generating image from pdf. Pdf to Image. You should have Imagick and Ghostscript installed

Gmagick thumbnail for multi-page PDF

I'm attempting to create a thumbnail of a multi-page PDF document using Gmagick, however I only want the first page of the PDF, not all of them.
$thumb = new Gmagick();
$thumb->readImage("/path/to/file/document.pdf");
$thumb->setImageFormat('JPG');
$thumb->thumbnailimage(198, 255);
$thumb->writeImage("/path/to/file/document.jpg");
$thumb->destroy();
This code works, however instead of creating just 1 image 'document.jpg' it creates 'document.jpg.0', 'document.jpg.1', 'document.jpg.2', etc. for all of the PDF pages. I could go and delete all the additional pages and rename the first image just 'document.jpg' but that seems a bit hacky to me.
Is there a way to designate just the first page of the PDF? I can't seem to find anything, and Gmagick's documentation seems to be lacking.
Pekka is right. GraphicsMagick - just like ImageMagick - accepts the special pdf file name notation filename.pdf[0] which would render only the first page, filename.pdf[1] for the second page, and so on.

Converting all pages of a multi page PDF into an image with PHP causes a duplicate result in the image

So I am using imagick to convert a PDF into an image. All works well for single page PDFs but I ran into a snag with a multi page pdf.
I found an example on how to deal with multiple pages here: http://php.net/manual/en/function.imagick-appendimages.php so I took that code:
$im = new Imagick($src);
$im->readImage($src);
$im->resetIterator();
$ima = $im->appendImages(true);
$ima->setImageFormat('jpg');
header("Content-Type: image/jpeg");
print $ima;
This works in that it produces an image with each page of the pdf the problem is that the PDF is displayed twice in the image. So, a three page PDF is displayed as a single image of 6 pages.
Here is an example PDF
and the resulting image created with the above code.
What am I doing that is causing this to happen?
Resolution:
Based on tandu's answer this did the trick
$im = new Imagick($src);
$im->resetIterator();
$ima = $im->appendImages(true);
$ima->setImageFormat('jpg');
header("Content-Type: image/jpeg");
print $ima;
The Imagick constructor loads the image from the file you provide. When you run readImage(), it loads them again. You only need one of those two.

Categories