• 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);
    
    
  • 相关阅读:
    kettle7.0数据库迁移(MySQL迁移到Postgresql,迁移过程中自动创建表结构)
    正向代理与反向代理区别
    MySQL存储引擎相关知识点
    设计模式-装饰器模式
    设计模式-策略模式
    算法—数据结构学习笔记(二)栈
    Spring Boot2.0学习笔记(一)
    关联容器——map
    迭代器
    C风格字符串
  • 原文地址:https://www.cnblogs.com/zhyunfe/p/6395224.html
Copyright © 2020-2023  润新知