photo.php,EasyPhoto.php

class EasyPhoto{

//所有图层

private $layers=array();

//当前活动图层

private $ActiveLayer;

//对象实例,单实例模式

private static $instance;

private $imageLayers=array();

public function __construct($fileName=null,$options=array()) {

if(!extension_loaded('gd')){

throw new Exception('需要gd库支持!');

}

if(is_file($fileName)){

$this->addLayer($fileName);

}

}

/*

增加一个图像图层

@param mixed $image 加入图片的完整路径

@param int $x 图层的x坐标

@param int $y图层的y坐标

@param string $pos图层的相对位置,默认是LT

C for center L for left R for right B for bottom T for top

可选值:LT|LC|LB|CT|CC|CB|RT|RC|RB

@param int $opacity图层的透明度

*/

public function addLayer($image,$options=array()){

if(is_string($image)){

$imageName=$image;

$this->imageLayers[]=$imageName;

$image=self::createFromImage($image);

}

$defaults=array(

'x'=>0,

'y'=>0,

'pos'=>'LT',

'opacity'=>100

);

$config=array_merge($defaults,$options);

$this->ActiveLayer=array(

'layer'=>$image,

'width'=>imagesx($image),

'height'=>imagesy($image),

'x'=>$config['x'],

'y'=>$config['y'],

'pos'=>$config['pos'],

'opacity'=>$config['opacity']

);

if(isset($imageName)){

$this->ActiveLayer['name']=$imageName;

}

$this->layers[]=$this->ActiveLayer;

return $this;

}

/*

取得所有图层中最大的宽和高

*/

private function getLayersMaxSize(){

$width=array();

$height=array();

foreach ($this->layers as $layer){

$width[]=$layer['width'];

$height[]=$layer['height'];

}

return array('width'=>max($width),'height'=>max($height));

}

/*

合并所有的图层,图层信息会覆盖成合并后的图层信息

*/

public function mergeLayers(){

$dst_layer=array();

$maxSize=$this->getLayersMaxSize();

foreach ($this->layers as $layer){

if(empty($dst_layer)){

$dst_layer=array(

'width'=>$maxSize['width'],

'height'=>$maxSize['height'],

'x'=>0,

'y'=>0,

'pos'=>'LT',

'opacity'=>100

);

$dst_layer['layer']=self::createTransparentBg($maxSize['width'],$maxSize['height']);

}

$realPosition=self::getRealPosition($maxSize['width'],$maxSize['height'],$layer);

imagecopymerge($dst_layer['layer'], $layer['layer'], $realPosition['x'], $realPosition['y'], 0, 0, $layer['width'], $layer['height'], $layer['opacity']);

}

$this->ActiveLayer=$dst_layer;

$this->layers=array($dst_layer);

return $this;

}

public function setLayerProperty($property=array()){

$index=array_search($this->ActiveLayer, $this->layers);

$this->ActiveLayer=array_merge($this->ActiveLayer,$property);

$this->layers[$index]=$this->ActiveLayer;

return $this;

}

/*

调整图像大小,假如存在多个图层的话,会先合并成一个图层再调整大小

@param int $width 设置的宽度,当为auto时候,直接使用mode 5

@param int $height 设置的高度,当为auto时候,直接使用mode 5

@param array $options 可选参数

@param int $options['mode']调整图片大小的5种模式, default 2

1:直接根据给定的宽高来缩放图形,如果给定的比例不一致会导致图片变形

2:根据给定的宽高,按照原图片的比例全部显示,比例跟原来不一致会差生空白

3:按照图片比例,图像以最大的边显示,多余的部分会去掉,造成生成的缩略图尺寸,其中宽或高会小于指定的

4:图片截取模式,比例不一致时,原图会按原来比例截取,截取中心点可以设定,默认是图片中心点CC

5:给定宽或高按照图片原来比例来调整图片大小

@param string $options['pos'] 截图中心,只在mode 4生效

C for center L for left R for right B for bottom T for top

可选值:LT|LC|LB|CT|CC|CB|RT|RC|RB

*/

public function resize($width,$height,$options=array()){

$default=array(

'mode'=>2,

'pos'=>'CC'

);

$config=array_merge($default,$options=array());

if(count($this->layers)>1){

$this->mergeLayers();

}

if($width=='auto'||$height=='auto'){

$config['mode']=5;

}

switch($config['mode']){

//直接根据给定的宽高来缩放图形,如果给定的比例不一致会导致图片变形

case 1:

$tmpImage=self::createTransparentBg($width, $height);

$result=imagecopyresampled($tmpImage,$this->ActiveLayer['layer'], 0, 0, 0, 0, $width, $height, $this->ActiveLayer['width'], $this->ActiveLayer['height']);

break;

//根据给定的宽高,按照原图片的比例全部显示,比例跟原来不一致会差生空白

case 2:

$tmpImage=self::createTransparentBg($width, $height);

$imageWidth=$this->ActiveLayer['width'];

$imageHeight=$this->ActiveLayer['height'];

$imgRate=$imageWidth*1.0/$imageHeight;

$resizeRate=$width/$height;

if($imgRate>$resizeRate){

$resizeH=round($width*$imageHeight*1.0/$imageWidth);

$resizeW=$width;

$dstX=0;

$dstY=round(($height-$resizeH)*1.0/2);

}else if($imgRate

$resizeW=round($height*$imageWidth*1.0/$imageHeight);

$resizeH=$height;

$dstY=0;

$dstX=round(($width-$resizeW)*1.0/2);

}else{

$resizeW=$width;

$resizeH=$height;

$dstY=0;

$dstX=0;

}

$result=imagecopyresampled($tmpImage,$this->ActiveLayer['layer'], $dstX, $dstY, 0, 0, $resizeW, $resizeH, $imageWidth, $imageHeight);

break;

//按照图片比例,图像以最大的边显示,多余的部分会去掉,造成生成的缩略图尺寸,其中宽或高会小于指定的

case 3:

$imageWidth=$this->ActiveLayer['width'];

$imageHeight=$this->ActiveLayer['height'];

$imgRate=$imageWidth*1.0/$imageHeight;

$resizeRate=$width/$height;

if($imgRate>$resizeRate){

$resizeH=round($width*$imageHeight*1.0/$imageWidth);

$resizeW=$width;

}else if($imgRate

$resizeW=round($height*$imageWidth*1.0/$imageHeight);

$resizeH=$height;

}else{

$resizeW=$width;

$resizeH=$height;

}

$tmpImage=self::createTransparentBg($resizeW, $resizeH);

$result=imagecopyresampled($tmpImage,$this->ActiveLayer['layer'], 0, 0, 0, 0, $resizeW, $resizeH, $imageWidth, $imageHeight);

break;

//图片截取模式,比例不一致时,原图会按原来比例截取,截取中心点可以设定,默认是图片中心点CC

case 4:

$tmpImage=self::createTransparentBg($width, $height);

$imageWidth=$this->ActiveLayer['width'];

$imageHeight=$this->ActiveLayer['height'];

$imgRate=$imageWidth*1.0/$imageHeight;

$resizeRate=$width/$height;

if($imgRate>$resizeRate){

$resizeW=round($imageWidth*$height*1.0/$imageHeight);

$resizeH=$height;

$dstX=round(($resizeW-$width)*1.0/2);

$dstX=-$dstX;

$dstY=0;

}else if($imgRate

$resizeW=$width;

$resizeH=round($width*$imageHeight*1.0/$imageWidth);

$dstX=0;

$dstY=round(($resizeH-$height)*1.0/2);

$dstY=-$dstY;

}else{

$resizeW=$width;

$resizeH=$height;

$dstY=0;

$dstX=0;

}

switch ($config['pos']){

case 'LT':

$dstX=0;

$dstY=0;

break;

case 'LC':

$dstX=0;

break;

case 'LB':

$dstX=0;

$dstY=$dstY*2;

break;

case 'TC':

$dstY=0;

break;

case 'CC':

break;

case 'CB':

$dstY=$dstY*2;

break;

case 'RT':

$dstY=0;

$dstX=$dstX*2;

break;

case 'RC':

$dstX=$dstX*2;

break;

case 'RB':

$dstY=$dstY*2;

$dstX=$dstX*2;

break;

}

$result=imagecopyresampled($tmpImage,$this->ActiveLayer['layer'], $dstX, $dstY,0,0, $resizeW, $resizeH, $imageWidth, $imageHeight);

break;

//给定宽或高按照图片原来比例来调整图片大小

case 5:

$imageWidth=$this->ActiveLayer['width'];

$imageHeight=$this->ActiveLayer['height'];

if($width=='auto'){

$resizeW=round($imageWidth*$height*1.0/$imageHeight);

$resizeH=$height;

}else if($height=='auto'){

$resizeW=$width;

$resizeH=round($imageHeight*$width*1.0/$imageWidth);

}

$tmpImage=self::createTransparentBg($resizeW, $resizeH);

$result=imagecopyresampled($tmpImage,$this->ActiveLayer['layer'], 0,0,0,0, $resizeW, $resizeH, $imageWidth, $imageHeight);

break;

}

$this->ActiveLayer['layer']=$tmpImage;

return $this;

}

public function resizeByPresent($widthPCT,$heightPCT,$options=array()){

$default=array(

'pos'=>'CC',

'mode'=>2

);

$config=array_merge($default,$options);

if(count($this->layers)>1){

$this->mergeLayers();

}

$imageWidth=$this->ActiveLayer['width'];

$imageHeight=$this->ActiveLayer['height'];

$width=$imageWidth*$widthPCT*1.0/100;

$height=$imageHeight*$heightPCT*1.0/100;

if($widthPCT==$heightPCT){

$options['mode']=1;

}

switch($options['mode']){

case 1:

$tmpImage=self::createTransparentBg($width, $height);

$result=imagecopyresampled($tmpImage,$this->ActiveLayer['layer'], 0, 0, 0, 0, $width, $height, $imageWidth, $imageHeight);

break;

case 2:

$tmpImage=self::createTransparentBg($width, $height);

$imgRate=$imageWidth*1.0/$imageHeight;

$resizeRate=$width/$height;

if($imgRate>$resizeRate){

$resizeH=round($width*$imageHeight*1.0/$imageWidth);

$resizeW=$width;

$dstX=0;

$dstY=round(($height-$resizeH)*1.0/2);

}else if($imgRate

$resizeW=round($height*$imageWidth*1.0/$imageHeight);

$resizeH=$height;

$dstY=0;

$dstX=round(($width-$resizeW)*1.0/2);

}else{

$resizeW=$width;

$resizeH=$height;

$dstY=0;

$dstX=0;

}

$result=imagecopyresampled($tmpImage,$this->ActiveLayer['layer'], $dstX, $dstY, 0, 0, $resizeW, $resizeH, $imageWidth, $imageHeight);

break;

case 3:

$imgRate=$imageWidth*1.0/$imageHeight;

$resizeRate=$width/$height;

if($imgRate>$resizeRate){

$resizeH=round($width*$imageHeight*1.0/$imageWidth);

$resizeW=$width;

}else if($imgRate

$resizeW=round($height*$imageWidth*1.0/$imageHeight);

$resizeH=$height;

}else{

$resizeW=$width;

$resizeH=$height;

}

$tmpImage=self::createTransparentBg($resizeW, $resizeH);

$result=imagecopyresampled($tmpImage,$this->ActiveLayer['layer'], 0, 0, 0, 0, $resizeW, $resizeH, $imageWidth, $imageHeight);

break;

case 4:

$tmpImage=self::createTransparentBg($width, $height);

$imgRate=$imageWidth*1.0/$imageHeight;

$resizeRate=$width/$height;

if($imgRate>$resizeRate){

$resizeW=round($imageWidth*$height*1.0/$imageHeight);

$resizeH=$height;

$dstX=round(($resizeW-$width)*1.0/2);

$dstX=-$dstX;

$dstY=0;

}else if($imgRate

$resizeW=$width;

$resizeH=round($width*$imageHeight*1.0/$imageWidth);

$dstX=0;

$dstY=round(($resizeH-$height)*1.0/2);

$dstY=-$dstY;

}else{

$resizeW=$width;

$resizeH=$height;

$dstY=0;

$dstX=0;

}

switch ($config['pos']){

case 'LT':

$dstX=0;

$dstY=0;

break;

case 'LC':

$dstX=0;

break;

case 'LB':

$dstX=0;

$dstY=$dstY*2;

break;

case 'TC':

$dstY=0;

break;

case 'CC':

break;

case 'CB':

$dstY=$dstY*2;

break;

case 'RT':

$dstY=0;

$dstX=$dstX*2;

break;

case 'RC':

$dstX=$dstX*2;

break;

case 'RB':

$dstY=$dstY*2;

$dstX=$dstX*2;

break;

}

$result=imagecopyresampled($tmpImage,$this->ActiveLayer['layer'], $dstX, $dstY,0,0, $resizeW, $resizeH, $imageWidth, $imageHeight);

break;

}

$this->ActiveLayer['layer']=$tmpImage;

return $this;

}

/*

图片剪裁

@param int $width剪裁后的宽度

@param int $height剪裁后的高度

@param array $options可选参数

@param int $options['x'] 相对于pos的x坐标

@param int $options['y'] 相对于pos的y坐标

@param string $options['pos'] 定位中心,以哪个点为参考中心

*/

public function crop($width,$height,$options=array()){

if(count($this->layers)>1){

$this->mergeLayers();

}

$defaults=array(

'x'=>0,

'y'=>0,

'pos'=>'LT'

);

$config=array_merge($defaults,$options);

$dst_image=self::createTransparentBg($width, $height);

$dst_layer=array(

'layer'=>$dst_image,

'width'=>$width,

'height'=>$height,

'x'=>$config['x'],

'y'=>$config['y'],

'pos'=>$config['pos']

);

$cropInfo=array('width'=>$width,'height'=>$height,'x'=>$config['x'],'y'=>$config['y'],'pos'=>$config['pos']);

$realPos=self::getCropPos($dst_layer, $this->ActiveLayer);

imagecopyresampled($dst_layer['layer'], $this->ActiveLayer['layer'], 0, 0, $realPos['x'], $realPos['y'], $width, $height, $width, $height);

$this->ActiveLayer=$dst_layer;

}

/*

保存图片,会自动获取扩展名来保存图片类型

@param string $fileName指定图片保存的完整路径(含路径跟文件名) 如:Uploads/photo/123.png

@param int $quality 指定jpg图片保存的质量,默认100

@param boolean $remove 是否删除使用的图片,默认删除

*/

public function save($fileName,$remove=true,$quality=100){

if(count($this->layers)>1){

$this->mergeLayers();

}

$fileInfo=pathinfo($fileName);

$extension=strtolower($fileInfo['extension']);

switch($extension){

case 'jpg':

imagejpeg($this->ActiveLayer['layer'],$fileName,$quality);

break;

case 'png':

imagepng($this->ActiveLayer['layer'],$fileName);

break;

case 'gif':

imagegif($this->ActiveLayer['layer'],$fileName);

break;

}

imagedestroy($this->ActiveLayer['layer']);

if($remove===true){

foreach ($this->imageLayers as $img){

unlink($img);

}

}

unset($this->ActiveLayer);

unset($this->layers);

unset($this->imageLayers);

$this->layers=array();

$this->imageLayers=array();

}

/*

设置当前图层的level,数值越大的图层越排在前面 (相当于zIndex),当level过大(大于图层数量)时,level值会设置成图层数量

@param int $level 图层的level

*/

public function setLevel($level){

$index=array_search($this->ActiveLayer, $this->layers);

unset($this->layers[$index]);

array_splice($this->layers, $level,0,array($this->ActiveLayer));

return $this;

}

public function topLayer(){

$len=count($this->layers);

$this->setLevel($len);

return $this;

}

/*

根据index值获取图层,并将当前图层替换成取得的图层

@param int $index 如果没设置过图层level的话,图层的index值按照添加的顺序从0-len-1

*/

public function getLayer($index){

$layersLen=count($this->layers);

$index=$index>0?$index:0;

$index=$index

$this->ActiveLayer=$this->layers[$index];

return $this;

}

/*

根据图片的名字获取图层,只支持通过图片创建的图层,并将当前图层替换成取得的图层

@param string $fileName 支持三种模式:1.图片完整的路径;2.图片名字;3.图片名字(不带扩展名)

*/

public function getLayerByFileName($fileName){

foreach ($this->layers as $layer){

if(empty($layer['name'])){

continue;

}

if($layer['name']===$fileName){

$this->ActiveLayer=$layer;

break;

}else{

$fileInfo=pathinfo($layer['name']);

if($fileName===$fileInfo['basename'] || $fileName === $fileInfo['filename']){

$this->ActiveLayer=$layer;

break;

}

}

}

return $this;

}

/*

将web颜色值转化成RGB值

@param string $hex web颜色值

*/

public static function convertHexToRGB($hex){

return array(

'R' => (int) base_convert(substr($hex, 0, 2), 16, 10),

'G' => (int) base_convert(substr($hex, 2, 2), 16, 10),

'B' => (int) base_convert(substr($hex, 4, 2), 16, 10),

);

}

/*

创建一个透明的背景

@param int $width

@param int $height

@param string $color web颜色值

@opacity int $opacity 0-127 127是透明,0是不透明

*/

public static function createTransparentBg($width, $height,$color ='ffffff',$opacity = 127){

$RGBColors = self::convertHexToRGB($color);

$image = imagecreatetruecolor($width, $height);

$color = imagecolorallocatealpha($image, $RGBColors['R'], $RGBColors['G'], $RGBColors['B'],$opacity);

imagecolortransparent($image,$color);

imagefill($image, 0, 0, $color);

return $image;

}

/*

根据图片创建gd image resource

@param string $fileName图像文件的完整路径

*/

public static function createFromImage($fileName){

if(file_exists($fileName)&&!is_dir($fileName)){

$imgInfo=getimagesize($fileName);

$width=$imgInfo[0];

$height=$imgInfo[1];

$type=$imgInfo[2];

if($type>3){

return array('status'=>1,'msg'=>'只支持jpg,png,gif这三种格式的图像文件');

}

switch ($type){

//gif

case 1:

$image=imagecreatefromgif($fileName);

break;

//jpg

case 2:

$image=imagecreatefromjpeg($fileName);

break;

//png

case 3:

$image=imagecreatefrompng($fileName);

break;

}

}else{

throw new Exception('不是一个有效的图像文件');

}

return $image;

}

/*

取得图像图层的绝对位置

@param string $dstW 目标图层的宽

@param string $dstH 目标图层的高

@param array $layer 需要获取绝对位置的图层

*/

public static function getRealPosition($dstW,$dstH,$layer){

$posOut=array();

switch ($layer['pos']){

case 'LT':

$posOut=array('x'=>$layer['x'],'y'=>$layer['y']);

break;

case 'LC':

$offsetH=round(($dstH-$layer['height'])*1.0/2);

$posOut=array('x'=>$layer['x'],'y'=>$offsetH+$layer['y']);

break;

case 'LB':

$offsetH=$dstH-$layer['height'];

$posOut=array('x'=>$layer['x'],'y'=>$offsetH-$layer['y']);

break;

case 'CT':

$offsetW=round(($dstW-$layer['width'])*1.0/2);

$posOut=array('x'=>$offsetW+$layer['x'],'y'=>$layer['y']);

break;

case 'CC':

$offsetW=round(($dstW-$layer['width'])*1.0/2);

$offsetH=round(($dstH-$layer['height'])*1.0/2);

$posOut=array('x'=>$offsetW+$layer['x'],'y'=>$offsetH+$layer['y']);

break;

case 'CB':

$offsetW=round(($dstW-$layer['width'])*1.0/2);

$offsetH=$dstH-$layer['height'];

$posOut=array('x'=>$offsetW+$layer['x'],'y'=>$offsetH-$layer['y']);

break;

case 'RT':

$offsetW=$dstW-$layer['width'];

$posOut=array('x'=>$offsetW-$layer['x'],'y'=>$layer['y']);

break;

case 'RC':

$offsetW=$dstW-$layer['width'];

$offsetH=round(($dstH-$layer['height'])*1.0/2);

$posOut=array('x'=>$offsetW-$layer['x'],'y'=>$offsetH+$layer['y']);

break;

case 'RB':

$offsetW=$dstW-$layer['width'];

$offsetH=$dstH-$layer['height'];

$posOut=array('x'=>$offsetW-$layer['x'],'y'=>$offsetH-$layer['y']);

break;

default:

$posOut=array('x'=>$layer['x'],'y'=>$layer['y']);

break;

}

return $posOut;

}

/*

取得剪裁部分的绝对位置

@param array $cropInfo 剪裁后图层的信息,包含width,height,x,y,pos等信息

@param array $layerInfo 目标图层的信息,包含width,height,x,y,pos等信息

*/

public static function getCropPos($cropInfo,$layerInfo){

switch ($cropInfo['pos']){

case 'LT':

$pos=array('x'=>$cropInfo['x'],'y'=>$cropInfo['y']);

break;

case 'LC':

$offsetHeight=round(($layerInfo['height']-$cropInfo['height'])*1.0/2);

$pos=array('x'=>$cropInfo['x'],'y'=>$cropInfo['y']+$offsetHeight);

break;

case 'LB':

$offsetHeight=$layerInfo['height']-$cropInfo['height'];

$pos=array('x'=>$cropInfo['x'],'y'=>$offsetHeight-$cropInfo['x']);

break;

case 'CT':

$offsetWidth=round(($layerInfo['width']-$cropInfo['width'])*1.0/2);

$pos=array('x'=>$offsetWidth+$cropInfo['x'],'y'=>$cropInfo['y']);

break;

case 'CC':

$offsetWidth=round(($layerInfo['width']-$cropInfo['width'])*1.0/2);

$offsetHeight=round(($layerInfo['height']-$cropInfo['height'])*1.0/2);

$pos=array('x'=>$offsetWidth+$cropInfo['x'],'y'=>$offsetHeight+$cropInfo['y']);

break;

case 'CB':

$offsetWidth=round(($layerInfo['width']-$cropInfo['width'])*1.0/2);

$offsetHeight=$layerInfo['height']-$cropInfo['height'];

$pos=array('x'=>$offsetWidth+$cropInfo['x'],'y'=>$offsetHeight-$cropInfo['y']);

break;

case 'RT':

$offsetWidth=$layerInfo['width']-$cropInfo['width'];

$pos=array('x'=>$offsetWidth-$cropInfo['x'],'y'=>$cropInfo['y']);

break;

case 'RC':

$offsetWidth=$layerInfo['width']-$cropInfo['width'];

$offsetHeight=round(($layerInfo['height']-$cropInfo['height'])*1.0/2);

$pos=array('x'=>$offsetWidth-$cropInfo['x'],'y'=>$offsetHeight+$cropInfo['y']);

break;

case 'RB':

$offsetWidth=$layerInfo['width']-$cropInfo['width'];

$offsetHeight=$layerInfo['height']-$cropInfo['height'];

$pos=array('x'=>$offsetWidth-$cropInfo['x'],'y'=>$offsetHeight-$cropInfo['y']);

break;

}

return $pos;

}

public static function sortLayers($a,$b){

if($a['level']>$b['level']){

return 1;

}else if($a['level']

return -1;

}else{

return 0;

}

}

}

一键复制

编辑

Web IDE

原始数据

按行查看

历史

你可能感兴趣的:(photo.php)