zoukankan      html  css  js  c++  java
  • GD库的基本信息,图像的旋转、水印、缩略图、验证码,以及图像类的封装

    GD库检测

    <?php
    phpinfo();
    ?>

    GD库安装
    • Windows 使用phpstudy

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


    GD库支持的图像格式

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

    图像信息处理

    <?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_proWWWphptestgdfontcomicz.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_proWWWphptestgdfontcomicz.ttf',$str);
    }
    
    header('Content-Type:image/png');
    imagepng($im);

     各种图形绘制

    <?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库检测文件 GDBasic.php

    <?php
    /**
     * GDBasic.php
     * description GD基础类
     */
    
    namespace TestLib;
    
    
    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 TestLib;
    
    require_once 'GDBasic.php';
    
    class Captcha extends GDBasic
    {
        //图像宽度
        protected $_width = 60;
        //图像高度
        protected $_height = 25;
    
        //随机串
        protected $_code = 'ABCDEFGHJKLMNPQRSTUVWXYZ23456789abcdefghjklmnpqrstuvwxyz';
    
        //字体文件
        protected $_font_file = 'D:phpstudy_proWWWphptestgdfontcomicz.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 TestLibCaptcha(80,30);
    
    $captcha->string(6,14)->show();//6位数随机验证码

    逻辑计算验证码演示

    require_once './lib/Captcha.php';
    
    $captcha = new TestLibCaptcha(80,30);
    
    $captcha->logic(12)->show();

    图片类封装 Image.php

    <?php
    /**
     * Image.php
     * author: F.X
     * date: 2017
     * description 图像类
     */
    
    namespace TestLib;
    
    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 TestLibImage('../image/b.png');
    $image->resize(400,200)->save('../image/b_400_200.png');

    按比例缩放+旋转 演示

    require_once './lib/Image.php';
    
    $image = new TestLibImage('../image/b.png');
    $image->resizeByPercent(50)->rotate(1800)->show();
  • 相关阅读:
    最大子列和
    喷水装置
    某种排序
    三个水杯
    奇偶数分离
    ASCII码排序(未完)
    1002
    if语句
    6.7
    A+B问题 涉及EOF
  • 原文地址:https://www.cnblogs.com/chenyingying0/p/12192252.html
Copyright © 2011-2022 走看看