Cropping an Image to Make Square Thumbnails in PHP

Overview

You can use the square_crop() function to automatically resize and trim virtually any JPEG, GIF, or PNG image. The function accepts up to four parameters, but only requires two. If the file extension of the destination file is different from the source file, the image will automatically be converted to the appropriate format.

This function requires the PHP GD library.

Parameters

Parameter Description Default Value
$src_image The name of the source image -
$dest_image The name of the new thumbnail image to be created -
$thumb_size The size of the new thumbnail in pixels (optional) 64
$jpg_quality Compression quality: 0-100 (optional) 90

Return Values

This function returns true on success, false otherwise.

The Code

<?php

function square_crop($src_image, $dest_image, $thumb_size = 64, $jpg_quality = 90) {

    // Get dimensions of existing image
    $image = getimagesize($src_image);

    // Check for valid dimensions
    if( $image[0] <= 0 || $image[1] <= 0 ) return false;

    // Determine format from MIME-Type
    $image['format'] = strtolower(preg_replace('/^.*?\//', '', $image['mime']));

    // Import image
    switch( $image['format'] ) {
        case 'jpg':
        case 'jpeg':
            $image_data = imagecreatefromjpeg($src_image);
        break;
        case 'png':
            $image_data = imagecreatefrompng($src_image);
        break;
        case 'gif':
            $image_data = imagecreatefromgif($src_image);
        break;
        default:
            // Unsupported format
            return false;
        break;
    }

    // Verify import
    if( $image_data == false ) return false;

    // Calculate measurements
    if( $image[0] &gt; $image[1] ) {
        // For landscape images
        $x_offset = ($image[0] - $image[1]) / 2;
        $y_offset = 0;
        $square_size = $image[0] - ($x_offset * 2);
    } else {
        // For portrait and square images
        $x_offset = 0;
        $y_offset = ($image[1] - $image[0]) / 2;
        $square_size = $image[1] - ($y_offset * 2);
    }

    // Resize and crop
    $canvas = imagecreatetruecolor($thumb_size, $thumb_size);
    if( imagecopyresampled(
        $canvas,
        $image_data,
        0,
        0,
        $x_offset,
        $y_offset,
        $thumb_size,
        $thumb_size,
        $square_size,
        $square_size
    )) {

        // Create thumbnail
        switch( strtolower(preg_replace('/^.*\./', '', $dest_image)) ) {
            case 'jpg':
            case 'jpeg':
                return imagejpeg($canvas, $dest_image, $jpg_quality);
            break;
            case 'png':
                return imagepng($canvas, $dest_image);
            break;
            case 'gif':
                return imagegif($canvas, $dest_image);
            break;
            default:
                // Unsupported format
                return false;
            break;
        }

    } else {
        return false;
    }

}

?>

Example

In its simplest form, you can produce a 64×64 pixel square thumbnail using the following code:

square_crop('full.jpg', 'thumb.jpg');

You can specify any size for thumbnails by passing a third argument. This will generate a 100×100 pixel thumbnail:

square_crop('full.jpg', 'thumb.jpg', 100);

You can also convert between different image formats. The following will produce a JPEG thumbnail from a GIF image:

square_crop('full.gif', 'thumb.jpg');

Sample Outputs

The image will be resized with its edges trimmed into a square:

square_crop_example

If you enjoyed this article, please share it with a friend!

13 Responses to Cropping an Image to Make Square Thumbnails in PHP

  1. Jon Jackson says:

    Thanks for the article Cory. Keep up the good work.

  2. Billy says:

    Excellent, exactly what I need. But it doesn’t work for me. I get this error:
    Warning: preg_replace() [function.preg-replace]: Unknown modifier ‘/’

    Any ideas?

  3. Cory LaViska says:

    @Billy – looks like an escape issue when the article got posted. The regex’s were missing backslashes. The article is fixed now :)

  4. Titi says:

    Exellent function, I was looking for a good way to do the same but finally, I think I’ll choose this one.
    Anyway, in your function, when you check if the image is either landscape or portrait, you define a $square_size variable by using the previous $x_offset (resp. $y_offset) one ; but the only thing you want to do is to crop the image so that the final one is a square one, so you can use the $image[1] (resp. $image[0]) to do exactly the same (i.e. “$image[0] – ($x_offset * 2) = $image[1]“).
    Much easier I think ;)

  5. Vivekanand says:

    This has helped me a lot, saved lot of my time. Thank you very much for the effort and for spending time for us.

    Thanks,
    Vivek
    [http://www.developersnippets.com]

  6. Sergio Vilar says:

    Hi, this is a exelent function.
    This help me a lot.

    I spent months looking for something like this in Portuguese, because I am Brazilian, but not found.

    In addition, it is my thank you for providing this function for us.

    Thanks a lot!

  7. ilyasishak says:

    dear Cory,

    thank you for writing this good function. it helps me a lot.

    good job!

  8. Tom says:

    if the function returns a true or false, how do you get the thumbnail to output on the page? sorry, i’m new at this.

  9. Cory LaViska says:

    @Tom: The function produces a file based on $dest_image. If it returns true, the image has been created; otherwise it will be false.

    You can either use header() and readfile() to display it, or simply link to it with (if it’s in a web accessible location).

  10. Talenz says:

    we are using this for the cropping of images to square. this is useful.

    initially, we tried using thumbnail resizer, but it didnt work. But, this code seems to be better!

  11. Paul says:

    Thanks a lot – your function is very useful, portable and well-written… you’ve saved me some time.

  12. Snowcore says:

    Nice function, thanks!
    What about cropping image to square with rounded corners?

  13. McCrae says:

    Thanks for the function