PHP GD performance improvements resize and crop the background of the image, keeping the correct aspect ratio

I have developed an image resizing and cropping class using the PHP GD library. I used the skibulks image trim script to crop the background of the image in the first step and scale the image in the second step to the required dimensions (while maintaining the original ratio).

Question: Is it really necessary to do the first task imagecopy

after getting the new cropped sizes from the function $this->_trimBackground()

to recreate the image first with the imagecopy

new cropped dimensions (and resize it again)? Or , is it possible to combine this assignment with the next resizing part imagecopyresampled

?

Are there any other possible performance improvements that I'm not aware of? Every job offer is welcome!

Function 1:

/**
 * Resize image file
 * 
 * @param   string $filepath the image filepath
 * @param   integer $width the width to resize
 * @param   integer $height the height to resize
 * @return  (image blob|boolean status)
 * @throws  Asset_Model_Image_Exception
 */
private function _resizeImageByFilepathAndReturn($filepath, $width, $height) {

    list($imageWidth, $imageHeight, $imageType) = getimagesize($filepath);

   switch($imageType) {
    case IMAGETYPE_GIF:
            $gdImage = imagecreatefromgif($filepath);
            break;
      case IMAGETYPE_JPEG:
            $gdImage = imagecreatefromjpeg($filepath);
            break;
      case IMAGETYPE_PNG:
            $gdImage = imagecreatefrompng($filepath);
            break;
      default:
                return false;
   }

   if($box = $this->_trimBackground($gdImage)) {

    $gdTrimmed = imagecreatetruecolor($box['w'], $box['h']);
    imagecopy($gdTrimmed, $gdImage, 0, 0, $box['l'], $box['t'], $box['w'], $box['h']);

    $imageWidth = $box['w'];
    $imageHeight = $box['h'];
    $gdImage = $gdTrimmed;

    unset($gdTrimmed);

   }

   if($imageWidth <= $width && $imageHeight <= $height) {

    $fwidth = $imageWidth;
        $fheight = $imageHeight;

   } else {

        $wscale = $width / $imageWidth;
        $hscale = $height / $imageHeight;
        $scale = min($wscale, $hscale);
        $fwidth = $scale * $imageWidth;
        $fheight = $scale * $imageHeight;

   }

   $gdThumbnail = imagecreatetruecolor($width, $height);

   imagefill($gdThumbnail, 0, 0, 0x00FFFFFF);

   imagecopyresampled($gdThumbnail, $gdImage, ($width - $fwidth) / 2, ($height - $fheight) / 2, 0, 0, $fwidth, $fheight, $imageWidth, $imageHeight);

   ob_start();
   imagejpeg($gdThumbnail, null, 90);
   $image = ob_get_contents();
   ob_end_clean();

   imagedestroy($gdImage);
   imagedestroy($gdThumbnail);

   return $image;

}

      

Function 2:

/**
 * Trim image background
 * 
 * @param $gdImage image ressource
 */
private function _trimBackground($gdImage){

    $hex = imagecolorat($gdImage, 0,0);

    $width = imagesx($gdImage);
    $height = imagesy($gdImage);

    $bTop = 0;
    $bLft = 0;
    $bBtm = $height - 1;
    $bRt = $width - 1;

    for(; $bTop < $height; ++$bTop) {
        for($x = 0; $x < $width; ++$x) {
            if(imagecolorat($gdImage, $x, $bTop) != $hex) {
                break 2;
            }
        }
    }

    if($bTop == $height) {
        return false;
    }

    for(; $bBtm >= 0; --$bBtm) {
        for($x = 0; $x < $width; ++$x) {
            if(imagecolorat($gdImage, $x, $bBtm) != $hex) {
                break 2;
            }
        }
    }

    for(; $bLft < $width; ++$bLft) {
        for($y = $bTop; $y <= $bBtm; ++$y) {
            if(imagecolorat($gdImage, $bLft, $y) != $hex) {
                break 2;
            }
        }
    }

    for(; $bRt >= 0; --$bRt) {
        for($y = $bTop; $y <= $bBtm; ++$y) {
            if(imagecolorat($gdImage, $bRt, $y) != $hex) {
                break 2;
            }
        }
    }

    $bBtm++;
    $bRt++;

    return array('l' => $bLft, 't' => $bTop, 'r' => $bRt, 'b' => $bBtm, 'w' => $bRt - $bLft, 'h' => $bBtm - $bTop);

}

      

+3


source to share


1 answer


imagecopy () copies the section of your $ gdImage to $ gdTrimmed, and a few lines later overwrites $ gdImage with $ gdTrimmed.

Do you really need to do the first imagecopy?

This is what you need to ask yourself.



Using a function imagedestroy()

instead unset()

can greatly improve your productivity. Here's a helpful comment by imagedestroy () :

Reusing an image variable does NOT clear old data from memory! You have to use imagedestroy () to clear the data. (I don't know if unset () also works).

Also note that the image data in memory is raw, so don't base how much memory you are using based on the original compressed image format (like jpeg or png).

+5


source







All Articles