Scaling and rotating

bool imagecopyresized ( resource dest_image, resource source_image, int dest_x, int dest_y, int source_x, int source_y, int dest_width, int dest_height, int source_width, int source_height)

bool imagecopyresampled ( resource dest_image, resource source_image, int dest_x, int dest_y, int source_x, int source_y, int dest_width, int dest_height, int source_width, int source_height)

resource imagerotate ( resource source_image, float angle, int background_color)

PHP offers you two different ways to resize an image, and you should choose the right one for your needs. The first option, imagecopyresized(), allows you to change the size of an image quickly and easily, but has the downside of producing fairly low-quality pictures. When an image with detail is resized, aliasing ("jaggies") is usually visible, which makes the resized version hard to read, particularly if the resizing was to an unusual size. The other option is imagecopyresampled(), which takes the same parameters as imagecopyresized() and works in the same way with the exception that the resized image is smoothed so that it is still visible. The downside here is that the smoothing takes more CPU effort, so the image takes longer to produce.

Here is an example of imagecopyresized() in action - save it as specialeffects.php:

<?php
    header("content-type: image/png");
    $src_img = imagecreatefrompng("complicated.png");
    $srcsize = getimagesize("complicated.png");
    $dest_x = $srcsize[0] / 1.5;
    $dest_y = $srcsize[1] / 1.5;
    $dst_img = imagecreatetruecolor($dest_x, $dest_y);

    imagecopyresized($dst_img, $src_img, 0, 0, 0, 0, $dest_x, $dest_y, $srcsize[0], $srcsize[1]);
    imagepng($dst_img);
    imagedestroy($src_img);
    imagedestroy($dst_img);
?>

There are two images being used in there. The first one, $src_img, is created from an PNG screenshot of the online PHP manual - this contains lots of text, which highlights the aliasing problem with imagecopyresized() nicely. The variables $dest_x and $dest_y are set to be the width and height of complicated.png divided by 1.5, which will set the destination size to be 66% of the source size. Resizing "exact" values such as 10%, 50%, etc, usually looks better than resizing unusual values such as 66%, 79%, etc.

The second image is then created using imagecreatetruecolor() and our destination sizes, and stored in $dst_img. Now comes the key part: imagecopyresized() takes quite a few variables, and you really need not bother memorising them. They are, in order, the image to copy to, the image to copy from, the destination X co-ordinate, destination Y co-ordinate, source X co-ordinate, source Y co-ordinate, destination width, destination height, source width, and source height. Parameters three to six, the co-ordinates, allow you to copy regions of the pictures as opposed to the whole picture - PHP will copy from the specified co-ordinate to the end of the picture, so by passing in 0 we're using the entire picture. You probably will not ever want to copy regions using these parameters, so just leave them as 0.

Take a screenshot of a website of your choosing, and save it as complicated.png in the same directory as your PHP script, then load up specialeffects.php in your browser. All being well, you should see that the website picture has been resized down, but as a result all the text is hard if not impossible to read.

Now, to give you an idea why imagecopyresampled() is better, change the imagecopyresized() call to imagecopyresampled(). The parameter list is identical, so just change the function name. This time you should see a marked difference - the website is still smaller, but should be perfectly legible as the text should be nicely smoothed.

The final special effect we're going to look at is imagerotate(), which, as you can guess, rotates an image. This is much easier to do than resizing and resampling, as it only has three parameters: the image to rotate, and the number of degrees anti-clockwise you wish to rotate it, and the colour to use wherever space is uncovered. The rotation is performed from the centre of the source image, and the destination image will automatically be sized to fit the whole of the rotated image.

The last parameter only really makes sense once you have seen it in action, so try out this script:

<?php
    $image = imagecreatefrompng("button.png");
    $hotpink = imagecolorallocate($image, 255, 110, 221);
    $rotated_image = imagerotate($image, 50, $hotpink);

    header("content-type: image/png");
    imagepng($rotated_image);
    imagedestroy($image);
    imagedestroy($rotated_image);
?>

You'll need to put your own file in where I have used button.png, but otherwise it should be straightforward.

The image has been rotated by 50 degrees, anti-aliased to avoid jagged lines, resized by the minimum amount so that the outputted picture has just enough space to hold the rotated image. Finally, note that the gaps in the image, effectively the "background", have been colour the hot pink we defined. White is usually preferable, but it would not have been quite so obvious in the screenshot!

 

Want to learn PHP 7?

Hacking with PHP has been fully updated for PHP 7, and is now available as a downloadable PDF. Get over 1200 pages of hands-on PHP learning today!

If this was helpful, please take a moment to tell others about Hacking with PHP by tweeting about it!

Next chapter: Points and lines >>

Previous chapter: Basic image copying

Jump to:

 

Home: Table of Contents

Copyright ©2015 Paul Hudson. Follow me: @twostraws.