3 php gd image image-processing image-resizing
我使用PHP GD库开发了一个图像大小调整和修剪类.我使用了skibulks图像修剪脚本来修剪第一步中的图像背景,并将第二步中的图像缩放到所需的尺寸(保持原始比例).
问题:imagecopy
从$this->_trimBackground()
功能中获取新修剪的图像尺寸后,是否真的有必要完成第一项工作,以便使用新的修剪尺寸重新创建图像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;
}
Run Code Online (Sandbox Code Playgroud)
功能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);
}
Run Code Online (Sandbox Code Playgroud)
imagecopy()将$ gdImage的一部分复制到$ gdTrimmed,稍后几行用$ gdTrimmed覆盖$ gdImage.
是否真的有必要进行第一次图像复制?
这是你应该问自己的事情.
使用imagedestroy()
函数而不是unset()
可能会大大提高您的性能.这是对imagedestroy()的有用评论:
重用图像变量不会清除旧数据的内存!您必须使用imagedestroy()来清除数据.(我不知道unset()是否也能正常工作).
另请注意,内存中的图像数据是原始的,因此请不要根据压缩图像的原始文件大小(例如jpeg或png)确定使用的内存量.