Saving Each PDF Page to an Image Using Imagick
Solution 1
Seems like most of my code was correct. The issue was, I was using $img->flattenImages();
incorrectly. This merges
a sequence of images into one image. Much like how Photoshop flattens all visible layers into an image when exporting a jpg
.
I removed the above line and the individual files were written as expected.
Solution 2
/* convert pdf file to list image files */
if($_FILES['file_any']['type']=='application/pdf'){
$file_name = str_replace(substr($url,0,strpos($url,$_FILES['file_any']['name'])),'',$url);
$basename = substr($file_name,0,strpos($file_name,'.'));
$abcd = wp_upload_dir();
$delpath = $abcd['path'];
$savepath = $abcd['url'];
$dirpath = substr($savepath,(strpos($savepath,'/upl')+1));
$file_name = basename($file_name, '.pdf');
$img = new imagick($delpath.'/'.$file_name.'.pdf');
$img->setImageBackgroundColor('white');
$img->setResolution(300,300);
$num_pages = $img->getNumberImages();
$img->setImageCompressionQuality(100);
$imageurl = NULL;
$imagedelurl = NULL;
for($i = 0;$i < $num_pages; $i++) {
$imageurl[]=$savepath.'/'.$basename.'-'.$i.'.jpg';
$imagedelurl[] = $delpath.'/'.$basename.'-'.$i.'.jpg';
// Set iterator postion
$img->setIteratorIndex($i);
// Set image format
$img->setImageFormat('jpeg');
// Write Images to temp 'upload' folder
$img->writeImage($delpath.'/'.$file_name.'-'.$i.'.jpg');
}
$img->destroy();
}
Solution 3
There is a much easier way without the loop, just use $img->writeImages($filename,false);
and it will make a file per PDF-page. As you said, if you flatten
the image first, it only saves 1 page.
Solution 4
first install
imagemagick
in your system or server and then create
pdfimage
folder and put pdf file in this folder then run the code and upload it file
<?php
$file_name = $_FILES['pdfupload']['name']; // using just for this example, I pull $file_name from another function
//echo strpos($file_name,'.pdf');
$basename = substr($file_name,0,strpos($file_name,'.'));
//echo $_FILES['pdfupload']['type'];
//if (isset($_POST['submit'])){
if($_FILES['pdfupload']['type']=='application/pdf'){
// Strip document extension
$file_name = basename($file_name, '.pdf');
// Convert this document
// Each page to single image
$img = new imagick('pdfimage/'.$file_name.'.pdf');
// Set background color and flatten
// Prevents black background on objects with transparency
$img->setImageBackgroundColor('white');
//$img = $img->flattenImages();
// Set image resolution
// Determine num of pages
$img->setResolution(300,300);
$num_pages = $img->getNumberImages();
// Compress Image Quality
$img->setImageCompressionQuality(100);
$images = NULL;
// Convert PDF pages to images
for($i = 0;$i < $num_pages; $i++) {
$images[]=$basename.'-'.$i.'.jpg';
// Set iterator postion
$img->setIteratorIndex($i);
// Set image format
$img->setImageFormat('jpeg');
// Write Images to temp 'upload' folder
$img->writeImage('pdfimage/'.$file_name.'-'.$i.'.jpg');
}
echo "<pre>";
print_r($images);
$img->destroy();
}
//}
?>
Mike Barwick
Follow me on Twitter and I'll follow back! Be sure to say hello though! @mikebarwick
Updated on June 08, 2022Comments
-
Mike Barwick almost 2 years
I have the following php function below that's converting a local PDF file into images. In short, I want each PDF page to be converted to a separate image.
The function converts the PDF to an image - but only the last page. I want every page of the PDF to be converted to a image and numbered. Not just the last page of the PDF.
Currently, this function converts the last page of
example.pdf
toexample-0.jpg
. Issue I'm sure lies within thefor
method. What am I missing?$file_name = 'example.pdf'; // using just for this example, I pull $file_name from another function function _create_preview_images($file_name) { // Strip document extension $file_name = basename($file_name, '.pdf'); // Convert this document // Each page to single image $img = new imagick('uploads/'.$file_name.'.pdf'); // Set background color and flatten // Prevents black background on objects with transparency $img->setImageBackgroundColor('white'); $img = $img->flattenImages(); // Set image resolution // Determine num of pages $img->setResolution(300,300); $num_pages = $img->getNumberImages(); // Compress Image Quality $img->setImageCompressionQuality(100); // Convert PDF pages to images for($i = 0;$i < $num_pages; $i++) { // Set iterator postion $img->setIteratorIndex($i); // Set image format $img->setImageFormat('jpeg'); // Write Images to temp 'upload' folder $img->writeImage('uploads/'.$file_name.'-'.$i.'.jpg'); } $img->destroy(); }
-
DJDave over 4 yearsI don't follow the line $img = new imagick('uploads/'.$file_name.'.pdf'); - surely you pass in the filename, and pass that to the constructor? If your filename has no path, and is in the uploads directory I can see it might work. Anyhow, if it helps anyone else, I replaced the line with $img = new imagick(); $img->readImage($file_name); (BEFORE the line that trims off the extension by calling basename)