>我使用PHP GD库开发了一个图像大小调整和修剪类。我在第一步中使用 skibulks 图像修剪脚本修剪图像背景,并在第二步中将图像缩放到所需的大小(保持原始比例)。
问题:从$this->_trimBackground()
函数获取新的修剪图像大小后,是否真的有必要imagecopy
先通过imagecopy
新的修剪大小来重新创建图像(然后再次调整大小)? 或者,是否可以将此作业与以下调整大小的部分合并imagecopyresampled
?
是否有其他可能的性能改进,但我不知道? 欢迎提出任何性能建议!
功能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;
}
功能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);
}
imagecopy() 将$gdImage的一部分复制到$gdTrimmed,几行之后用$gdTrimmed覆盖$gdImage。
真的有必要做第一个图像复制吗?
这是你应该问自己的问题。
使用imagedestroy()
函数而不是unset()
可能会大大提高您的性能。这里有一个关于 imagedestroy() 的有用评论:
重用图像变量不会清除内存中的旧数据! 您必须使用 imagedestroy() 来清除数据。 (我不知道是否 unset() 也可以)。
另请注意,内存中的图像数据是原始的,因此不要基于多少 您正在使用的内存基于压缩的原始文件大小 图像(例如 JPEG 或 PNG)。