一个经典实用的PHP图像处理类分享


Posted in PHP onNovember 18, 2014

本图像处理类可以完成对图片的缩放、加水印和裁剪的功能,支持多种图片类型的处理,缩放时进行优化等。

<?php
/**
 file: image.class.php 类名为Image
 图像处理类,可以完成对各种类型的图像进行缩放、加图片水印和剪裁的操作。
 */
class Image {
  /* 图片保存的路径 */
  private $path;
 
  /**
   * 实例图像对象时传递图像的一个路径,默认值是当前目录
   * @param  string $path  可以指定处理图片的路径
   */
  function __construct($path="./"){
    $this->path = rtrim($path,"/")."/";
  }
 
  /**
   * 对指定的图像进行缩放
   * @param  string $name  是需要处理的图片名称
   * @param  int $width   缩放后的宽度
   * @param  int $height   缩放后的高度
   * @param  string $qz   是新图片的前缀
   * @return mixed      是缩放后的图片名称,失败返回false;
   */
  function thumb($name, $width, $height,$qz="th_"){
    /* 获取图片宽度、高度、及类型信息 */
    $imgInfo = $this->getInfo($name);
    /* 获取背景图片的资源 */
    $srcImg = $this->getImg($name, $imgInfo);
    /* 获取新图片尺寸 */
    $size = $this->getNewSize($name,$width, $height,$imgInfo);
    /* 获取新的图片资源 */
    $newImg = $this->kidOfImage($srcImg, $size,$imgInfo);
    /* 通过本类的私有方法,保存缩略图并返回新缩略图的名称,以"th_"为前缀 */
    return $this->createNewImage($newImg, $qz.$name,$imgInfo);
  }
 
  /**
   * 为图片添加水印
   * @param  string $groundName 背景图片,即需要加水印的图片,暂只支持GIF,JPG,PNG格式
   * @param  string $waterName 图片水印,即作为水印的图片,暂只支持GIF,JPG,PNG格式
   * @param  int $waterPos    水印位置,有10种状态,0为随机位置;
   *                1为顶端居左,2为顶端居中,3为顶端居右;
   *                4为中部居左,5为中部居中,6为中部居右;
   *                7为底端居左,8为底端居中,9为底端居右;
   * @param  string $qz     加水印后的图片的文件名在原文件名前面加上这个前缀
   * @return  mixed        是生成水印后的图片名称,失败返回false
   */
  function waterMark($groundName, $waterName, $waterPos=0, $qz="wa_"){
    /*获取水印图片是当前路径,还是指定了路径*/
    $curpath = rtrim($this->path,"/")."/";
    $dir = dirname($waterName);
    if($dir == "."){
      $wpath = $curpath;
    }else{
      $wpath = $dir."/";
      $waterName = basename($waterName);
    }
 
    /*水印图片和背景图片必须都要存在*/
    if(file_exists($curpath.$groundName) && file_exists($wpath.$waterName)){
      $groundInfo = $this->getInfo($groundName);        //获取背景信息
      $waterInfo = $this->getInfo($waterName, $dir);      //获取水印图片信息
      /*如果背景比水印图片还小,就会被水印全部盖住*/
      if(!$pos = $this->position($groundInfo, $waterInfo, $waterPos)){
        echo '水印不应该比背景图片小!';
        return false;
      }
 
      $groundImg = $this->getImg($groundName, $groundInfo);  //获取背景图像资源
      $waterImg = $this->getImg($waterName, $waterInfo, $dir); //获取水印图片资源
 
      /* 调用私有方法将水印图像按指定位置复制到背景图片中 */
      $groundImg = $this->copyImage($groundImg, $waterImg, $pos, $waterInfo);
      /* 通过本类的私有方法,保存加水图片并返回新图片的名称,默认以"wa_"为前缀 */
      return $this->createNewImage($groundImg, $qz.$groundName, $groundInfo);
 
    }else{
      echo '图片或水印图片不存在!';
      return false;
    }
  }
 
  /**
   * 在一个大的背景图片中剪裁出指定区域的图片
   * @param  string $name  需要剪切的背景图片
   * @param  int $x     剪切图片左边开始的位置
   * @param  int $y     剪切图片顶部开始的位置
   * @param  int $width   图片剪裁的宽度
   * @param  int $height   图片剪裁的高度
   * @param  string $qz   新图片的名称前缀
   * @return  mixed      裁剪后的图片名称,失败返回false;
   */
  function cut($name, $x, $y, $width, $height, $qz="cu_"){
    $imgInfo=$this->getInfo($name);         //获取图片信息
    /* 裁剪的位置不能超出背景图片范围 */
    if( (($x+$width) > $imgInfo['width']) || (($y+$height) > $imgInfo['height'])){
      echo "裁剪的位置超出了背景图片范围!";
      return false;
    }
 
    $back = $this->getImg($name, $imgInfo);     //获取图片资源
    /* 创建一个可以保存裁剪后图片的资源 */
    $cutimg = imagecreatetruecolor($width, $height);
    /* 使用imagecopyresampled()函数对图片进行裁剪 */
    imagecopyresampled($cutimg, $back, 0, 0, $x, $y, $width, $height, $width, $height);
    imagedestroy($back);
    /* 通过本类的私有方法,保存剪切图并返回新图片的名称,默认以"cu_"为前缀 */
    return $this->createNewImage($cutimg, $qz.$name,$imgInfo);
  }
 
  /* 内部使用的私有方法,用来确定水印图片的位置 */
  private function position($groundInfo, $waterInfo, $waterPos){
    /* 需要加水印的图片的长度或宽度比水印还小,无法生成水印 */
    if( ($groundInfo["width"]<$waterInfo["width"]) || ($groundInfo["height"]<$waterInfo["height"]) ) {
      return false;
    }
    switch($waterPos) {
      case 1:     //1为顶端居左
        $posX = 0;
        $posY = 0;
        break;
      case 2:     //2为顶端居中
        $posX = ($groundInfo["width"] - $waterInfo["width"]) / 2;
        $posY = 0;
        break;
      case 3:     //3为顶端居右
        $posX = $groundInfo["width"] - $waterInfo["width"];
        $posY = 0;
        break;
      case 4:     //4为中部居左
        $posX = 0;
        $posY = ($groundInfo["height"] - $waterInfo["height"]) / 2;
        break;
      case 5:     //5为中部居中
        $posX = ($groundInfo["width"] - $waterInfo["width"]) / 2;
        $posY = ($groundInfo["height"] - $waterInfo["height"]) / 2;
        break;
      case 6:     //6为中部居右
        $posX = $groundInfo["width"] - $waterInfo["width"];
        $posY = ($groundInfo["height"] - $waterInfo["height"]) / 2;
        break;
      case 7:     //7为底端居左
        $posX = 0;
        $posY = $groundInfo["height"] - $waterInfo["height"];
        break;
      case 8:     //8为底端居中
        $posX = ($groundInfo["width"] - $waterInfo["width"]) / 2;
        $posY = $groundInfo["height"] - $waterInfo["height"];
        break;
      case 9:     //9为底端居右
        $posX = $groundInfo["width"] - $waterInfo["width"];
        $posY = $groundInfo["height"] - $waterInfo["height"];
        break;
      case 0:
      default:    //随机
        $posX = rand(0,($groundInfo["width"] - $waterInfo["width"]));
        $posY = rand(0,($groundInfo["height"] - $waterInfo["height"]));
        break;
    }
    return array("posX"=>$posX, "posY"=>$posY);
  }
 
  /* 内部使用的私有方法,用于获取图片的属性信息(宽度、高度和类型) */
  private function getInfo($name, $path=".") {
    $spath = $path=="." ? rtrim($this->path,"/")."/" : $path.'/';
 
    $data = getimagesize($spath.$name);
    $imgInfo["width"]  = $data[0];
    $imgInfo["height"] = $data[1];
    $imgInfo["type"]  = $data[2];
 
    return $imgInfo;
  }
 
  /*内部使用的私有方法, 用于创建支持各种图片格式(jpg,gif,png三种)资源 */
  private function getImg($name, $imgInfo, $path='.'){
 
    $spath = $path=="." ? rtrim($this->path,"/")."/" : $path.'/';
    $srcPic = $spath.$name;
 
    switch ($imgInfo["type"]) {
      case 1:         //gif
        $img = imagecreatefromgif($srcPic);
        break;
      case 2:         //jpg
        $img = imagecreatefromjpeg($srcPic);
        break;
      case 3:         //png
        $img = imagecreatefrompng($srcPic);
        break;
      default:
        return false;
        break;
    }
    return $img;
  }
 
  /* 内部使用的私有方法,返回等比例缩放的图片宽度和高度,如果原图比缩放后的还小保持不变 */
  private function getNewSize($name, $width, $height, $imgInfo){
    $size["width"] = $imgInfo["width"];     //原图片的宽度
    $size["height"] = $imgInfo["height"];    //原图片的高度
 
    if($width < $imgInfo["width"]){
      $size["width"]=$width;          //缩放的宽度如果比原图小才重新设置宽度
    }
 
    if($height < $imgInfo["height"]){
      $size["height"] = $height;        //缩放的高度如果比原图小才重新设置高度
    }
    /* 等比例缩放的算法 */
    if($imgInfo["width"]*$size["width"] > $imgInfo["height"] * $size["height"]){
      $size["height"] = round($imgInfo["height"]*$size["width"]/$imgInfo["width"]);
    }else{
      $size["width"] = round($imgInfo["width"]*$size["height"]/$imgInfo["height"]);
    }
 
    return $size;
  }
 
  /* 内部使用的私有方法,用于保存图像,并保留原有图片格式 */
  private function createNewImage($newImg, $newName, $imgInfo){
    $this->path = rtrim($this->path,"/")."/";
    switch ($imgInfo["type"]) {
      case 1:       //gif
        $result = imageGIF($newImg, $this->path.$newName);
        break;
      case 2:       //jpg
        $result = imageJPEG($newImg,$this->path.$newName);
        break;
      case 3:       //png
        $result = imagePng($newImg, $this->path.$newName);
        break;
    }
    imagedestroy($newImg);
    return $newName;
  }
 
  /* 内部使用的私有方法,用于加水印时复制图像 */
  private function copyImage($groundImg, $waterImg, $pos, $waterInfo){
    imagecopy($groundImg, $waterImg, $pos["posX"], $pos["posY"], 0, 0, $waterInfo["width"],$waterInfo["height"]);
    imagedestroy($waterImg);
    return $groundImg;
  }
 
  /* 内部使用的私有方法,处理带有透明度的图片保持原样 */
  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;
  }
}
PHP 相关文章推荐
php 字符过滤类,用于过滤各类用户输入的数据
May 27 PHP
php mysql Errcode: 28 终极解决方法
Jul 01 PHP
The specified CGI application misbehaved by not returning a complete set of HTTP headers
Mar 31 PHP
smarty基础之拼接字符串的详解
Jun 18 PHP
destoon设置自定义搜索的方法
Jun 21 PHP
php中的curl_multi系列函数使用例子
Jul 29 PHP
PHP将进程作为守护进程的方法
Mar 19 PHP
php检测图片主要颜色的方法
Jul 01 PHP
java模拟PHP的pack和unpack类
Apr 13 PHP
微信公众平台开发-微信服务器IP接口实例(含源码)
Mar 05 PHP
PHP实现的简单留言板功能示例【基于thinkPHP框架】
Dec 07 PHP
PHP中的Iterator迭代对象属性详解
Apr 12 PHP
PHP中一些可以替代正则表达式函数的字符串操作函数
Nov 17 #PHP
PHP向浏览器输出内容的4个函数总结
Nov 17 #PHP
PHP中使用匿名函数操作数据库的例子
Nov 17 #PHP
PHP中定义数组常量(array常量)的方法
Nov 17 #PHP
php中addslashes函数与sql防注入
Nov 17 #PHP
php数组排序usort、uksort与sort函数用法
Nov 17 #PHP
php中current、next与reset函数用法实例
Nov 17 #PHP
You might like
如何去掉文章里的 html 语法
2006/10/09 PHP
PHP完整的日历类(CLASS)
2006/11/27 PHP
php数据库的增删改查 php与javascript之间的交互
2017/08/31 PHP
Laravel监听数据库访问,打印SQL的例子
2019/10/24 PHP
javascript demo 基本技巧
2009/12/18 Javascript
js中的preventDefault与stopPropagation详解
2014/01/29 Javascript
javascript动态添加checkbox复选框的方法
2015/12/23 Javascript
JS简单实现DIV相对于浏览器固定位置不变的方法
2016/06/17 Javascript
jquery 动态增加删除行的简单实例(推荐)
2016/10/12 Javascript
详解jQuery中基本的动画方法
2016/12/14 Javascript
js实现点击按钮弹出上传文件的窗口
2016/12/23 Javascript
JS设置CSS样式的方式汇总
2017/01/21 Javascript
Angular6封装http请求的步骤详解
2018/08/13 Javascript
vue项目每30秒刷新1次接口的实现方法
2018/12/04 Javascript
vue移动端屏幕适配详解
2019/04/30 Javascript
微信公众号平台接口开发 获取access_token过程解析
2019/08/14 Javascript
vue中进行微博分享的实例讲解
2019/10/14 Javascript
解决vue语法会有延迟加载显现{{xxx}}的问题
2019/11/14 Javascript
Node 模块原理与用法详解
2020/05/13 Javascript
python字符串str和字节数组相互转化方法
2017/03/18 Python
Python RabbitMQ消息队列实现rpc
2018/05/30 Python
解决Python plt.savefig 保存图片时一片空白的问题
2019/01/10 Python
浅谈Python 函数式编程
2020/06/20 Python
Big Green Smile德国网上商店:提供各种天然产品
2018/05/23 全球购物
加拿大城市本地限时优惠:Buytopia.ca
2018/09/19 全球购物
应用服务器有那些
2012/01/19 面试题
化妆品活动策划方案
2014/05/23 职场文书
财政局党的群众路线教育实践活动剖析材料
2014/10/13 职场文书
2015年爱国卫生月活动总结
2015/03/26 职场文书
电影建国大业观后感
2015/06/01 职场文书
商业计划书范文
2019/04/24 职场文书
Golang 实现获取当前函数名称和文件行号等操作
2021/05/08 Golang
html css3不拉伸图片显示效果
2021/06/07 HTML / CSS
CentOS8.4安装Redis6.2.6的详细过程
2021/11/20 Redis
SQL Server中的游标介绍
2022/05/20 SQL Server
spring IOC容器的Bean管理XML自动装配过程
2022/05/30 Java/Android