16

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 to example-0.jpg. Issue I'm sure lies within the for 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();
}
Mike Barwick
  • 6,288
  • 6
  • 51
  • 76
  • I do not know if something changed, but last time I was generating pdf thumbnail it was by `$img = new imagick('file.pdf[0]');` to get only first page. – dev-null-dweller Dec 15 '13 at 19:53
  • Yeah...I'm aware of that. But I don't want the first, middle, or last page - I want ALL the pages converted into single images. – Mike Barwick Dec 15 '13 at 19:54
  • I know, what I'm trying to say is that PDF does not work well as other multi-image formats, so probably you have to get number of pages and in the loop create new imagick instances, appending `[$i]` to file name. – dev-null-dweller Dec 15 '13 at 19:56
  • Did you look at *all* the code...that's exactly what I'm trying to do... – Mike Barwick Dec 15 '13 at 19:57
  • 1
    This method will not work with multi-page PDF. `$img->flattenImages();` merges all pages on top of each other and exports the file as a single image, regardless of the amount of pages. For a solution to multi-page PDFs with black background see http://stackoverflow.com/q/26793063/2028547 – MarcinWolny Jan 13 '15 at 15:05

4 Answers4

12

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.

Mike Barwick
  • 6,288
  • 6
  • 51
  • 76
  • I 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) – DJDave Jan 07 '20 at 18:52
6
 /* 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();
                }
Anand
  • 536
  • 3
  • 9
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.

1

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();
    }
    //}
?>
Umesh Maliya
  • 115
  • 7