Page 1 of 1

My Resize and Move Image Function + Smart Cropping

Posted: Fri Nov 21, 2008 10:21 pm
by volomike
Here's a snippet to enjoy.

This is my resize and move image function, and includes smart cropping. Its goal is to make portrait-style images out of any given image size. Basically it figures out if the uploaded image is:

- portrait-ish
- square-ish
- rectangle-ish

If the image is portrait-ish in shape, it just resamples to the new width and height.

If the image is rectangle-ish (landscape) in shape, it trims off 1/5 of each side and resamples to the new width and height.

If the image is square-ish in shape, it trims off 1/6 of each side and resamples to the new width and height.

I call this "smart cropping".

It requires the GD library to be installed in your PHP. I tested on Linux. Your mileage on other OSes may vary.

Usually when you have an uploaded image, it sits in the /tmp folder, so our input image would be that, and our output image is $sNewPathAndFileName. The $nQualityPercentage should probably be around 85 to 100. (I stick with 90.)

You probably have a different variable naming and function naming convention. Oh well.

The routine returns TRUE if all went well.

Room for improvement is probably to make some kind of setting where one can choose whether they want the destination to be portrait-ish, square-ish, or rectangle-ish (longer width, I mean). For now, I just stuck with portrait-ish.

Code: Select all

public static function ResizeAndMoveImage($sTempPathAndFileName, $sNewPathAndFileName, $nWidth, $nHeight, $nQualityPercentage) {
        // comes from volomike.com, v1.0, Nov 21, 2008
    $sTemp = $sTempPathAndFileName;
    $sNew = $sNewPathAndFileName;
    $nQuality = $nQualityPercentage;
    $hSource = imagecreatefromjpeg($sTemp);
    if ($hSource === FALSE) {
        return FALSE;
    }
    list($nOldWidth,$nOldHeight)=getimagesize($sTemp);
    // DETERMINE IF IMAGE IS SQUARE-ISH, RECTANGLE-ISH, OR CONSIDERED PORTRAIT-ISH
    // NOTE: THIS IS AN IMPERFECT ALGORITHM, BUT SORT OF WORKS
    $w = $nOldWidth;
    $h = $nOldHeight;
    $m = ceil($w / 10);
    if ($w == $h) {
        $sShape = 'square-ish';
    } else if ( ( ($w - $m) >= $h ) and ( ($w - $m) <= ($h + $m) ) ) {
        $sShape = 'square-ish';
    } else if ( ( ($w + $m) >= $h ) and ( ($w + $m) <= ($h + $m) ) ) {
        $sShape = 'square-ish';
    } else if ( ( ($h - $m) >= $w ) and ( ($h - $m) <= ($w + $m) ) ) {
        $sShape = 'square-ish';
    } else if ( ( ($h + $m) >= $w ) and ( ($h + $m) <= ($w + $m) ) ) {
        $sShape = 'square-ish';
    } else if ($w > $h) {
        if (($w/2) + ($w/3) >= $h) {
            $sShape = 'rectangle-ish';
        } else {
            $sShape = 'square-ish';
        }
    } else {
        $sShape = 'portrait-ish';
    }
    $nOffsetX = 0;
    $nOffsetY = 0;
    // IF SQUARE-ISH, THEN CHOP OFF 1/6 ON LEFT AND 1/6 ON RIGHT
    if ($sShape == 'square-ish') {
        $m = ceil($w / 6);
        $nOffsetX += $m;
        $nOldWidth -= ($m * 2);
    }
    // IF RECTANGLE-ISH, THEN CHOP OFF 1/5 ON LEFT AND 1/5 ON RIGHT
    if ($sShape == 'rectangle-ish') {
        $m = ceil($w / 5);
        $nOffsetX += $m;
        $nOldWidth -= ($m * 2);
    }
    $hNewTemp=imagecreatetruecolor($nWidth,$nHeight);
    if ($hNewTemp === FALSE) {
        return FALSE;
    }
    if (!imagecopyresampled($hNewTemp,$hSource,0,0,$nOffsetX,$nOffsetY,$nWidth,$nHeight,$nOldWidth,$nOldHeight)) {
        return FALSE;
    }
    if (!imagejpeg($hNewTemp,$sNew,$nQuality)) {
        return FALSE;
    }
    @ imagedestroy($hSource);
    @ imagedestroy($hNewTemp);
    return TRUE;
}
I hope this helps a lot of people out there!