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程序设计有所帮助