php实现的支持imagemagick及gd库两种处理的缩略图生成类
本文实例讲述了php实现的支持imagemagick及gd库两种处理的缩略图生成类及其用法实例,非常具有实用价值。分享给大家供大家参考。具体如下:
一、功能:
1.按比例缩小/放大
2.填充背景色
3.按区域裁剪
4.添加水印,包括水印的位置,透明度等
使用imagemagick/GD库实现,imagemagick地址:www.imagemagick.org
需要安装imagemagick,安装方法如下:https://www.nhooo.com/article/55528.htm
二、实现方法:
PicThumb.class.php类文件如下:
<?php /**缩略图生成类,支持imagemagick及gd库两种处理 *Date:2013-07-15 *Author:fdipzone *Ver:1.2 * *Func: *publicset_config:设置参数 *publiccreate_thumb:生成缩略图 *privatefit:缩略图片 *privatecrop:裁剪图片 *privategd_fit:GD库缩略图片 *privategd_crop:GD库裁剪图片 *privateget_size:获取要转换的size *privateget_crop_offset:获取裁图的偏移量 *privateadd_watermark:添加水印 *privatecheck_handler:判断处理程序是否已安装 *privatecreate_dirs:创建目录 *privateexists:判断参数是否存在 *privateto_log:记录log *privatehex2rgb:hex颜色转rgb颜色 *privateget_file_ext:获取图片类型 * *ver:1.1增加GD库处理 *ver:1.2增加width,height错误参数处理 *增加当图片colorspace不为RGB时作转RGB处理 *修正使用crop保存为gif时出现透明无效区域问题,使用+repage参数,删除透明无效区域即可 * *tips:建议使用imagemagick *GD库不支持透明度水印,如果必须使用透明水印,请将水印图片做成有透明度。 *GD库输出gif如加透明水印,会有问题。 */ classPicThumb{//classstart private$_log=null;//logfile private$_handler=null;//进行图片处理的程序,imagemagick/gd库 private$_type='fit';//fitorcrop private$_source=null;//原图路径 private$_dest=null;//缩略图路径 private$_watermark=null;//水印图片 private$_opacity=75;//水印圖片透明度,gd库不支持 private$_gravity='SouthEast';//水印摆放位置NorthWest,North,NorthEast,West,Center,East,SouthWest,South,SouthEast private$_geometry='+10+10';//水印定位,gd库不支持 private$_croppos='TL';//截图的位置TLTMTRMLMMMRBLBMBR private$_bgcolor=null;//填充的背景色 private$_quality=90;//生成的图片质量 private$_width=null;//指定区域宽度 private$_height=null;//指定区域高度 //初始化 publicfunction__construct($logfile=''){ if($logfile!=''){ $this->_log=$logfile; } } //设置参数 publicfunctionset_config($param=array()){ $this->_handler=$this->exists($param,'handler')?strtolower($param['handler']):null; $this->_type=$this->exists($param,'type')?strtolower($param['type']):'fit'; $this->_watermark=$this->exists($param,'watermark')?$param['watermark']:null; $this->_opacity=$this->exists($param,'opacity')?$param['opacity']:75; $this->_gravity=$this->exists($param,'gravity')?$param['gravity']:'SouthEast'; $this->_geometry=$this->exists($param,'geometry')?$param['geometry']:'+10+10'; $this->_croppos=$this->exists($param,'croppos')?$param['croppos']:'TL'; $this->_bgcolor=$this->exists($param,'bgcolor')?$param['bgcolor']:null; $this->_quality=$this->exists($param,'quality')?$param['quality']:90; $this->_width=$this->exists($param,'width')?$param['width']:null; $this->_height=$this->exists($param,'height')?$param['height']:null; } /**创建缩略图 *@paramString$source原图 *@paramString$dest目标图 *@returnboolean */ publicfunctioncreate_thumb($source,$dest){ //检查使用的handler是否已安装 if(!$this->check_handler()){ $this->to_log('handlernotinstalled'); returnfalse; } //判断区域宽高是否正确 if(!is_numeric($this->_width)||!is_numeric($this->_height)||$this->_width<=0||$this->_height<=0){ $this->to_log('widthorheightinvalid'); returnfalse; } //判断源文件是否存在 if(!file_exists($source)){ $this->to_log($source.'notexists'); returnfalse; } //创建目标文件路径 if(!$this->create_dirs($dest)){ $this->to_log(dirname($dest).'createfail'); returnfalse; } $this->_source=$source;//源文件 $this->_dest=$dest;//目标文件 //处理图片 switch($this->_type){ case'fit': if($this->_handler=='imagemagick'){ return$this->fit(); }else{ return$this->gd_fit(); } break; case'crop': if($this->_handler=='imagemagick'){ return$this->crop(); }else{ return$this->gd_crop(); } break; default: $this->to_log($this->_type.'notfitandcrop'); returnfalse; } } /**按比例压缩或拉伸图片 *@returnboolean */ privatefunctionfit(){ //判断是否填充背景 $bgcolor=($this->_bgcolor!=null)? sprintf("-background'%s'-gravitycenter-extent'%sx%s'",$this->_bgcolor,$this->_width,$this->_height):""; //判断是否要转为RGB $source_info=getimagesize($this->_source); $colorspace=(!isset($source_info['channels'])||$source_info['channels']!=3)?'-colorspaceRGB':''; //命令行 $cmd=sprintf("convert-resize'%sx%s''%s'%s-quality%s%s'%s'",$this->_width,$this->_height,$this->_source,$bgcolor,$this->_quality,$colorspace,$this->_dest); //记录执行的命令 $this->to_log($cmd); //执行命令 exec($cmd); //添加水印 $this->add_watermark($this->_dest); returnis_file($this->_dest)?true:false; } /**裁剪图片 *@returnboolean */ privatefunctioncrop(){ //获取生成的图片尺寸 list($pic_w,$pic_h)=$this->get_size(); //获取截图的偏移量 list($offset_w,$offset_h)=$this->get_crop_offset($pic_w,$pic_h); //判断是否要转为RGB $source_info=getimagesize($this->_source); $colorspace=(!isset($source_info['channels'])||$source_info['channels']!=3)?'-colorspaceRGB':''; //命令行 $cmd=sprintf("convert-resize'%sx%s''%s'-quality%s%s-crop%sx%s+%s+%s+repage'%s'",$pic_w,$pic_h,$this->_source,$this->_quality,$colorspace,$this->_width,$this->_height,$offset_w,$offset_h,$this->_dest); //记录执行的命令 $this->to_log($cmd); //执行命令 exec($cmd); //添加水印 $this->add_watermark($this->_dest); returnis_file($this->_dest)?true:false; } /**GD库按比例压缩或拉伸图片 *@returnboolean */ privatefunctiongd_fit(){ //获取生成的图片尺寸 list($pic_w,$pic_h)=$this->get_size(); list($owidth,$oheight,$otype)=getimagesize($this->_source); switch($otype){ case1:$source_img=imagecreatefromgif($this->_source);break; case2:$source_img=imagecreatefromjpeg($this->_source);break; case3:$source_img=imagecreatefrompng($this->_source);break; default:returnfalse; } //按比例缩略/拉伸图片 $new_img=imagecreatetruecolor($pic_w,$pic_h); imagecopyresampled($new_img,$source_img,0,0,0,0,$pic_w,$pic_h,$owidth,$oheight); //判断是否填充背景 if($this->_bgcolor!=null){ $bg_img=imagecreatetruecolor($this->_width,$this->_height); $rgb=$this->hex2rgb($this->_bgcolor); $bgcolor=imagecolorallocate($bg_img,$rgb['r'],$rgb['g'],$rgb['b']); imagefill($bg_img,0,0,$bgcolor); imagecopy($bg_img,$new_img,(int)(($this->_width-$pic_w)/2),(int)(($this->_height-$pic_h)/2),0,0,$pic_w,$pic_h); $new_img=$bg_img; } //获取目标图片的类型 $dest_ext=$this->get_file_ext($this->_dest); //生成图片 switch($dest_ext){ case1:imagegif($new_img,$this->_dest,$this->_quality);break; case2:imagejpeg($new_img,$this->_dest,$this->_quality);break; case3:imagepng($new_img,$this->_dest,(int)(($this->_quality-1)/10));break; } if(isset($source_img)){ imagedestroy($source_img); } if(isset($new_img)){ imagedestroy($new_img); } //添加水印 $this->add_watermark($this->_dest); returnis_file($this->_dest)?true:false; } /**GD库裁剪图片 *@returnboolean */ privatefunctiongd_crop(){ //获取生成的图片尺寸 list($pic_w,$pic_h)=$this->get_size(); //获取截图的偏移量 list($offset_w,$offset_h)=$this->get_crop_offset($pic_w,$pic_h); list($owidth,$oheight,$otype)=getimagesize($this->_source); switch($otype){ case1:$source_img=imagecreatefromgif($this->_source);break; case2:$source_img=imagecreatefromjpeg($this->_source);break; case3:$source_img=imagecreatefrompng($this->_source);break; default:returnfalse; } //按比例缩略/拉伸图片 $tmp_img=imagecreatetruecolor($pic_w,$pic_h); imagecopyresampled($tmp_img,$source_img,0,0,0,0,$pic_w,$pic_h,$owidth,$oheight); //裁剪图片 $new_img=imagecreatetruecolor($this->_width,$this->_height); imagecopyresampled($new_img,$tmp_img,0,0,$offset_w,$offset_h,$this->_width,$this->_height,$this->_width,$this->_height); //获取目标图片的类型 $dest_ext=$this->get_file_ext($this->_dest); //生成图片 switch($dest_ext){ case1:imagegif($new_img,$this->_dest,$this->_quality);break; case2:imagejpeg($new_img,$this->_dest,$this->_quality);break; case3:imagepng($new_img,$this->_dest,(int)(($this->_quality-1)/10));break; } if(isset($source_img)){ imagedestroy($source_img); } if(isset($tmp_img)){ imagedestroy($tmp_img); } if(isset($new_img)){ imagedestroy($new_img); } //添加水印 $this->add_watermark($this->_dest); returnis_file($this->_dest)?true:false; } /**获取目标图生成的size *@returnArray$width,$height */ privatefunctionget_size(){ list($owidth,$oheight)=getimagesize($this->_source); $width=(int)($this->_width); $height=(int)($this->_height); switch($this->_type){ case'fit': $pic_w=$width; $pic_h=(int)($pic_w*$oheight/$owidth); if($pic_h>$height){ $pic_h=$height; $pic_w=(int)($pic_h*$owidth/$oheight); } break; case'crop': if($owidth>$oheight){ $pic_h=$height; $pic_w=(int)($pic_h*$owidth/$oheight); }else{ $pic_w=$width; $pic_h=(int)($pic_w*$oheight/$owidth); } break; } returnarray($pic_w,$pic_h); } /**获取截图的偏移量 *@paramint$pic_w图宽度 *@paramint$pic_h图高度 *@returnArray$offset_w,$offset_h */ privatefunctionget_crop_offset($pic_w,$pic_h){ $offset_w=0; $offset_h=0; switch(strtoupper($this->_croppos)){ case'TL': $offset_w=0; $offset_h=0; break; case'TM': $offset_w=(int)(($pic_w-$this->_width)/2); $offset_h=0; break; case'TR': $offset_w=(int)($pic_w-$this->_width); $offset_h=0; break; case'ML': $offset_w=0; $offset_h=(int)(($pic_h-$this->_height)/2); break; case'MM': $offset_w=(int)(($pic_w-$this->_width)/2); $offset_h=(int)(($pic_h-$this->_height)/2); break; case'MR': $offset_w=(int)($pic_w-$this->_width); $offset_h=(int)(($pic_h-$this->_height)/2); break; case'BL': $offset_w=0; $offset_h=(int)($pic_h-$this->_height); break; case'BM': $offset_w=(int)(($pic_w-$this->_width)/2); $offset_h=(int)($pic_h-$this->_height); break; case'BR': $offset_w=(int)($pic_w-$this->_width); $offset_h=(int)($pic_h-$this->_height); break; } returnarray($offset_w,$offset_h); } /**添加水印 *@paramString$dest图片路径 */ privatefunctionadd_watermark($dest){ if($this->_watermark!=null&&file_exists($this->_watermark)&&file_exists($dest)){ list($owidth,$oheight,$otype)=getimagesize($dest); list($w,$h,$wtype)=getimagesize($this->_watermark); //水印图比原图要小才加水印 if($w<=$owidth&&$h<=$oheight){ if($this->_handler=='imagemagick'){//imagemagick添加水印 $cmd=sprintf("composite-gravity%s-geometry%s-dissolve%s'%s'%s%s",$this->_gravity,$this->_geometry,$this->_opacity,$this->_watermark,$dest,$dest); $this->to_log($cmd); exec($cmd); }else{//gd添加水印 switch($wtype){ case1:$water_img=imagecreatefromgif($this->_watermark);break; case2:$water_img=imagecreatefromjpeg($this->_watermark);break; case3:$water_img=imagecreatefrompng($this->_watermark);break; default:returnfalse; } switch($otype){ case1:$dest_img=imagecreatefromgif($dest);break; case2:$dest_img=imagecreatefromjpeg($dest);break; case3:$dest_img=imagecreatefrompng($dest);break; default:returnfalse; } //水印位置 switch(strtolower($this->_gravity)){ case'northwest': $posX=0; $posY=0; break; case'north': $posX=($owidth-$w)/2; $posY=0; break; case'northeast': $posX=$owidth-$w; $posY=0; break; case'west': $posX=0; $posY=($oheight-$h)/2; break; case'center': $posX=($owidth-$w)/2; $posY=($oheight-$h)/2; break; case'east': $posX=$owidth-$w; $posY=($oheight-$h)/2; break; case'southwest': $posX=0; $posY=$oheight-$h; break; case'south': $posX=($owidth-$w)/2; $posY=$oheight-$h; break; case'southeast': $posX=$owidth-$w; $posY=$oheight-$h; break; } imagealphablending($dest_img,true); imagecopy($dest_img,$water_img,$posX,$posY,0,0,$w,$h); switch($otype){ case1:imagegif($dest_img,$dest,$this->_quality);break; case2:imagejpeg($dest_img,$dest,$this->_quality);break; case3:imagepng($dest_img,$dest,(int)(($this->_quality-1)/10));break; } if(isset($water_img)){ imagedestroy($water_img); } if(isset($dest_img)){ imagedestroy($dest_img); } } } } } /**判断处理程序是否已安装 *@returnboolean */ privatefunctioncheck_handler(){ $handler=$this->_handler; if(!in_array($handler,array('imagemagick','gd',null))){ returnfalse; } //检查是否有安装imagemagick $imagemagick_installed=strstr(shell_exec('convert-version'),'Version:ImageMagick')!=''?true:false; //检查是否有安装gd库 $gd_installed=function_exists('gd_info')?true:false; switch($handler){ case'imagemagick': return$imagemagick_installed; break; case'gd': return$gd_installed; break; casenull: if($imagemagick_installed){ $this->_handler='imagemagick'; returntrue; } if($gd_installed){ $this->_handler='gd'; returntrue; } break; } returnfalse; } /**创建图片目录 *@paramString$path *@returnboolean */ privatefunctioncreate_dirs($dest){ if(!is_dir(dirname($dest))){ returnmkdir(dirname($dest),0777,true); } returntrue; } /**判断参数是否存在 *@paramArray$obj数组对象 *@paramString$key要查找的key *@returnboolean */ privatefunctionexists($obj,$key=''){ if($key==''){ returnisset($obj)&&!empty($obj); }else{ $keys=explode('.',$key); for($i=0,$max=count($keys);$i<$max;$i++){ if(isset($obj[$keys[$i]])){ $obj=$obj[$keys[$i]]; }else{ returnfalse; } } returnisset($obj)&&!empty($obj); } } /**记录log *@paramString$msg要记录的log讯息 */ privatefunctionto_log($msg){ if($this->_log){ $msg='['.date('Y-m-dH:i:s').']'.$msg."\r\n"; file_put_contents($this->_log,$msg,FILE_APPEND); } } /**hex颜色转rgb颜色 *@paramString$colorhex颜色 *@returnArray */ privatefunctionhex2rgb($hexcolor){ $color=str_replace('#','',$hexcolor); if(strlen($color)>3){ $rgb=array( 'r'=>hexdec(substr($color,0,2)), 'g'=>hexdec(substr($color,2,2)), 'b'=>hexdec(substr($color,4,2)) ); }else{ $r=substr($color,0,1).substr($color,0,1); $g=substr($color,1,1).substr($color,1,1); $b=substr($color,2,1).substr($color,2,1); $rgb=array( 'r'=>hexdec($r), 'g'=>hexdec($g), 'b'=>hexdec($b) ); } return$rgb; } /**获取图片类型 *@paramString$file图片路径 *@returnint */ privatefunctionget_file_ext($file){ $filename=basename($file); list($name,$ext)=explode('.',$filename); $ext_type=0; switch(strtolower($ext)){ case'jpg': case'jpeg': $ext_type=2; break; case'gif': $ext_type=1; break; case'png': $ext_type=3; break; } return$ext_type; } }//classend ?>
demo示例代码如下:
<?php define('ROOT',dirname(__FILE__)); require(ROOT."/PicThumb.class.php"); $logfile=ROOT.'/PicThumb.log'; $source1=ROOT.'/pic/source.jpg'; $dest1=ROOT.'/pic/1.jpg'; $dest2=ROOT.'/pic/2.gif'; $dest3=ROOT.'/pic/3.png'; $source2=ROOT.'/pic/source_cmyk.jpg'; $dest4=ROOT.'/pic/4.jpg'; $dest5=ROOT.'/pic/5.gif'; $dest6=ROOT.'/pic/6.png'; $watermark=ROOT.'/pic/watermark.png'; //按比例生成缩略图 $param=array( 'type'=>'fit', 'width'=>100, 'height'=>100, ); $obj=newPicThumb($logfile); $obj->set_config($param); $flag=$obj->create_thumb($source1,$dest1); if($flag){ echo'<imgsrc="pic/'.basename($dest1).'">'; }else{ echo'createthumbfail'; } //按比例生成缩略图,不足部分用#FF0000填充 $param=array( 'type'=>'fit', 'width'=>100, 'height'=>100, 'bgcolor'=>'#FFFF00' ); $obj=newPicThumb($logfile); $obj->set_config($param); $flag=$obj->create_thumb($source1,$dest2); if($flag){ echo'<imgsrc="pic/'.basename($dest2).'">'; }else{ echo'createthumbfail'; } //裁剪250x250的缩略图,裁剪位置是底部中间,水印位置西南,透明度50 $param=array( 'type'=>'crop', 'croppos'=>'BM', 'width'=>250, 'height'=>250, 'watermark'=>$watermark, 'opacity'=>50, 'gravity'=>'SouthWest' ); $obj=newPicThumb($logfile); $obj->set_config($param); $flag=$obj->create_thumb($source1,$dest3); if($flag){ echo'<imgsrc="pic/'.basename($dest3).'">'; }else{ echo'createthumbfail'; } //按比例生成缩略图CMYK格式 $param=array( 'type'=>'fit', 'width'=>100, 'height'=>100, ); $obj=newPicThumb($logfile); $obj->set_config($param); $flag=$obj->create_thumb($source2,$dest4); if($flag){ echo'<imgsrc="pic/'.basename($dest4).'">'; }else{ echo'createthumbfail'; } //按比例生成缩略图,不足部分用#FF0000填充CMYK格式 $param=array( 'type'=>'fit', 'width'=>100, 'height'=>100, 'bgcolor'=>'#FFFF00' ); $obj=newPicThumb($logfile); $obj->set_config($param); $flag=$obj->create_thumb($source2,$dest5); if($flag){ echo'<imgsrc="pic/'.basename($dest5).'">'; }else{ echo'createthumbfail'; } //裁剪250x250的缩略图,裁剪位置是底部中间,水印位置西南,透明度50CMYK格式 $param=array( 'type'=>'crop', 'croppos'=>'BM', 'width'=>250, 'height'=>250, 'watermark'=>$watermark, 'opacity'=>50, 'gravity'=>'SouthWest' ); $obj=newPicThumb($logfile); $obj->set_config($param); $flag=$obj->create_thumb($source2,$dest6); if($flag){ echo'<imgsrc="pic/'.basename($dest6).'">'; }else{ echo'createthumbfail'; } ?>
本文完整实例代码点击此处本站下载。
希望本文所述对大家的PHP程序设计有所帮助