欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

GD库的基本信息,图像的旋转、水印、缩略图、验证码,以及图像类的封装

程序员文章站 2022-12-09 07:55:20
GD库检测 GD库安装• Windows 使用phpstudy • Linux 编译安装 –with-gd• Linux 编译安装扩展 GD库支持的图像格式 使用 gd_info() 函数 检测服务器支持的图像格式 图像信息处理

gd库检测

<?php
phpinfo();
?>

GD库的基本信息,图像的旋转、水印、缩略图、验证码,以及图像类的封装

 

 

 

gd库安装
• windows 使用phpstudy

• linux 编译安装 –with-gd
• linux 编译安装扩展


gd库支持的图像格式

使用 gd_info() 函数 检测服务器支持的图像格式

GD库的基本信息,图像的旋转、水印、缩略图、验证码,以及图像类的封装

 

图像信息处理

 

 

<?php
//获取图像详细信息
$image = '../image/b.png';
$info = getimagesize($image);
var_dump($info);

$string = file_get_contents($image);
$info = getimagesizefromstring($string);
var_dump($info);

//获取图像的文件后缀
$imagetype = image_type_to_extension($info[2],false);
var_dump($imagetype);//string(3) "png"
//获取图像的mime type
$mime = image_type_to_mime_type($info[2]);
var_dump($mime);//string(9) "image/png"
//创建图像
$im = imagecreatefrompng($image);
echo sprintf('a.jpg 宽:%s,高:%s',imagesx($im),imagesy($im));//a.jpg 宽:543,高:299

//根据不同的图像type 来创建图像
switch($info[2])
{
    case 1://imagetype_gif
        $im = imagecreatefromgif($image);
        break;
    case imagetype_jpeg:
        $im = imagecreatefromjpeg($image);
        break;
    case 3:
        $im = imagecreatefrompng($image);
        break;

    default:
        echo '图像格式不支持';
        break;

}

随机显示图片

/**
 * 创建图像
 * 设置背景色
 * 输出图像
 *
 */

//创建图像 imagecreate();
$im = imagecreatetruecolor(200,200);
$back = imagecolorallocate($im,mt_rand(200,255),mt_rand(200,255),mt_rand(200,255));
imagefill($im,0,0,$back);

//设置header mime type
header('content-type:image/png');
imagepng($im,'../image/back.png');

//随机输出图像到浏览器中
$imagelist = array(
    '../image/a.jpg',
    '../image/b.png',
    '../image/back.png'
);

$imagekey = array_rand($imagelist);
$image = $imagelist[$imagekey];
//获取图像信息
$info = getimagesize($image);

//根据图像类别不同 调用不同的创建图像函数
switch($info[2])
{
    case 1://imagetype_gif
        $im = imagecreatefromgif($image);
        break;
    case imagetype_jpeg:
        $im = imagecreatefromjpeg($image);
        break;
    case 3:
        $im = imagecreatefrompng($image);
        break;

    default:
        echo '图像格式不支持';
        break;

}
//设置header mime type
$mimetype = image_type_to_mime_type($info[2]);
header('content-type:'.$mimetype);

//根据image type调用不同的图像输出类型
switch($info[2])
{
    case 1://imagetype_gif
        imagegif($im);
        break;
    case imagetype_jpeg:
        imagejpeg($im,null,60);
        break;
    case 3:
        imagepng($im);
        break;
}

imagedestroy($im);

图像旋转

//旋转图像
$im = imagecreatefrompng('../image/b.png');

$back = imagecolorallocate($im,233,230,232);
$rotate = imagerotate($im,75,$back);

header('content-type:image/jpeg');
imagejpeg($rotate);

缩略图(图片放大缩小)

<?php
/**
 * 缩略图
 *
 */

//创建原图
$srcim = imagecreatefromjpeg('../image/a.jpg');

$srcw = imagesx($srcim);
$srch = imagesy($srcim);

$percent = 0.5;

$desw = $srcw * $percent;
$desh = $srch * $percent;

//创建新图
$desim = imagecreatetruecolor($desw, $desh);

//拷贝图像并调整大小
//imagecopyresized();

//重采样拷贝图像并调整大小
imagecopyresampled($desim, $srcim, 0, 0, 0, 0, $desw, $desh, $srcw, $srch);

//生成图
imagejpeg($desim, "../image/a_{$desw}_{$desh}.jpg", 75);
//imagepng($desim,"../image/a_{$desw}_{$desh}.png");

//生成的图像会自动出现在image文件夹中,不会出现在页面上

图像拷贝(生成水印)

$im = imagecreatefrompng('../image/b.png');

$logo = imagecreatefrompng('../image/logo.png');

//把logo图片从x y开始宽度为w 高度为h的部分图像拷贝到im图像的x y坐标上
imagecopy($im,$logo,400,200,0,0,imagesx($logo),imagesy($logo));

//透明度拷贝
imagecopymerge($im,$logo,400,200,0,0,imagesx($logo),imagesy($logo),10);
header('content-type:image/png');

imagepng($im);

图像中显示文字

//创建画布
$im = imagecreatetruecolor(400,200);
$back = imagecolorallocate($im,mt_rand(200,250),mt_rand(200,250),mt_rand(200,250));
imagefill($im,0,0,$back);

//创建字体颜色
$stringcolor = imagecolorallocate($im,mt_rand(50,150),mt_rand(50,150),mt_rand(50,150));
//图像中水平写入字符串
//imagestring只能使用系统字体
imagestring($im,5,mt_rand(20,imagesx($im)-50),mt_rand(10,imagesy($im)),'hello',$stringcolor);
//垂直写入字符串
//imagestringup($im,5,mt_rand(20,imagesx($im)-50),mt_rand(10,imagesy($im)),'hello',$stringcolor);

header('content-type:image/png');
imagepng($im);

随机四位数验证码

//创建画布
$im = imagecreatetruecolor(400,200);
$back = imagecolorallocate($im,mt_rand(200,250),mt_rand(200,250),mt_rand(200,250));
imagefill($im,0,0,$back);

//生成随机字符串
$string = 'abcdefg123456789abcdefghigk';
$str='';
for($i=0;$i<4;$i++)
{
    $str.= $string[mt_rand(0,strlen($string)-1)];
}

//图像中写入字符串
imagestring($im,5,mt_rand(20,imagesx($im)-50),mt_rand(10,imagesy($im)),$str,$stringcolor);

header('content-type:image/png');
imagepng($im);
imagettftext()可以使用自定义字体,然鹅
使用“imagettftext()”函数时,字体路径要写带盘符的绝对路径,写相对路径就报错
比如改成:
d:\phpstudy_pro\www\phptest\gd\font\comicz.ttf
imagettftext($im,15,mt_rand(-10,10),mt_rand(20,imagesx($im)-50),mt_rand(10,imagesy($im)),$stringcolor,'./font/comicz.ttf',$str);

四色随机验证码

<?php

//创建画布
$im = imagecreatetruecolor(400,200);
$back = imagecolorallocate($im,mt_rand(200,250),mt_rand(200,250),mt_rand(200,250));
imagefill($im,0,0,$back);

//生成随机字符串
$string = 'abcdefg123456789abcdefghigk';

for($i=0;$i<4;$i++)
{
    $stringcolor = imagecolorallocate($im,mt_rand(50,150),mt_rand(50,150),mt_rand(50,150));
    $str = $string[mt_rand(0,strlen($string)-1)];
    //图像中写入字符串
    imagettftext($im,15,mt_rand(-10,10),20+$i*15,100,$stringcolor,'d:\phpstudy_pro\www\phptest\gd\font\comicz.ttf',$str);
}

header('content-type:image/png');
imagepng($im);

GD库的基本信息,图像的旋转、水印、缩略图、验证码,以及图像类的封装

 

 

 各种图形绘制

<?php
/**
 * 图形绘制
 * 绘画复杂图形
 */

//画布
$im = imagecreatetruecolor(400, 200);
$back = imagecolorallocate($im, mt_rand(200, 255), mt_rand(200, 255), mt_rand(200, 255));
imagefill($im, 0, 0, $back);

//画点
$black = imagecolorallocate($im,10,10,10);
for($i=0;$i<150;$i++)
{
    imagesetpixel($im,mt_rand(10,390),mt_rand(10,190),$black);
}

//画线
$red = imagecolorallocate($im, 10, 0, 0);
for($j = 0; $j < 3; $j++)
{
    imageline($im, mt_rand(10, 400), mt_rand(10, 200), mt_rand(10, 400), mt_rand(10, 200), $red);

}

//设置线条粗细
imagesetthickness($im,5);
imageline($im, mt_rand(10, 400), mt_rand(10, 200), mt_rand(10, 400), mt_rand(10, 200), $red);

$style = array($red,$red,$red,$red,$red,$back,$back,$back,$back,$back);

//设置划线的风格
imagesetstyle($im,$style);

//设置划线的风格
imageline($im,10,50,250,200,img_color_styled);

//画矩形
imagerectangle($im,50,50,150,150,$red);

//画圆
imageellipse($im,200,100,100,100,$red);

header('content-type:image/jpeg');
imagejpeg($im, null, 70);

GD库的基本信息,图像的旋转、水印、缩略图、验证码,以及图像类的封装

 

 

 验证码类的封装

gd库检测文件 gdbasic.php

<?php
/**
 * gdbasic.php
 * description gd基础类
 */

namespace test\lib;


class gdbasic
{
    protected static $_check =false;

    //检查服务器环境中gd库
    public static function check()
    {
        //当静态变量不为false
        if(static::$_check)
        {
            return true;
        }

        //检查gd库是否加载
        if(!function_exists("gd_info"))
        {
            throw new \exception('gd is not exists');
        }

        //检查gd库版本
        $version = '';
        $info = gd_info();
        if(preg_match("/\\d+\\.\\d+(?:\\.\\d+)?/", $info["gd version"], $matches))
        {
            $version = $matches[0];
        }

        //当gd库版本小于2.0.1
        if(!version_compare($version,'2.0.1','>='))
        {
            throw new \exception("gd requires gd version '2.0.1' or greater, you have " . $version);
        }

        self::$_check = true;
        return self::$_check;
    }
}

验证码类的文件captcha.php

<?php
/**
 * captcha.php
 * description 验证码类
 */

namespace test\lib;

require_once 'gdbasic.php';

class captcha extends gdbasic
{
    //图像宽度
    protected $_width = 60;
    //图像高度
    protected $_height = 25;

    //随机串
    protected $_code = 'abcdefghjklmnpqrstuvwxyz23456789abcdefghjklmnpqrstuvwxyz';

    //字体文件
    protected $_font_file = 'd:\phpstudy_pro\www\phptest\gd\font\comicz.ttf';

    //图像
    protected $_im;
    //验证码
    protected $_captcha;

    public function __construct($width = null, $height = null)
    {
        self::check();
        $this->create($width, $height);
    }

    /**
     * 创建图像
     * @param $width
     * @param $height
     */
    public function create($width, $height)
    {
        $this->_width = is_numeric($width) ? $width : $this->_width;
        $this->_height = is_numeric($height) ? $height : $this->_height;
        //创建图像
        $im = imagecreatetruecolor($this->_width, $this->_height);
        $back = imagecolorallocate($im, mt_rand(200, 255), mt_rand(200, 255), mt_rand(200, 255));
        //填充底色
        imagefill($im, 0, 0, $back);
        $this->_im = $im;
    }

    /**
     * 混乱验证码
     */
    public function moll()
    {
        $back = imagecolorallocate($this->_im, 0, 0, 0);
        //在图像中随机生成50个点
        for($i = 0; $i < 50; $i++)
        {
            imagesetpixel($this->_im, mt_rand(0, $this->_width), mt_rand(0, $this->_height), $back);
        }

        imageline($this->_im, mt_rand(0, $this->_width), mt_rand(0, $this->_height), mt_rand(0, $this->_width), mt_rand(0, $this->_height), $back);

        imageline($this->_im, mt_rand(0, $this->_width), mt_rand(0, $this->_height), mt_rand(0, $this->_width), mt_rand(0, $this->_height), $back);
    }


    /**
     * 生成验证码随机串
     * @param int $length 验证码的个数
     * @param int $fontsize 字符串的字体大小
     * @return captcha
     */
    public function string($length = 4, $fontsize = 15)
    {
        $this->moll();
        $code = $this->_code;
        $captcha = '';
        for($i = 0; $i < $length; $i++)
        {
            $string = $code[mt_rand(0, strlen($code) - 1)];
            $strcolor = imagecolorallocate($this->_im, mt_rand(100, 150), mt_rand(100, 150), mt_rand(100, 150));
            imagettftext($this->_im, $fontsize, mt_rand(-10, 10), mt_rand(3, 6) + $i * (($this->_width - 10) / $length), ($this->_height / 3) * 2, $strcolor, $this->_font_file, $string);
            $captcha .= $string;
        }

        $this->_captcha = $captcha;
        return $this;
    }


    /**
     * 验证码存入session
     */
    public function setsession()
    {
        if(!isset($_session))
        {
            session_start();
        }
        $_session['captcha_code'] = $this->_captcha;
    }

    /**
     * 逻辑运算符验证码
     * @param int $fontsize 字体大小
     * @return $this
     */
    public function logic($fontsize = 12)
    {
        $this->moll();
        $codearray = array(1 => 1, 2, 3, 4, 5, 6, 7, 8, 9);
        $operatorarray = array('+' => '+', '-' => '-', 'x' => '*');
        list($first, $second) = array_rand($codearray, 2);
        $operator = array_rand($operatorarray);
        $captcha = 0;
        $string = '';
        switch($operator)
        {
            case '+':
                $captcha = $first + $second;
                break;
            case '-':
                //当第一个数小于第二个数
                if($first < $second)
                {
                    list($first, $second) = array($second, $first);
                }
                $captcha = $first - $second;
                break;

            case 'x':
                $captcha = $first * $second;
                break;
        }
        //设置验证码类变量
        $this->_captcha = $captcha;
        //要输出到图像中的字符串
        $string = sprintf('%s%s%s=?', $first, $operator, $second);

        $strcolor = imagecolorallocate($this->_im, mt_rand(100, 150), mt_rand(100, 150), mt_rand(100, 150));
        imagettftext($this->_im, $fontsize, 0, 5, ($this->_height / 3) * 2, $strcolor, $this->_font_file, $string);

        return $this;
    }


    /**
     * 输出验证码
     */
    public function show()
    {
        //生成session
        $this->setsession();
        header('content-type:image/jpeg');
        imagejpeg($this->_im);
        imagedestroy($this->_im);
    }
}

检测gd库演示

//检测gd库
$info = gd_info();
preg_match("/\\d+\\.\\d+(?:\\.\\d+)?/", $info["gd version"], $matches);
var_dump($matches);//0 => string '2.1.0' (length=5)

6位随机数验证码演示

require_once './lib/captcha.php';

$captcha = new \test\lib\captcha(80,30);

$captcha->string(6,14)->show();//6位数随机验证码

GD库的基本信息,图像的旋转、水印、缩略图、验证码,以及图像类的封装

 

 

逻辑计算验证码演示

require_once './lib/captcha.php';

$captcha = new \test\lib\captcha(80,30);

$captcha->logic(12)->show();

GD库的基本信息,图像的旋转、水印、缩略图、验证码,以及图像类的封装

 

 

图片类封装 image.php

<?php
/**
 * image.php
 * author: f.x
 * date: 2017
 * description 图像类
 */

namespace test\lib;

require_once 'gdbasic.php';

class image extends gdbasic
{
    protected $_width;
    protected $_height;
    protected $_im;
    protected $_type;
    protected $_mime;
    protected $_real_path;

    
    public function __construct($file)
    {
        //检查gd库
        self::check();
        $imageinfo = $this->createimagebyfile($file);
        $this->_width = $imageinfo['width'];
        $this->_height = $imageinfo['height'];
        $this->_im = $imageinfo['im'];
        $this->_type = $imageinfo['type'];
        $this->_real_path = $imageinfo['real_path'];
        $this->_mime = $imageinfo['mime'];
    }


    /**
     * 根据文件创建图像
     * @param $file
     * @return array
     * @throws \exception
     */
    public function createimagebyfile($file)
    {
        //检查文件是否存在
        if(!file_exists($file))
        {
            throw new \exception('file is not exits');
        }

        //获取图像信息
        $imageinfo = getimagesize($file);
        $realpath = realpath($file);
        if(!$imageinfo)
        {
            throw new \exception('file is not image file');
        }

        switch($imageinfo[2])
        {
            case imagetype_gif:
                $im = imagecreatefromgif($file);
                break;
            case imagetype_jpeg:
                $im = imagecreatefromjpeg($file);
                break;
            case imagetype_png:
                $im = imagecreatefrompng($file);
                break;
            default:
                throw  new \exception('image file must be png,jpeg,gif');
        }

        return array(
            'width'     => $imageinfo[0],
            'height'    => $imageinfo[1],
            'type'      => $imageinfo[2],
            'mime'      => $imageinfo['mime'],
            'im'        => $im,
            'real_path' => $realpath,
        );

    }

    /**
     * 缩略图
     * @param  int $width 缩略图高度
     * @param  int $height 缩略图宽度
     * @return $this
     * @throws \exception
     */
    public function resize($width, $height)
    {
        if(!is_numeric($width) || !is_numeric($height))
        {
            throw new \exception('image width or height must be number');
        }
        //根据传参的宽高获取最终图像的宽高
        $srcw = $this->_width;
        $srch = $this->_height;

        if($width <= 0 || $height <= 0)
        {
            $desw = $srcw;//缩略图高度
            $desh = $srch;//缩略图宽度
        }
        else
        {
            $srcp = $srcw / $srch;//宽高比
            $desp = $width / $height;

            if($width > $srcw)
            {
                if($height > $srch)
                {
                    $desw = $srcw;
                    $desh = $srch;
                }
                else
                {
                    $desh = $height;
                    $desw = round($desh * $srcp);
                }
            }
            else
            {
                if($desp > $srcp)
                {
                    $desw = $width;
                    $desh = round($desw / $srcp);
                }
                else
                {
                    $desh = $height;
                    $desw = round($desh * $srcp);
                }
            }
        }

        //php版本小于5.5
        if(version_compare(php_version, '5.5.0', '<'))
        {
            $desim = imagecreatetruecolor($desw, $desh);
            if(imagecopyresampled($desim, $this->_im, 0, 0, 0, 0, $desw, $desh, $srcw, $srch))
            {
                imagedestroy($this->_im);
                $this->_im = $desim;
                $this->_width = imagesx($this->_im);
                $this->_height = imagesy($this->_im);
            }
        }
        else
        {
            if($desim = imagescale($this->_im, $desw, $desh))
            {
                $this->_im = $desim;
                $this->_width = imagesx($this->_im);
                $this->_height = imagesy($this->_im);
            }

        }

        return $this;
    }


    /**
     * 根据百分比生成缩略图
     * @param int $percent 1-100
     * @return image
     * @throws \exception
     */
    public function resizebypercent($percent)
    {
        if(intval($percent) <= 0)
        {
            throw new \exception('percent must be gt 0');
        }

        $percent = intval($percent) > 100 ? 100 : intval($percent);

        $percent = $percent / 100;

        $desw = $this->_width * $percent;
        $desh = $this->_height * $percent;
        return $this->resize($desw, $desh);
    }


    /**
     * 图像旋转
     * @param $degree
     * @return $this
     */
    public function rotate($degree)
    {
        $degree = 360 - intval($degree);
        $back = imagecolorallocatealpha($this->_im,0,0,0,127);
        $im = imagerotate($this->_im,$degree,$back,1);
        imagesavealpha($im,true);
        imagedestroy($this->_im);
        $this->_im = $im;
        $this->_width = imagesx($this->_im);
        $this->_height = imagesy($this->_im);
        return $this;
    }


    /**
     * 生成水印
     * @param file $water 水印图片
     * @param int $pct   透明度
     * @return $this
     */
    public function watermask($water ='',$pct = 60 )
    {
        //根据水印图像文件生成图像资源
        $waterinfo = $this->createimagebyfile($water);
        imagecopymerge();
        //销毁$this->_im
        $this->_im = $waterinfo['im'];
        $this->_width = imagesx($this->_im);
        $this->_height = imagesy($this->_im);
        return $this;

    }

    
    /**
     * 图片输出
     * @return bool
     */
    public function show()
    {
        header('content-type:' . $this->_mime);
        if($this->_type == 1)
        {
            imagegif($this->_im);
            return true;
        }

        if($this->_type == 2)
        {
            imagejpeg($this->_im, null, 80);
            return true;
        }

        if($this->_type == 3)
        {
            imagepng($this->_im);
            return true;
        }
    }

    /**
     * 保存图像文件
     * @param $file
     * @param null $quality
     * @return bool
     * @throws \exception
     */
    public function save($file, $quality = null)
    {
        //获取保存目的文件的扩展名
        $ext = pathinfo($file, pathinfo_extension);
        $ext = strtolower($ext);
        if(!$ext || !in_array($ext, array('jpg', 'jpeg', 'gif', 'png')))
        {
            throw new \exception('image save file must be jpg ,png,gif');
        }

        if($ext === 'gif')
        {
            imagegif($this->_im, $file);
            return true;
        }
        if($ext === 'jpeg' || $ext === 'jpg')
        {
            if($quality > 0)
            {
                if($quality < 1)
                {
                    $quality = 1;
                }
                if($quality > 100)
                {
                    $quality = 100;
                }

                imagejpeg($this->_im, $file, $quality);
            }
            else
            {
                imagejpeg($this->_im, $file);
            }
            return true;
        }

        if($ext === 'png')
        {
            imagepng($this->_im, $file);
            return true;
        }

    }
}

指定尺寸缩放 演示

require_once './lib/image.php';

$image = new \test\lib\image('../image/b.png');
$image->resize(400,200)->save('../image/b_400_200.png');

GD库的基本信息,图像的旋转、水印、缩略图、验证码,以及图像类的封装

 

 

按比例缩放+旋转 演示

require_once './lib/image.php';

$image = new \test\lib\image('../image/b.png');
$image->resizebypercent(50)->rotate(1800)->show();