Site icon Ryadel

PHP resize and crop images with Imagick

php-cgi.exe - The FastCGI process exited unexpectedly error and how to fix it

If you're a PHP developer there's a high chance that you already know Imagick, a native php extension to perform image processing tasks using the ImageMagick API. ImageMagick, in turn, is a open-source software  suite that can be used to  create, edit, and compose bitmap images in a variety of formats (over 100) including DPX, EXR, GIF, JPEG, JPEG-2000, PDF, PhotoCD, PNG, Postscript, SVG, and TIFF.

In this post we'll see how we can use the Imagick PHP extension to proportionally resize and crop images in real-time: in a nutshell, we'll learn how to create real-time thumbnails from a given source image; the main advantage about such technique is that it can be used in Windows and Linux environments, since the Imagick extension and the ImageMagick tools suite are available for both platforms.

If you want to create real-time image thumbnails  for PDF files, check out this post instead.

To-do list

Here's a brief summary of what we're going to throughout this post:

  • Install the Imagick PHP extension
  • Install ImageMagick
  • Check the installation
  • Create a sample PHP file (sample source code included)

As we'll see, the first two steps are quite different for Windows and Linux and will require separate instructions, while the third one is identical.

Install the Imagick PHP extension

If you are using a Linux server, in order to setup and activate the Imagick PHP extension you just need to install the corresponding package in the following way:

The first command will install some prerequisites (which you might already have), while the latter will setup the Imagick extension; it goes without saying that the above commands are meant for Debian-based Linux distributions (Debian, Ubuntu, and the likes): if you're using another distro, use the available package manager to do the same.

IMPORTANT: Be sure to pick the package corresponding to your installed PHP version: in the above example we're getting the PHP 5.6 extension.

If you are under Windows, you will need to edit the php.ini file and uncomment the following line:

In the unlikely case it doesn't exist, you can add it under the [ExtensionList] block.

Needless to say, you also need to ensure that you actually do have such DLL file in the /ext/ subfolder - the one placed under your system's PHP installation folder. If you don't have that, you can get it on the PECL Imagick package archive at the following url:

IMPORTANT: Be sure to get a version compatible with your PHP version (5.x, 7.x, 8.x), thread safety (TS or NTS) and server's CPU architecture (32 or 64 bit): if you're not sure about these values,  read this post to understand how you can them out. In case you're still getting troubles, you might also want to take a look at this useful guide by Michele Locati that will greatly help to determine the right package to get depending on your PHP version, architecture and thread safety mode.

Install ImageMagick

Now that we've got the PHP extension we need to install the ImageMagick software suite, as it will be the underlying engine that will actually perform the image processing tasks. In order to do that, go to the ImageMagick official website, navigate to the download section and pick the Linux or Windows Binary Release compatible with your environment.

IMPORTANT: be sure to select the same CPU architecture of your PHP version, otherwise the PHP extension wrapper won't work. Again, if you don't know which version you need to install, check out the Michele Locati's guide to pinpoint the ImageMagick release which is most suited for your PHP and Imagick version.

If you're using Linux, you can also try to directly install the ImageMagick's latest versions through your package manager in the following way:

Check the installation

As soon as we've installed the Imagick PHP extension and the ImageMagick software tool we might want to check if everything is working properly. In order to do that, reload the PHP handler by restarting your web server (of the php-fpm service, in case you're using it) and then create a PHP file with the following content:

Put the one-liner above in a phpinfo.php file, publish it to your web server and run it once to see if our prerequisites are being properly loaded:

PHP resize and crop images with Imagick

If you see something like this, it means that both the Imagick PHP extension and the ImageMagick software suite are ready to be used by PHP. If you don't see this, here are some common issues you might need to fix, splitted into Windows and Linux.

WARNING: be sure to delete the phpinfo.php file as soon as you don't need it anymore: leaving it publicly available is a major security risk, as it exposes your entire PHP configuration, as well as some sensitive system settings and folder structures.

If you don't want to use the phpinfo() technique, you can check if the extension is properly loaded using the PHP CLI in the following way:

If imagick is present among the resulting text lines, it means that everything is ok.

Windows issues

  • Add the ImageMagick installation folder to the PATH environment variable. Be sure to add the folder containing the executable files, because it has been changed between ImageMagick 6.x and 7.x versions in the following way:
    • 6.x: C:\Program Files (x86)\ImageMagick-6.9.3-7-vc11-x86\bin
    • 7.x: C:\Program Files (x86)\ImageMagick-7.0.11-Q16
  • Create a temporary folder accessible by ImageMagick and add it to the MAGICK_TEMPORARY_PATH (or MAGICK_TMPDIR) environment variable. This might be required if your PHP temporary folder is unaccessible from the ImageMagick executables, which seems to be fairly frequent on most Windows-based servers. If you see "permissions denied" issues, this workaround will most likely fix it.

Linux issues

None so far: the Linux configuration is usually free from major issues, as long as the appropriate Imagick and ImageMagick versions are being installed.

WARNING: be sure to delete the phpinfo.php file as soon as you don't need it anymore: leaving it publicly available is a major security risk, as it exposes your entire PHP configuration, as well as some sensitive system settings and folder structures.

Source code sample

Now that we've dealt with the prerequisites and checked that everything is worked as expected, we can proceed with the source code.

Here's the sample code for a minimalistic thumb.php file that accepts the following GET parameters:

  • url : the URL of a source image
  • w : the width of the thumbnail that will be generated
  • h : the height of the thumbnail that will be generated
  • mode : 0 for proportional resize with a "best-fit" crop (default), 1 for proportional resize with background padding.
  • bg : the background padding color, only used when mode is equal to 1 and the thumbnail requires a padding (default is 000000, meaning that we'll have a black background).

The main difference between mode 0 and mode 1 is that the first will potentially crop the source image in order to make it fit to the given width/height while avoiding the "padding" effect, while the second will preserve the image content while potentially adding a padding to make it fit. To better understand it, take a look at the following screenshot:

If one between width (w) and height (h) parameter is not present, it will be automatically calculated using the same ratio inferred from the other one; this also means that mode will be irrelevant in such scenario, since no cropping nor padding will occur. If neither of them are present, the script will just return the source image without performing changes.

That said, here's the PHP source code:

NOTE:  the code can be used "as-is" to test if the Imagick implementation works: however, in a real production environment, we strongly suggest to further improve the "path traversal hacks" countermeasures to prevent (malicious) users from being able to call the script and obtain "any" image file present on the server: the best thing to do in order to avoid that would be to only allow image resize from a number of fixed folders, stripping everything minus the filename from the input URL and constructing the path using a secure server-side logic.

In practical terms, instead of doing this:

we could do something like this:

And obtain a much safer outcome: if you need to specify subfolders (or different folders), you can add another paramter and use a "safe" convention to make the caller able to select it (such as "1" for "/www/website/images", "2" for "/www/website/images/subfolder/", "3" for "/www/website/anotherfolder/", and so on).

Conclusions

That's it, at least for now: I hope that this post and the above code sample will be useful for other PHP developers that are looking for a way to perform image processing tasks in a easy and convenient way.

 

Exit mobile version