PHP面向对象——GD库实现图片水印和缩略图

今天的实现目标就是使用GD库完成对图片加水印和图

片缩略图两个功能

动身前逻辑准备

属性:
	路径

功能:
  构造方法

  生成水印的方法
  获取

图片信息
  获取位置信息(123 456 789)
  创建图片资源
  合并图片资源
  重新命名
  保存图片
  生成缩

略图的方法
  获取图片信息
  获取需要缩放的图片大小
  创建图片资源
  处理一下可能出现的黑边问题
  

重新命名
  保存图片

接下来将文字描述转换为代码

首先,创建一个Image类,包含属性和构造方

class Image()
  {
  	//定义图片路径
    static $path = '/';
  	//构造方法
  	

public function __construct($path = '/') {
      $this->path = rtrim($path,'').'/';
  	}
  

}

接下来完善类中的方法

  • 获取图片信息
static private function getImageInfo($imgPath)
  

{
    $info = getimagesize($imgPath);
  	return array(
    		'width' => $info

[0],
      		'height'=> $info[1],
      		'mime'  => $info['mime'],
   

   		'name'  => basename($imgPath)
    );
  }
  • 检查目标图片与水印图片大小是不是

匹配

static private function checksize($dstImgInfo,$waterImgInfo)
 {
   if

($waterImgInfo['width'] > $dstImgInfo['width'] || $waterImgInfo['height'] > $dstImgInfo

['height'])
     {
       return false;
     } else {
       return true;
     }
 }
  • 根据需要

确定水印的位置

这里将图片分成九宫格

1 2 3

4 5 6

7 8 9

static private function getPosition($dstImgInfo,$waterImgInfo,$postion)
  {
    switch 

($position) {
      case 1:
        $x = 0;
        $y = 0;
        break;
      case 2:
		

$x = ceil(($desImgInfo['width'] - $waterImgInfo['width']) / 2);
		$y = 0;
		

break;
	case 3:
		$x = $dstImgInfo['width'] - $waterImgInfo['width'];
		$y 

= 0;
	case 4:
		$x = 0;
		$y = ceil(($dstImgInfo['height'] - $waterImgInfo

['height']) / 2);
		break;
	case 5:
		$x = ceil(($desImgInfo['width'] -

$waterImgInfo['width']) / 2);
		$y = ceil(($dstImgInfo['height'] - $waterImgInfo

['height']) / 2);
		break;
	case 6:
		$x = $dstImgInfo['width'] - 

$waterImgInfo['width'];
		$y = ceil(($dstImgInfo['height'] - $waterImgInfo['height']) 

/ 2);
		break;
	case 7:
		$x = 0;
		$y = $dstImgInfo['height'] - 

$waterImgInfo['height'];
		break;
	case 8:
		$x = ceil(($desImgInfo

['width'] - $waterImgInfo['width']) / 2);
		$y = $dstImgInfo['height'] - 

$waterImgInfo['height'];
		break;
	case 9:
		$x = $dstImgInfo['width'] - 

$waterImgInfo['width'];
		$y = $dstImgInfo['height'] - $waterImgInfo['height'];
	}
	

return [
				'x' => $x,
				'y' => $y
	

	];
  }
  • 根据图片的mime类型创建图片资源
static private function createImgRes

($imgPath,$imgInfo)
  {
    switch ($imgInfo['mime']) {
      case 'image/jpg':
      case 

'image/jpeg':
      case 'image/pjpeg':
        $res = imagecreatefromjpeg($imgPath);
        

break;
      case 'image/png':
      case 'image/x-png':
        $res = imagecreatefrompng

($imgPath);
        break;
      case 'image/gif':
        $res = imagecreatefromgif

($imgPath);
        break;
      case 'image/bmp':
      case 'image/wbmp':
        $res = 

imagecreatefromwbmp($imgPath);
        break;
      default:
        exit('图片我们不支持!');
 

       break;
		}
		return $res;
  }
  • 给原图加上水印
static 

private function merge($dstImgRes,$waterImgRes,$waterImgInfo,$pos,$opacity)
	{
		

imagecopymerge($dstImgRes, $waterImgRes, $pos['x'], $pos['y'], 0, 0, $waterImgInfo

['width'], $waterImgInfo['height'], $opacity);

		return $dstImgRes;
	}
	
  • 保存图片
static private function saveImg($newImgRes,$newPath,$dstImgInfo)
	{
  

switch ($dstImgInfo['mime']) {
    case 'image/jpg':
    case 'image/jpeg':
    case 

'image/pjpeg':
      $res = imagejpeg($newImgRes,$newPath);
      break;
    case 'image/png':
 

   case 'image/x-png':
      $res = imagepng($newImgRes,$newPath);
      break;
    case 

'image/gif':
      $res = imagegif($imgPath);
      break;
    case 'image/bmp':
    case 

'image/wbmp':
      $res = imagewbmp($newImgRes,$newPath);
      break;
    default:
      

exit('您的破图片我们不支持!');
      break;
	}
}
  • 完成水印生成的公共方法

 /*

$dstImg:原图像
 *$waterImg:水印图片
 *$postion:水印的位置
 *$prefix:最终生成水印的图片名称前缀
 

*$opacity:水印透明度
 */
static public function water($dstImg,$waterImg,$position = 9,$prefix 

= 'water_',$opacity = 50)
{	
  	//判断图片是否存在
  $dstImg = self::$path.$dstImg;
  

if(!file_exists($dstImg))
    {
      exit('目标图片不存在');
    }
  if(!file_exists

($waterImg))
    {
      exit('水印图片不存在');
    }
  
  //通过自己定义的函数来获取图片和水印

图片的信息
  $dstImgInfo = self::getImageInfo($dstImg);
  $waterImgInfo = self::getImageInfo

($waterImg);
  
  //检查图片大小的函数
  if(!self::checkSize($dstImgInfo,$waterImgInfo))
    {
  

    exit('水印图片大小不能超过目标图片的大小');
    }
  //获取水印在目标图片的位置
	

$pos = self::getPosition($dstImgInfo,$waterImgInfo,$position);

  //创建图片资源,准备合并
	

$dstImgRes = self::createImgRes($dstImg,$dstImgInfo);
	$waterImgRes = self::createImgRes

($waterImg,$waterImgInfo);
  //合并图片,生成新图片
	$newImgRes = self::merge

($dstImgRes,$waterImgRes,$waterImgInfo,$pos,$opacity);
	$newPath = self::$path.

$prefix.uniqid().$dstImgInfo['name'];
	imagedestroy($dstImgRes);
	imagedestroy

($waterImgRes);
	imagedestroy($newImgRes);
	//生成新图片
	self::saveImg($newImgRes,

$newPath,$dstImgInfo);

	return $newPath;
}

上述面是给图片加水印的全部方法,接下来完成

图片缩略图

//生成缩略图的方法
	static public function thump($img,$width,$height,

$prefix = 'thump_')
	{
		if(!file_exists($img))
		{
			

exit('破图片不存在');
		}
		//获取图片的信息
     	//getImageInfo()自

定义函数
		$imgInfo = self::getImageInfo($img);
		//创建图片资源
      

	//createImgRes()自定义函数
		$imgRes  = self::createImgRes($img,

$imgInfo);
		//获取新的大小
      	//getNewSize()自定义函数--->得到最新的大小
	

	$newSize = self::getNewSize($width,$height,$imgInfo);
		//解决黑边问题
      

	//kidOfImage()自定义函数
		$newImgRes = self::kidOfImage($imgRes, 

$newSize, $imgInfo);
		//拼装缩略后的新的图片名字
		$newPath = 

$prefix.$newSize['width'].'X'.$newSize['height'].$imgInfo['name'];
		//保存图片
	

	self::saveImg($newImgRes,$newPath,$imgInfo);

		imagedestroy($newImgRes);
	

	//返回新的路径
		return $newPath;
	}
  • 重新计算缩略后的图成比例的宽

高问题


	static private function getNewSize($width,$height,$imgInfo)
	{
		

$size = [];

		//判断缩略后的图的宽度,是不是比原图小
		if($imgInfo

['width'] > $width)
		{
			$size['width'] = $width;
		

}
		//判断缩略图的高度是不是比原图小
		if($imgInfo['height'] > 

$height)
		{
			$size['height'] = $height;
		}

	

	//即使小了,但是不成比例也不可以
		//如果缩略后的宽度是合适的,那么按

照比例重新设高度
		if($imgInfo['width'] * $size['width'] > $imgInfo['height'] 

* $imgInfo['height'])
		{
			$size['height'] = $imgInfo

['height'] * $size['width'] / $imgInfo['width'];
		}else{
			//

缩略后的高度是合适的,按照比例重新设置宽度
			$size['width'] = $imgInfo

['width'] * $size['height'] / $imgInfo['height'];
		}
		return 

$size;
	}
  • 解决可能出现的黑边问题
	static private function kidOfImage($srcImg, 

$size, $imgInfo)
	{
		$newImg = imagecreatetruecolor($size["width"], 

$size["height"]);
		$otsc = imagecolortransparent($srcImg);
		if ( $otsc 

>= 0 && $otsc < imagecolorstotal($srcImg)) {
			 $transparentcolor = 

imagecolorsforindex( $srcImg, $otsc );
				 $newtransparentcolor = 

imagecolorallocate(
				 $newImg,
				 

$transparentcolor['red'],
				 $transparentcolor['green'],
		

		 $transparentcolor['blue']
			 );

			 

imagefill( $newImg, 0, 0, $newtransparentcolor );
			 

imagecolortransparent( $newImg, $newtransparentcolor );
		}

		

imagecopyresized( $newImg, $srcImg, 0, 0, 0, 0, $size["width"], $size["height"], $imgInfo

["width"], $imgInfo["height"] );
		imagedestroy($srcImg);
		return 

$newImg;
	}
}

使用方式

Image::water('zhyunfe-com.jpg','2.jpg');

Image::thump('./zhyunfe-com.jpg',50,50);