PHP 图像编辑GD库的使用以及图像的压缩

1、php在使用GD库的时候应打开对应的GD库扩展,如下图

2、GD库的开头小案例

imagecreatetruecolor(width, height) 创建一个幕布

imagecolorallocate(handle, red, green, blue) 定义一个颜色

imagecolortransparent(handle, color) 把颜色设置为透明颜色, 第二个参数为imagecolorallocate对象的颜色

imagefill(handle, x, y, color) 填充幕布的颜色

 1 <?php
 2 header('content-type:image/png');
 3 ini_set('display_errors', true);
 4 //创建画布,并且指定宽高
 5 $handle = imagecreatetruecolor(300, 200);
 6 //给画布创建颜色
 7 $bgColor = imagecolorallocate($handle, 200,15,16);
 8 //把颜色从(0,0)点开始填充到画布
 9 imagefill($handle, 0,0, $bgColor);
10 //绘制直线
11 $lineColor = imagecolorallocate($handle, 200,200,200);
12 //参数二表示起点的x轴坐标
13 //参数三表示起点的Y轴坐标
14 //参数四表示终点的x轴坐标
15 //参数五表示终点的Y轴坐标
16 imageline($handle, 0,0,100,200, $lineColor);
17 //输出
18 imagepng($handle);
19 //销毁图像
20 imagedestroy($handle);
21 ?>

 3、使用GD库绘制矩形

<?php
header('content-type:image/png');
ini_set('display_errors', true);
$handle = imagecreatetruecolor(300, 200);
$bgColor = imagecolorallocate($handle, 50, 150, 250);
imagefill($handle, 0, 0, $bgColor);
$rectColor = imagecolorallocate($handle, 232, 16, 16);
//绘制一个描边的矩形
//第二个参数表示
imagerectangle($handle, 50, 50, 150, 150, $rectColor);
//绘制一个填充的矩形
imagefilledrectangle($handle, 180, 50, 280, 150, $rectColor);
imagepng($handle);
imagedestroy($handle);
?>

 4、使用GD库绘制圆形

<?php
header('content-type:image/png');
ini_set('display_errors', true);
$handle = imagecreatetruecolor(400, 200);
$bgColor = imagecolorallocate($handle, 200,20,50);
imagefill($handle, 0, 0, $bgColor);
$color = imagecolorallocate($handle, 132, 209, 73);
//绘制边軭的圆
imageellipse($handle, 100,100, 100, 100, $color);
//绘制填充的圆
imagefilledellipse($handle, 300, 100, 100 ,100, $color);
imagepng($handle);
imagedestroy($handle);
?>

 5、使用图片的复制功能

imagesx($handle)  可以获取图片的宽度

imagesy($handle) 可以获取图片的高度

getimagesize($filename) 可以获取图片的大小,类型等相关的信息

imagecopyresampled($dsimage, $srcimage, $dst_x, $dst_y, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h);  复制图片并且调整大小

<?php
header('content-type:image/png');
ini_set('display_errors', true);
$handle = imagecreatetruecolor(400, 200);
$bgColor = imagecolorallocate($handle, 255, 255, 153);
imagefill($handle, 0, 0, $bgColor);
//获取需要复制的原图
$source = imagecreatefrompng('test.png');
//获取原图的宽
$imagex = imagesx($source);
//获取原图的高
$imagey = imagesy($source);
//执行图片的复制
//参数1表示目标图片
//参数2表示原图资源
//参数3,4表示目标图片起始x,y点
//参数5,6表示原图图片的起始x,y点
//参数7,8表示图片的宽高
imagecopy($handle, $source, 0, 0, 0, 0, $imagex, $imagey);
imagepng($handle);
imagedestroy($handle);
?>

 6、GD库绘制字符串与文字

 imagestring => 不能指定绘制的字体

 imagettftext =>  可以指定绘制的字体

imagepng($handle, $newFileName) 当没有newFileName的时候会以图片的形式输出,当有第二个参数时,会保存到指定的文件里

imagegif,imagejpeg的用法如上

<?php
header('content-type:image/png');
ini_set('display_errors', true);
$handle = imagecreatetruecolor(400, 200);
$bgColor = imagecolorallocate($handle, 255, 200, 10);
imagefill($handle, 0, 0, $bgColor);
$fontColor = imagecolorallocate($handle, 0, 0, 160);
//绘制字体
//参数二表示,字体的大小,但是似乎没有多大的用处
//参数三和参数四表示,字体开始的起点的x轴和Y轴坐标
//参数五表示,需要绘制的内容
//参数六表示,字体的颜色
//注意,因为这个函数不能指定字体以及更多的属性,因此更多的是使用imagettftext这个函数 
imagestring($handle, 100, 10, 10, 'are you ok???',$fontColor);
imagepng($handle);
imagedestroy($handle);
?>
<?php
header('content-type: image/png');
ini_set('display_errors', true);
$handle = imagecreatetruecolor(400, 200);
$bgColor = imagecolorallocate($handle, 200, 230, 20);
imagefill($handle, 0, 0, $bgColor);
$fontColor = imagecolorallocate($handle, 200, 0, 200);
//参数二:表示字体的大小
//参数三:表示字体的旋转角度
//参数四:表示起始的X轴起点
//参数五:表示起始的Y轴起点
//参数六:表示字体的颜色
//参数七:表示字体文件的路径
//参数八:表示渲染的内容
imagettftext($handle, 30, 20, 100, 150, $fontColor, './resource/STHUPO.TTF', 'hello world');
imagepng($handle);
imagedestroy($handle);
?>

 7、GD库绘制弧形

<?php
header('content-type:image/png');
ini_set('display_errors', true);
$handle = imagecreatetruecolor(400, 200);
$bgColor = imagecolorallocate($handle, 200, 200, 10);
imagefill($handle, 0, 0, $bgColor);
$lineColor = imagecolorallocate($handle, 255, 0, 255);
//参数二,三:表示圆心的X轴坐标,Y轴坐标
//参数四,五:表示弧度的宽和高
//参数六,七:表示弧度的起点和终点,(起点表示三点钟方向)
//参数八:表示线条的颜色
imagearc($handle, 100, 100, 100, 100, 0, 180, $lineColor);
//其他参数和上面的函数一样,最后一个参数表示类型,也可以用0表示
imagefilledarc($handle, 300, 100, 100,100, 90, 270, $lineColor,IMG_ARC_PIE);
imagepng($handle);
imagedestroy($handle);
?>

 8、用GD库绘制点

<?php
header('content-type: image/png');
ini_set('display_errors', true);
$handle = imagecreatetruecolor(400, 200);
$bgColor = imagecolorallocate($handle, 200, 200, 150);
imagefill($handle, 0, 0, $bgColor);
for ($i = 0; $i < 10000; $i++) {
    $dotColor = imagecolorallocate($handle, mt_rand(0, 255), mt_rand(0, 255), mt_rand(0, 255));
    //创建点
    //第二个参数和第三个参数分别表示点的x轴和y轴坐标
    //参数四表示点的颜色
    imagesetpixel($handle, mt_rand(0, 400), mt_rand(0, 200), $dotColor);
}
imagepng($handle);
imagedestroy($handle);
?>

 9、封装生成验证码的类

<?php
ini_set('display_errors', true);

class Captcha {
    private $config = [
        'width' => 100,                 //画布的宽
        'height' => 30,                 //画布的高
        'number' => 4,                  //生成随机数的数量
        'font' => './resource/STHUPO.TTF',  //验证码的字体
        'fontSize' => 18,               //字体大小
        'content' => []
    ];
    private $handle;                    //验证码句柄

    public function __construct(array $conf = []) {
        $this->config = array_replace($this->config, $conf);
        empty($this->config['content'])? $this->config['content'] = $this->fillText(): null;           //如果没有内容,那么要创造内容
    }

    public function init() {
        header('content-type: image/png');
        $this->createPng();
        $this->createText();
        $this->createDot();
        $this->createLine();
        imagepng($this->handle);
        imagedestroy($this->handle);
    }

    /**创建文字
     * @return array
     */
    private function fillText() {
        return $content = array_merge(range('a', 'z'), range('A', 'Z'), range(3,9));
    }

    /**
     * 创建幕布
     */
    private function createPng() {
        $this->handle = imagecreatetruecolor($this->config['width'], $this->config['height']);
        $bgColor = imagecolorallocate($this->handle, mt_rand(100, 200), mt_rand(100, 200), mt_rand(100, 200));
        imagefill($this->handle, 0, 0, $bgColor);
    }

    /**
     * 创建字体
     */
    private function createText() {
        $space = $this->config['width'] / (1+$this->config['number']);
        for($i = 0; $i < $this->config['number']; $i ++) {
            $fontColor = imagecolorallocate($this->handle, mt_rand(0,100), mt_rand(0,100), mt_rand(0,100));
            $text = $this->config['content'][mt_rand(0, count($this->config['content'])-1)];
            $height = ($this->config['height'] + $this->config['fontSize']) / 2;
            $width = ($i+1) * $space - $this->config['fontSize'] /2;
            imagettftext($this->handle, $this->config['fontSize'], mt_rand(-30, 30), $width, $height, $fontColor, $this->config['font'], $text);
        }
    }

    /**
     * 画干扰点
     */
    private function createDot() {
        for($i = 0; $i < 100; $i ++) {
            $dotColor = imagecolorallocate($this->handle, mt_rand(0, 255), mt_rand(0, 255), mt_rand(0, 255));
            imagesetpixel($this->handle, mt_rand(0, $this->config['width']), mt_rand(0, $this->config['height']), $dotColor);
        }
    }

    /**
     * 绘制曲直干扰线
     */
    private function createLine() {
        for($i = 0; $i < 5; $i ++) {
            $lineColor = imagecolorallocate($this->handle, mt_rand(0,100), mt_rand(0, 100), mt_rand(0, 100));
            imageline($this->handle, mt_rand(0, $this->config['width']), mt_rand(0, $this->config['height']), mt_rand(0, $this->config['width']), mt_rand(0, $this->config['height']), $lineColor);
            imagearc($this->handle, mt_rand(0, $this->config['width']), mt_rand(0, $this->config['height']), mt_rand(0, $this->config['width']), mt_rand(0, $this->config['height']), mt_rand(0, 360), mt_rand(0, 360), $lineColor);
        }
    }


}

$c = new Captcha([
    'content'=> ['你','我','他', '是', '给'],
//    'fontSize' => 12,
]);
$c->init();

?>

 10、在上传图片上添加水印的类(PHP部份)

<?php
header('content-type:text/html;charset=utf-8');
ini_set('display_errors', true);
class UploadFile {
    private $file;
    private $allowType = ['image/png', 'image/jpg', 'image/jpeg'];
    private $limitSize = 3*1024*1024;
    private $targetPath = 'd:/uploadFile';
    public function __construct() {
        if($_FILES['file']['error'] === 4) {
            die('请上传文件');
        }
        $this->file = $_FILES['file'];
    }

    private function getExtension() {
        return substr(strrchr($this->file['name'], '.'), 1);
    }

    private function getNewFile() {
        $file = sprintf('%s/%s',$this->targetPath, date('Ymd'));
        if(!file_exists($file)) {
            mkdir($file, 0777, true);
        }
        return $file;
    }

    private function getNewFileName() {
        return sprintf('%s/%s.%s', $this->getNewFile(), uniqid('up_', true),$this->getExtension());
    }

    private function checkFileType() {
        $finfo = new finfo(FILEINFO_MIME_TYPE);
        $type =$finfo->file($this->file['tmp_name']);
        return in_array($type, $this->allowType) && in_array($this->file['type'], $this->allowType);
    }

    private function checkFileSize() {
        return $this->file['size'] <= $this->limitSize;
    }

    /**实现图片的水印
     * @param $file
     * @param $newFileName
     * @return bool
     */
    private function printLogo($file, $newFileName) {
        $ext = $this->getExtension();
        $handle = null;
        switch(strtolower($ext)) {
            case 'jpg' || 'jpeg': $handle = imagecreatefromjpeg($file);break;
            case 'png': $handle = imagecreatefrompng($file);break;
        }
        $fontColor = imagecolorallocate($handle, 0, 0, 0);
        imagettftext($handle, 40,-30, 100, 100, $fontColor,'./resource/STHUPO.TTF', 'are you ok???');
        $res = imagejpeg($handle, $newFileName);
        imagedestroy($handle);
        return $res;
    }

    public function init() {
        if(is_uploaded_file($this->file['tmp_name'])) {
            !$this->checkFileType() ? die(sprintf('上传的类型错误,只允许上传%s类型的文件', implode(',', $this->allowType))): null;
            !$this->checkFileSize() ? die(sprintf('上传的大小错误,只允许上传%d大小的文件', $this->limitSize)): null;
            $fileName = $this->getNewFileName();
            if($this->printLogo($this->file['tmp_name'], $fileName)) {
                echo '上传成功';
            } else {
                echo '上传失败';
            }
        } else {
            echo 'unknow';
        }

    }
}

$u = new UploadFile();
$u->init();
?>

html部份

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>test</title>
</head>
<body>
<form action="./test.php" method="post" enctype="multipart/form-data">
    <input type="file" name="file">
    <input type="submit" value="提交">
</form>
</body>
</html>

 11、图像的压缩

 介绍:在图像上传后,一般不直接使用图片,因为图片往往过大,一般通过等比例压缩后再使用

<?php
header('content-type:text/html; charset=utf-8');
ini_set('display_errors', true);

class ThumbPress{
    private $handle;                //原图的句柄
    private $type;                  //文件类型
    private $src_width;             //原图的宽
    private $src_height;            //原图的高
    private $limitType = ['image/png', 'image/jpg', 'image/jpeg', 'image/gif'];
    private $imageCreate = ['imagecreatefrompng', 'imagecreatefromjpeg', 'imagecreatefromjpeg', 'imagecreatefromgif'];
    private $imageOutPut = ['imagepng', 'imagejpeg', 'imagejpeg', 'imagegif'];
    private $config = [
        'width' => 50,
        'height' => 50,
        'text' => '',
        'fontSize' => 20,
        'font' => './resource/STHUPO.TTF',
        'targetFile' => 'd:/uploadFile/thumbImg'
    ];

    public function __construct($conf) {
        $this->config = array_replace($this->config, $conf);
        if(file_exists($this->config['filename']) && in_array($this->type = mime_content_type($this->config['filename']), $this->limitType)) {
            $this->handle = array_combine($this->limitType, $this->imageCreate)[$this->type]($this->config['filename']);
        }
    }

    /**计算缩放比率
     * @return float|int
     */
    private function getScaleBite() {
        $scale = 1;
        $this->src_width = imagesx($this->handle);
        $this->src_height = imagesy($this->handle);
        switch(true) {
            case $this->src_width >= $this->src_height: $scale = $this->src_width / $this->config['width']; break;
            case $this->src_width < $this->src_height: $scale = $this->src_height / $this->config['hegiht']; break;
        }
        return $scale;
    }

    /**创建新图片的幕布
     * @return false|resource
     */
    private function createScreen() {
        $screen = imagecreatetruecolor($this->config['width'], $this->config['height']);
        $color = imagecolorallocate($screen, 255, 255, 255);
        $color = imagecolortransparent($screen, $color);
        imagefill($screen, 0, 0, $color);
        return $screen;
    }

    /**创建图片新名字,生成新地址
     * @return string
     */
    private function createFilePath(): string {
        $name = sprintf('thumb_%s', basename($this->config['filename']));
        if(!file_exists($this->config['targetFile'])) {
            mkdir($this->config['targetFile'], 0777, true);
        }
        return sprintf('%s/%s', $this->config['targetFile'], $name);
    }

    /**打印水印
     * @param $screen
     */
    private function printLogo($screen) {
        if(!$this->config['text']) {
            return;
        }
        $fontColor = imagecolorallocate($screen, 0, 0, 0);
        imagettftext($screen, $this->config['fontSize'], 0, 20, 20, $fontColor, $this->config['font'], $this->config['text']);
    }

    /**压缩图片
     * @return string
     */
    private function imageThumb(): string {
        $screen = $this->createScreen();
        $scale = $this->getScaleBite();
        $newFileName = $this->createFilePath();
        $targetWidth = $this->src_width / $scale;
        $targetHeight = $this->src_height / $scale;
        imagecopyresampled($screen, $this->handle,0,0,0,0, $targetWidth, $targetHeight, $this->src_width, $this->src_height);
        $this->printLogo($screen);
        array_combine($this->limitType, $this->imageOutPut)[$this->type]($screen, $newFileName); //输出图片
        return $newFileName;            //返回新图片的名字
    }

    public function init() {
        if(!$this->handle) {
            return false;
        }
        return $this->imageThumb();
    }
}

?>
原文地址:https://www.cnblogs.com/rickyctbu/p/10924986.html