Today I had to convert a PDF into a web embeddable image. In the past we used to run Ghostscript via exec()/system() calls, but that’s annoying because you have to deal with temporary files, if you don’t intend to keep them for archive. So I wanted to try a more decent way: convert the PDF using PHP’s Imagick libraries and display the image inline, using data-uri. This is the code I came up with:
try { // [0] means pick just the first page of the PDF http://php.net/manual/en/imagick.construct.php#113801 $img = new \Imagick(Yii::getAlias("@app/documenti/pdf/{$this->telaio}-{$this->id}.pdf[0]")); } catch (\ImagickException $e) { Yii::trace($e->getMessage(), __METHOD__); // If there's an error, most likely missing file, display a transparent PNG // If you want smaller image you can use GIF, but I had to display it in a mPDF document and it didn't like it return 'data:image/gif;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQMAAAAl21bKAAAAA1BMVEUAAACnej3aAAAAAXRSTlMAQObYZgAAAAFiS0dEAIgFHUgAAAAJcEhZcwAACxMAAAsTAQCanBgAAAAHdElNRQfhCw0MIjeCY5EAAAAACklEQVQI12NgAAAAAgAB4iG8MwAAAABJRU5ErkJggg=='; } $img->setImageFormat("png"); return 'data:image/png;base64,'.base64_encode($img->getimageblob());
Unfortunately the exception I got was not about a missing file (which of course could have been properly checked), but:
ImagickException FailedToExecuteCommand ‘gs’
Ok, given that you have GhostScript installed (maybe via Homebrew), and gs command is in your path, let’s see why it’s not working.
I’ve been pulling my hair nearly for one hour, why the command was running fine from shell and not from within php? The best bet was that gs was not in php’s $PATH, and checking with
getenv("PATH");
indeed showed the evidence confirming this theory. So next step is: how to make Imagick aware of Homebrew’s default installation path /usr/local/bin? Unfortunately setenv(“PATH”) didn’t work, I had to change the variable in the configuration files. After a little more digging into php configuration and Homebrew’s php setup I managed to find it. Edit /usr/local/etc/php/7.0/php-fpm.d/www.conf and add into the [www] stanza:
env[PATH] = /usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin
restart php70 service (or whatever version you have installed) and you’re done!
Thanks! Finally a proper soluti0n