Php 性能改进:调整和修剪图像背景,保持正确的比例
我使用PHPGD库开发了一个图像大小调整和修剪类。我曾经在第一步修剪图像背景,在第二步将图像缩放到所需的大小(保持原始比例) 问题:从Php 性能改进:调整和修剪图像背景,保持正确的比例,php,image,image-processing,gd,image-resizing,Php,Image,Image Processing,Gd,Image Resizing,我使用PHPGD库开发了一个图像大小调整和修剪类。我曾经在第一步修剪图像背景,在第二步将图像缩放到所需的大小(保持原始比例) 问题:从$this->\u trimbbackground()函数获取新的修剪图像大小后,是否确实需要执行第一个imagecopy作业,首先通过imagecopy使用新的修剪尺寸重新创建图像(然后再次调整大小)或,是否可以将此作业与以下调整大小部分合并imagecopyresampled 是否还有其他我不知道的可能的性能改进?欢迎提出任何性能建议 功能1: /** *
$this->\u trimbbackground()
函数获取新的修剪图像大小后,是否确实需要执行第一个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;
}
/**
* 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);
}
/**
*调整图像文件大小
*
*@param string$filepath图像文件路径
*@param integer$width要调整大小的宽度
*@param integer$height要调整大小的高度
*@return(图像blob |布尔状态)
*@抛出资产\模型\图像\异常
*/
私有函数_resizeImageByFilepathAndReturn($filepath、$width、$height){
列表($imageWidth、$imageHeight、$imageType)=getimagesize($filepath);
开关($imageType){
案例图像类型\u GIF:
$gdImage=imagecreatefromgif($filepath);
打破
case IMAGETYPE_JPEG:
$gdImage=imagecreatefromjpeg($filepath);
打破
案例IMAGETYPE_PNG:
$gdImage=imagecreatefrompng($filepath);
打破
违约:
返回false;
}
如果($box=$this->_trimpbackground($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;
未结算(美元);
}
如果($imageWidth$bTop,'r'=>$bRt,'b'=>$bBtm,'w'=>$bRt-$bLft,'h'=>$bBtm-$bTop);
}
imagecopy()将$gdImage的一部分复制到$gdTrimmed,几行之后会用$gdTrimmed覆盖$gdImage
真的有必要进行第一次图像复制吗
这是你应该问问自己的
使用imagedestroy()
函数而不是unset()
可能会大大提高性能。以下是一条有用的评论:
重复使用图像变量不会清除内存中的旧数据!
必须使用imagedestroy()清除数据。)我不知道
unset()也可以工作)
还要注意的是,内存中的图像数据是原始的,所以不需要计算多少
根据压缩文件的原始文件大小使用的内存
图像(如jpeg或png)
也许是回答这个问题的好地方谢谢你给我的提示jeztah!我也创造了它。你为什么要优化性能?什么?为什么我要优化性能?因为大约有1000万。图像和时间就是金钱?:-)你一定要自己使用GD吗?您有权访问IMagick模块吗?还是访问程序转换?(还有ImageMagick)我敢打赌,使用其中任何一种都会给您带来非常好的性能提升。(我们处理大量这样的图像,由gearman jobqueue支持,并通过几个应用程序服务器进行拆分)非常感谢,使用imagedestroy()将性能提高了40%。