11

We are converting PDF pages to multiple single images. We found a code snippet in stackoverflow and converted it to a service class. We have Imagick installed and it shows up in phpinfo() as well. However, in our laravel application, version 5.2, we are getting following error.

ReflectionException in Container.php line 798:
Class Imagick does not exist

We tested our code outside laravel environment and it's working like a charm. No such error is thrown. We also ran following command to check Imagick

php -i | grep -i imagick

and this is the output

    /etc/php5/cli/conf.d/20-imagick.ini,
    imagick
    imagick module => enabled
    imagick module version => 3.4.3RC1
    imagick classes => Imagick, ImagickDraw, ImagickPixel, ImagickPixelIterator
    Imagick compiled with ImageMagick version => ImageMagick 6.7.7-10 2016-06-01 Q16 http://www.imagemagick.org
    Imagick using ImageMagick library version => ImageMagick 6.7.7-10 2016-06-01 Q16 http://www.imagemagick.org
    imagick.locale_fix => 0 => 0
    imagick.progress_monitor => 0 => 0
    imagick.skip_version_check => 0 => 0

Everything seems right. It works outside Laravel but not in laravel. I got no idea what's wrong. Do we have to configure Laravel to use Imagick?

Here is our service class that we are using

<?php

namespace App\Services\Utilities;

use Imagick;

class PdfToImageService
{
    /**
     * Destination folder where images will be saved
     * @var string
     */
    protected $destination = 'images/users/';

    /**
     * Injecting dependencies
     * 
     * @param Imagick $imagick
     */
    function __construct(Imagic $imagick)
    {
        $this->imagick = $imagick;
    }

    /**
     * Convert pdf having multiple pages to multiple single images
     * 
     * 1. Strip document extension
     * 2. Convert this document
     * 3. Set background color and flatten. It Prevents black background on objects with transparency
     * 4. Set image resolution
     * 5. Determine number of pages
     * 6. Compress Image Quality
     * 7. Generate images from each pdf page
     * 8. Destroy current imagick session
     * 
     * @param  string $fileName
     * @return array  $convertedImageNames
     */
    public function createImages($fileName)
    {
        $fileName = basename($fileName);
        $this->imagick->readImage($fileName);
        $this->imagick->setImageBackgroundColor('white');
        $this->imagick->setResolution(300,300);
        $this->imagick->setImageCompressionQuality(100);

        $convertedImageNames = $this->generateImageFromPDFPage(
            $fileName, $this->imagick->getNumberImages()
        );

        $this->imagick->destroy();

        return $convertedImageNames;
    }

    /**
     * Loop throught each pdf pages and convert it to image.
     *      A. Set iterator postion
     *      B. Set image format
     *      C. Write Images to destination folder 
     * 
     * @param  string  $fileName
     * @param  integer $noOfPages
     * @return array
     */
    private function generateImageFromPDFPage($fileName, $noOfPages)
    {
        for($i = 0;$i < $noOfPages; $i++) {
            $this->imagick->setIteratorIndex($i);
            $this->imagick->setImageFormat('jpeg');    
            $this->imagick->writeImage($this->destination.$fileName.'-'.$i.'.jpg');
            $convertedImageNames[$i] = $fileName.'-'.$i.'.jpg';
        }

        return $convertedImageNames;
    }
}
AddWeb Solution Pvt Ltd
  • 21,025
  • 5
  • 26
  • 57
IamGhale
  • 1,275
  • 2
  • 14
  • 26
  • The problem might be namespace. Try adding \ in front of Imagick use statement. It might be Laravel resolving wrong class in IOC container, it might not be understanding the class in global namespace – developernaren Jun 15 '16 at 12:44
  • 1
    did you try installing imagemagick ? `apt-get install imagemagick` – rüff0 Aug 28 '18 at 05:37
  • 1
    `function __construct(Imagic $imagick)` - that does not look like you try to load the correct class. Have you tried using `Imagick` instead of `Imagic`? – Nico Haase Nov 09 '21 at 15:44

4 Answers4

4

This is what worked for me for Laravel 5.7 on Homestead:

sudo apt-get update
sudo apt-get install -y imagemagick php-imagick
sudo service php7.2-fpm restart
sudo service nginx restart

If you're using a version of PHP other than 7.2 or aren't using Nginx, you'll need to adjust.

miken32
  • 42,008
  • 16
  • 111
  • 154
Ryan
  • 22,332
  • 31
  • 176
  • 357
2

Can you try editing php.ini located in
cd /etc/php5/apache2/php.ini

if your linux is ubuntu ?

cat php.ini | grep extension=imagick.so

if there is the results of search, then you might get this
;extension=imagick.so
You remove this semicolon ; and if not any results,

echo "extension=imagick.so" >> /etc/php5/apache2/php.ini

And finally

sudo /etc/init.d/apahce2 restart

It works with this code

<?php

namespace App\Http\Controllers;
use Illuminate\Routing\Controller as BaseController;
use Imagick;

class GuestController extends BaseController {

    public $imagic;

    public function __construct(){
        $this->imagic = new Imagick();
    }

    public function test(){
        return get_class_methods($this->imagic);
    }
}
Luca Angioloni
  • 2,243
  • 2
  • 19
  • 28
  • We already did that, adding the extension=imagick.so in /etc/php5/apache2/php.ini and restarting the apache server. We did all the required set up. I guess there is some issue with my laptop. It's working fine now. I should have restarted my laptop before. Anyway thank you for your response. – IamGhale Jun 16 '16 at 04:19
0

Try this:

  1. Dowload the extension here (the tarball): http://pecl.php.net/package/imagick

(Lets suppose you use the version: 3.4.3)

  1. Go to the extension directory with the terminal Example

    cd /Downloads/
    
  2. Extract the tarball

    tar xf imagick-3.4.3.tgz
    
  3. Go to the new extracted directory

    cd imagick-3.4.3.tgz
    
  4. Phpize the library (is base written in C)

    phpize
    
  5. Run

    ./configure
    
  6. Run

    make && make test && make install
    
  7. Go to your php.ini (ussualy in Ubuntu located at /etc/php/7.x/cli/php.ini) and add this line:

    extension=imagick.so 
    

That's it. Update php

    service php7.2-fpm restart

and the server (apache, nginx or other).

Luigi Lopez
  • 1,037
  • 10
  • 23
  • I get this error: "checking ImageMagick MagickWand API configuration program... checking Testing /usr/local/bin/MagickWand-config... Doesn't exist" – Ryan Oct 10 '18 at 01:54
  • Try if the extension is in php with phpinfo() http://php.net/manual/en/function.phpinfo.php – Luigi Lopez Oct 10 '18 at 14:01
  • 1
    The `./configure` part. This worked for me though: https://stackoverflow.com/a/52742469/470749 – Ryan Oct 10 '18 at 14:25
-1

To install Imagick run bellow command:
sudo apt-get install php-imagick

For specific PHP version (in my case 7.1):
sudo apt-get install php7.1-imagick

Then restart apache:
sudo service apache2 restart

To check if the extension has been installed:
php -m | grep imagick

If the above approach doesn't works for you, try this:
sudo apt install libmagickwand-dev
sudo apt-get install php-imagick

Update php.ini with extension=imagick.so and then restart apache.

  • Please add some explanation to your answer such that others can learn from it. According to the output of `php -i`, these packages are already installed – Nico Haase Nov 09 '21 at 15:45