Search code examples
phplaravel-8imagick

Error converting pdf from url to image - Laravel Imagick


In my Laravel application with sail (docker), I'm making a function to convert pdf documents to images.

The function receives a URL, which contains the pdf document.
Ex: "http://localhost:5000/my-application/hojavavida/8/documents/1676480714qhRZ57Bjl2nD673.pdf"

All these documents come from the Minio container.
I am using Imagick to do the conversion the function is as follows:

public function pdfToImage($pdfFilePath)    
{ 
        $imagick = new Imagick();
        $imagick->readImage($pdfFilePath);
        
        $filename = time().Str::random(15).'.'.'jpg';
        $imagick->setImageFormat('jpg');
        $imagick->writeImage(Storage::disk('tmp')->put($directory .'/'. 
        $filename, $imagick));
        dd("created");
}

But it returns the following message:

"message": "Failed to read the file",
"exception": "ImagickException",

I have checked that by passing another URL with a pdf document, and it is able to read it and generate the image from the document.

The Main problem: I can't get it to read the URLs coming from my docker.

I did the requisites validation
verify if Imagick is installed on the container

php -i | grep imagick

imagick
imagick module => enabled
imagick module version => 3.7.0
imagick classes => Imagick, ImagickDraw, ImagickPixel, ImagickPixelIterator, ImagickKernel
imagick.allow_zero_dimension_images => 0 => 0
imagick.locale_fix => 0 => 0
imagick.progress_monitor => 0 => 0
imagick.set_single_thread => 1 => 1
imagick.shutdown_sleep_count => 10 => 10
imagick.skip_version_check => 1 => 1

verify GhostScript

which gs

/usr/bin/gs

Solution

  • Finally and seeing that only local URLs were the problem. so, I parse the URLs when those come from localhost and transform it to 'http://minio:9000'.

    // get host from URL

    $pdfFilePath = [];
        foreach ($urls as $url) {
            $host = parse_url($url, PHP_URL_HOST);
            if ($host == 'localhost') {
                $pdfFilePath[] = $this->transformUrl($url);
            }
        }
    

    So now passing the new URL to Imagick the conversion to image is correct.

    $imagick = new Imagick();
            $imagePaths = [];
            foreach ($pdfFilePath as $pdf) {
                $imagick->readImage($pdf);
                $filename = pathinfo($pdf, PATHINFO_FILENAME);
                $imagick->setImageFormat('jpg');
                $imagick->writeImage(public_path($directory . '/' . $filename . '.jpg'));
                $imagePaths[] = url($directory . '/' . $filename . '.jpg');