超NB图像处理类(缩略图、水印、验证码)


自己花了一天时间写了个图像处理类,主要包含三个功能:

1、缩略图

可按照不同方式缩略,可以按照宽等比例缩放、按照高等比例缩放、设置指定宽高等比例缩放(多余填充白色)、指定宽高填充缩放(不是等比例,直接填充满)、居中裁剪(不缩放,把大图居中裁剪)。

2、加水印

可设置水印位置(1左上、2右上、3居中、4左下、5右下)和水印透明度。

3、验证码

可设置验证码长度

下载:图像处理类

 

<?php
/**
 * 图像处理类
 * Be the best of whatever you are!
 * 调用方式:
 * $img=new Image();
 * 1、 $img->thumb(图像路径,缩略图宽度,缩略图高度,[略缩方式]);
 * 返回缩略图路径
 * 略缩方式1等比例缩放,2为填充,3为居中截取不缩放(默认等比例)
 * 略缩图默认保存路劲在该图片的同级目录的thumb目录下
 
 * 2、 $img->waterMark(图像路径,水印图路径,是否覆盖原图,[加水印位置],[透明度]);
 * 返回水印图名称
 * 加水印位置 1左上 2右上 3居中 4左下 5右下(默认右下)透明度默认40
 *
 * 3、$img->verCode([验证码长度]);
 * 返回一个验证码图像,可设置长度
 
 * @author: Dzer <Email:358654744@qq.com Blog:dzer.me>
 * @version: 2014-12-25 09:25:58
 * @Last Modified time: 2014-12-28 21:32:54
 */
class Image{
    protected $error=array();
    protected $imgIm=null;     //保存打开图像资源
    protected $type=array(1=>'gif',2=>'jpg',3=>'png',6=>'bmp',15=>'wbmp',16=>'xbm');
    protected $imgInfo=array();
    protected $thumbIm=null;
    protected $image;
    /**
     * thumb 生成缩略图
     * @param  string      $image     图片路径
     * @param  int      $maxWidth  略缩图宽度(为0时 按照高等比例缩放)
     * @param  int      $maxHeight 略缩图宽度(为0时 按照宽等比例缩放)
     * @param  int         $thType    略缩方式 1为等比例 2为填充  3为居中截取
     * @return string                返回 略缩图的路径
     */
    public function thumb($image,$maxWidth,$maxHeight,$thType=1){
        $this->image=$image;
        //打开图像
        if(!$this->open($this->image)){
            return false;
        }
        if(empty($maxWidth) && empty($maxHeight)){
            $this->error[]='宽高不能同时为0';
            return false;
        }
        $pathinfo pathinfo($this->image); 
        $path str_replace('\\''/'$pathinfo['dirname']).'/thumb';
        $this->cjDir($path);
        //图片重命名
        $image$path.'/'.basename($this->image,'.'.$this->imgInfo['type']).'_thumb.'.$this->imgInfo['type'];    
        
        //判断是否需要缩放(不需要就直接另存)
        if($maxWidth>$this->imgInfo['width'] && $maxHeight>$this->imgInfo['height']){
            return $this->save($this->imgIm,$image);
        }
        $this->suofang($maxWidth,$maxHeight,$thType);
        return $this->save($this->thumbIm,$image);    
    }
    /**
     * save 保存图像
     * @param  resource  $im    图像资源
     * @param  string  $imgName 图像名称
     * @param  string  $type    后缀名
     * @param  integer $quality 图片质量(jpg能设置)
     * @return string           保存图像路径
     */
    public function save($im,$imgName='',$type='',$quality=80){
        if(empty($im)){
            $this->error[]='没有可保存的图像资源';
            return false;
        }
        //自动获取图像类型
        if(empty($type)){
            $type $this->imgInfo['type'];
        else {
            $type strtolower($type);
        }
        //保存图像
        if('jpeg' == $type || 'jpg' == $type){
            //JPEG图像设置隔行扫描
            imageinterlace($im, true);
            $sf=imagejpeg($im$imgName,$quality);
        }else{
            $fun ='image'.$type;
            $sf=$fun($im$imgName);
        }
        if(!is_null($this->imgIm)){
            imagedestroy($this->imgIm);
        }
        if($sf){
            return $imgName;
        }else{
            $this->error[]='图片保存出错';
            return false;
        }
    }
    /**
     * suofang 缩放图像
     * 1、如果高为0 按照宽等比例缩放,如果宽为零按照高等比例缩放
     * 2、如果高宽都设置  
     * 如果缩放方式type为1 等比例缩放 空白处留白
     * 如果缩放方式type为2 填充缩放 填充满整个图像
     * 如果缩放方式type为3 居中截取不缩放  居中截取大图复制到略缩图
     
     * @param  int  $maxWidth  略缩图宽度
     * @param  int  $maxHeight 略缩图高度
     * @param  int $thType     略缩方式 1为等比例 2为填充  3为居中截取
     */
    public function suofang($maxWidth,$maxHeight,$thType=1){
        $dst_x=$dst_y=0;
        if(empty($maxHeight)){
            $maxHeight=($maxWidth/$this->imgInfo['width']) * $this->imgInfo['height'];
        }elseif(empty($maxWidth)){
            $maxWidth=($maxHeight/$this->imgInfo['height']) * $this->imgInfo['width'];
        }
        //判断是否等比例缩放
        if($thType==1 || $thType==3){
            $bl=min($maxHeight/$this->imgInfo['height'],$maxWidth/$this->imgInfo['width']);
            $minWidth$bl$this->imgInfo['width'];
            $minHeight$bl$this->imgInfo['height'];
            $dst_x=($maxWidth-$minWidth)/2;
            $dst_y=($maxHeight-$minHeight)/2;
        }
        //创建缩放的画布
        $this->thumbIm=imagecreatetruecolor($maxWidth$maxHeight);
        //填充白色背景
        $white=imagecolorallocate($this->thumbIm, 255, 255, 255);
        imagefill($this->thumbIm, 0, 0, $white);
        
        if($thType==3){
            //截取大图坐标
            if(($this->imgInfo['width']-$maxWidth)>0){
                $minWidth=$maxWidth;
                $src_x=($this->imgInfo['width']-$maxWidth)/2;
                $dst_x=0;
            }else{
                $minWidth=$this->imgInfo['width'];
                $dst_x=($maxWidth-$minWidth)/2;
                $src_x=0;
            
            if(($this->imgInfo['height']-$maxHeight)>0){
                $minHeight=$maxHeight;
                $src_y=($this->imgInfo['height']-$maxHeight)/2;
                $dst_y=0;
            }else{
                $src_y=0;
                $minHeight=$this->imgInfo['height'];
                $dst_y=($maxHeight-$minHeight)/2;
            }
            imagecopymergegray($this->thumbIm, $this->imgIm, $dst_x$dst_y$src_x$src_y$minWidth$minHeight, 100);
        }elseif($thType==1){
            imagecopyresampled($this->thumbIm, $this->imgIm, $dst_x$dst_y, 0, 0, $minWidth$minHeight$this->imgInfo['width'], $this->imgInfo['height']);
        }else{
            imagecopyresampled($this->thumbIm, $this->imgIm, $dst_x$dst_y, 0, 0, $maxWidth$maxHeight$this->imgInfo['width'], $this->imgInfo['height']);
        }
    }
    /**
     * cjDir 创建目录
     * @param  string $dir 路径
     * @return bool    
     */
    public function cjDir($dir){
        if(!is_dir($dir)){
            return mkdir($dir,0777,true);
        }else{
            return true;
        }
    }    
    /**
     * open 打开图像
     * @param  string $image 图片路径
     * @return mixed         成功返回图像资源,失败返回false
     */
    public function open($image){
        //判断图像是否存在
        if(!is_file($image)){
            $this->error[]='图像不存在';
            return false;
        }
        //获取图像信息
        /*Array(
            [0] => 1024
            [1] => 400
            [2] => 3     1 = GIF,2 = JPG,3 = PNG,4 = SWF,5 = PSD,6 = BMP,7 = TIFF(intel byte order),8 = TIFF(motorola byte order),9 = JPC,10 = JP2,11 = JPX,12 = JB2,13 = SWC,14 = IFF,15 = WBMP,16 = XBM。
            [3] => width="1024" height="400"
            [bits] => 8 (kb)
            [mime] => image/png    )*/
        //获取图像信息
        $imgInfo=getimagesize($image);
        if($imgInfo==false || empty($imgInfo['bits'])){
            $this->error[]='图像错误';
            return false;
        }
        //判断图像类型
        if(!array_key_exists($imgInfo[2], $this->type)){
            $this->error[]='限制该图像类型';
            return false;
        }
        $this->imgInfo=array(
                'width'=>$imgInfo[0],
                'height'=>$imgInfo[1],
                'type'=>$this->type[$imgInfo[2]],
                'size'=>$imgInfo['bits'],
                'mime'=>$imgInfo['mime']
            );
        //创建大画布 需要判断用那个函数
        $imgType=array(
            'gif'=>'imagecreatefromgif',
            'jpg'=>'imagecreatefromjpeg',
            'png'=>'imagecreatefrompng',
            'bmp'=>'imagecreatefrombmp',
            'wbmp'=>'imagecreatefromwbmp',
            'xbm'=>'imagecreatefromxbm'
            );
        $imgRs=$imgType[$this->imgInfo['type']]($image);
        if($imgRs!==false){
            $this->imgIm=$imgRs;
            return $this->imgIm;
        }else{
            $this->error[]='图像打开失败';
            return false;
        }
    }
    /**
     * waterMark 图像加水印
     * @param  string      $image    需要加水印的图像路径
     * @param  string      $wimg     水印图像路径
     * @param  bool     $cover    是否覆盖原图
     * @param  int         $position 加水印位置(1为左上,2为右上,3为居中,4为左下,5为右下)
     * @param  int         $alpha    透明度(默认40)
     * @return mixed              返回成功加水印图像的路径 失败返回false
     */
    public function waterMark($image,$wimg,$cover=true,$position=5,$alpha=40){
        $this->image=$image;
        if(!is_file($wimg)){
            $this->error[]='水印图不存在';
            return false;
        }
        if($img_im=$this->open($this->image)){
            $img_info=$this->imgInfo;
        }else{
            return false;
        }
        if($wimg_im=$this->open($wimg)){
            $wimg_info=$this->imgInfo;
        }else{
            return false;
        }
        switch ($position) {
            case 1:            //左上
                $dst_x=0;
                $dst_y=0;
                break;
            case 2:            //右上
                $dst_x=$img_info['width']-$wimg_info['width'];
                $dst_y=0;
                break;
            case 3:            //居中
                $dst_x=($img_info['width']-$wimg_info['width'])/2;
                $dst_y=($img_info['height']-$wimg_info['height'])/2;
                break;
            case 4:            //左下
                $dst_x=0;
                $dst_y=$img_info['height']-$wimg_info['height'];
                break;
            case 5:            //右下
                $dst_x=$img_info['width']-$wimg_info['width'];
                $dst_y=$img_info['height']-$wimg_info['height'];
                break;    
            default:
                $this->error[]='参数错误';
        }
        imagecopymergegray($img_im$wimg_im$dst_x$dst_y, 0, 0, $wimg_info['width'], $wimg_info['height'], $alpha);
        if($cover==false){
        //图片重命名
            $pathinfo pathinfo($image); 
            $path str_replace('\\''/'$pathinfo['dirname']);
            $image$path.'/'.basename($this->image,'.'.$img_info['type']).'_w.'.$img_info['type'];
        }
        return $this->save($img_im,$image);
    }
    /**
     * verCode 验证码(可设置生成验证码的长度)
     * @param  int $num  验证码长度
     * @return image     返回生成验证码的图像
     */
    public function verCode($num=4){
        //计算图片的尺寸
        $width=$num*20;
        $height=30;
        //创建图像
        $im=imagecreatetruecolor($width$height);
        //创建颜色
        $gray=imagecolorallocate($im, 200, 200, 200);
        $red=imagecolorallocate($im, 255, 0, 0);
        $black=imagecolorallocate($im, 0, 0, 0);
        //填充颜色
        imagefill($im, 0, 0, $gray);
        //生成随机数
        $str='123456789abcdefghijkmnpqrstuvwxyzABCDEFGHIJKLMNPQRSTUVWXYZ';
        $str=substr(str_shuffle($str),0,$num);
        //随机画黑点
        for$i=1 ; $i<250 ; $i++){
            $x=rand(0,$width);
            $y=rand(0,$height);
            imagesetpixel($im$x$y$black);
        }
        //画干扰线
        $lineColor=imagecolorallocate($im, 80, 80, 80);
        imageline($im, 0, mt_rand(0,30), $width, mt_rand(0,30), $lineColor);
        imageline($im, 0, mt_rand(0,30), $width, mt_rand(0,30), $lineColor);
        imageline($im, 0, mt_rand(0,30), $width, mt_rand(0,30), $lineColor);
        //画边框 
        imagerectangle($im, 0, 0, $width-1, $height-1, $black);
        //写文字
        $font 'C:\Windows\Fonts\arialbi.ttf';
        for ($i=0,$x=0,$y=0; $i $num$i++) { 
            $x=$x+rand(10,18);
            $y=rand(17,24);
            if(!is_file($font)){
                imagestring($im, 5, $x$ysubstr($str,$i,1), $red);
            }else{
                imagettftext($im, 14, 0, $x$y$red$fontsubstr($str,$i,1));
            
        }
        //扭曲文字(正弦曲线 y=Asin(ωx+φ)+k) 搞不懂 高中学的都忘了就不写了
        //输出
        header('content-type:image/jpg');
        imagejpeg($im);
        imagedestroy($im);
        }
        public function getError(){
            return $this->error;
        }
}
?>

常常是最后一把钥匙打开了门