3

我使用 PHP GD 库开发了一个图像大小调整和修剪类。我在第一步中使用skibulks图像修剪脚本来修剪图像背景,并在第二步中将图像缩放到需要的大小(保持原始比例)。

问题:是否真的有必要在imagecopy从函数中获取新的修剪后的图像尺寸后执行第一项工作,以首先使用新的修剪后的尺寸$this->_trimBackground()重新创建图像imagecopy(然后再次调整其大小)? 或者,是否可以将此作业与以下调整大小部分合并imagecopyresampled

我不知道还有其他可能的性能改进吗?欢迎提出任何性能建议!

功能一:

/**
 * 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;

}

功能二:

/**
 * 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);

}
4

1 回答 1

5

imagecopy() 将你的 $gdImage 的一部分复制到 $gdTrimmed,几行之后用 $gdTrimmed 覆盖 $gdImage。

真的有必要做第一个图像复制吗?

这是你应该问自己的事情。

使用imagedestroy()函数代替unset()可能会大大提高您的性能。这是对imagedestroy()的有用评论:

重用图像变量不会清除内存中的旧数据!您必须使用 imagedestroy() 清除数据。(我不知道 unset() 是否也有效)。

另请注意,内存中的图像数据是原始数据,因此不要根据压缩图像的原始文件大小(例如 jpeg 或 png)来确定您使用的内存量。

于 2013-02-08T09:35:58.690 回答