Cropping Image to Square Dimension Using PHP

July 1st, 2010 by aditia rahman / 2 Comments  

     

When I wrote my previous post about creating image gallery with codeigniter, I browse some popular image sharing service, and I spent most of my time in flickr, till now I think flickr is still the best photo sharing on the net, when we search on flickr, there are many result that displayed only the thumbnail photo, for example you can see on the screen that I captured

Search Home Design On Flickr.com

You can see above the thumbnail size between each image is different (the thumbnail in my previous post is based on this search) and it depend on image resolution that uploaded by the user, whether it wide, landscape or square, in codeigniter image manipulation you can easily resizing to this kind of thumbnail just by set the “maintain_ratio” in the config options. Now back to flickr.com, when you see a thumbnail in the user sets, you can see the thumbnail are very tidy because all the resolution are the in same size (in flickr it resized and cropped to 75 x 75 pixels), like in the image below

Flickr.com Users Sets

So if we want to create thumbnail like this, first we have to resize the image then crop it, … haha not really that simple right? Here my though, the easier case is the square one, when user uploaded the image the script have to check wheter the image is wide, landscape or square, for wide or landscape image first we have to resize with maintain ratio to minimum value between width and height. Then Crop the bigger size wheter it the width or the height. Let see an example:

We want to upload the 200 x 400 pixels and create the 100 x 100 pixels thumbnail,

  1. First upload the image, and put the original image on the server
  2. Get the uploaded image width and height
  3. Check whether the width is longer that the height
  4. Resize the image with maintained ratio to 100 x 200 pixels
  5. Then we have to crop from the top  image and start in coordinate (0, 50), this usually written in x,y symbols

Yup pretty simple, now simple the implementation in the PHP code, in this code I assume the image is already placed on the server, so it will make the easier to locate the image, in the code below we create the thumbnail with maintained ratio, then create we create the second thumbnail that overwrite the first thumbnail that has been resized to the square that we desired, you can copy all this code and try on your local server, and just change the $path and $img variable that you want to test

<?php

header("Content-type: image/jpeg");

// get the image source
$path = "img/";
$img = "img_wide.jpg";
$img_src = imagecreatefromjpeg($path.$img);
$img_width = imagesx($img_src);
$img_height = imagesy($img_src);

$square_size = 100;

// check width, height, or square
if ($img_width == $img_height) {
    // square
    $tmp_width = $square_size;
    $tmp_height = $square_size;
} else if ($img_height < $img_width) {
    // wide
    $tmp_height = $square_size;
    $tmp_width = intval(($img_width / $img_height) * $square_size);
    if ($tmp_width % 2 != 0) {
        $tmp_width++;
    }
} else if ($img_height > $img_width) {
    $tmp_width = $square_size;
    $tmp_height = intval(($img_height / $img_width) * $square_size);
    if ($tmp_height % 2 != 0) {
        $tmp_height++;
    }
}

$img_new = imagecreatetruecolor($tmp_width, $tmp_height);
imagecopyresampled($img_new, $img_src, 0, 0, 0, 0,
        $tmp_width, $tmp_height, $img_width, $img_height);

// create temporary thumbnail and locate on the server
$thumb = "thumb_".$img;
imagejpeg($img_new, $path.$thumb);

// get tmp_image
$img_thumb_square = imagecreatefromjpeg($path.$thumb);
$thumb_width = imagesx($img_thumb_square);
$thumb_height = imagesy($img_thumb_square);

if ($thumb_height < $thumb_width) {
    // wide
    $x_src = ($thumb_width - $square_size) / 2;
    $y_src = 0;
    $img_final = imagecreatetruecolor($square_size, $square_size);
    imagecopy($img_final, $img_thumb_square, 0, 0,
            $x_src, $y_src, $square_size, $square_size);
    imagejpeg($img_final, $path.$thumb);
} else if ($thumb_height > $thumb_width) {
    // landscape
    $x_src = 0;
    $y_src = ($thumb_height - $square_size) / 2;
    $img_final = imagecreatetruecolor($square_size, $square_size);
    imagecopy($img_final, $img_thumb_square, 0, 0,
            $x_src, $y_src, $square_size, $square_size);
    imagejpeg($img_final, $path.$thumb);
} else {
    $img_final = imagecreatetruecolor($square_size, $square_size);
    imagecopy($img_final, $img_thumb_square, 0, 0,
            0, 0, $square_size, $square_size);
}

imagejpeg($img_final);

?>
        submit to reddit Delicious

2 Comments Leave a Comment Subscribe RSS

Leave a Comment