美文网首页
11.GD图像处理

11.GD图像处理

作者: 好像在哪见过你丶 | 来源:发表于2019-05-23 16:13 被阅读0次

    思考:在PHP开发中,应该会经常用到图形处理之类的,那么PHP能够处理图片吗?

    引入:PHP作为一款强大的后台处理语言,操作图片是必不可少的,PHP本身不操作图片,但是可以借助强大的扩展库实现图片的操作。PHP主要使用GD库实现图片操作。

    • 验证码制作
    • 缩略图
    • 水印图

    总结:PHP可以利用GD库进行各种图像操作


    1. 加载GD库【掌握】

    1. GD库作为一种扩展项,需要事先加载才能使用,加载的方式就是在php.ini中开启GD扩展


      加载GD扩展.png
    1. GD库加载后,内置了很多函数供开发人员操作,可以通过操作手册索引中输入image来检索
    操作手册查看GD函数.png
    1. 常用的GD函数列表
    • imagecreatetruecolor:创建一张真彩画布
    • imagecolorallocate:给画布分配颜色
    • imagefill:填充颜色
    • imagestring:水平写字符串(ASCII码)
    • imagettftext:文本写入
    • imageline:制作线段
    • imagecreatefromjpeg:打开一张jpeg图片
    • imagecreatefrompng:打开一张png图片
    • imagecopymerge:拷贝图像合并到另外一张图片资源
    • imagecopyresampled:不失真拷贝图片到另外一张图片资源
    • imagepng:保存或者输出图片,保存格式为png
    • imagejpeg:保存或者输出图片,保存格式为jpeg
    • imagedestroy:销毁资源
    • getimagesize:取得图片信息
    • pathinfo:得到文件信息

    总结

    1. GD库提供了很多函数来处理图片
    2. 根据不同的需求可以使用不同的函数来完成对应的功能
    3. 列出了制作验证码、水印和缩略图所需要的常用函数

    思考:验证码图片是怎么做成的呢?

    引入:在开发中,几乎所有的网站都有用到验证码功能,验证码不是一个简单的字符串,通常都是将字符串放到图片上,而且加上很多干扰内容来完成。

    2. 制作验证码【掌握】

    定义验证码(CAPTCHA)是“Completely Automated Public Turing test to tell Computers and Humans Apart”(全自动区分计算机和人类的图灵测试)的缩写 ,是一种区分用户是计算机还是人的公共全自动程序。验证码由最初的简单字符串到现在各式各样复杂的图片、计算、问题等,只是因为计算机识别的功能已经越来越强大。

    1. 验证码制作流程
    • 制作画布:imagecreatetruecolor
    • 填充背景色:imagecolorallocate分配颜色,imagefill填充颜色
    • 写入内容:imagestring写简单内容,imagettftext写入字体文字
    • 增加干扰:imageline增加线段,imagestring增加其他符号
    • 保存图片:imagepng输出或者保存图片
    1. 简单图片制作
    <?php
    //制作简单图片
    
    //1.创建画布
    $img = imagecreatetruecolor(200,200);   //宽度和高度,像素单位,得到画布资源
    
    //2.输出图片
    header('content-type:image/png');
    imagepng($img);                       //所有gd函数都需要图片资源
    
    //3.销毁资源
    imagedestroy($img);
    
    1. 简单验证码制作
    <?php
        
    //制作简单验证码图片
        
    //1.创建画布资源
    $img = imagecreatetruecolor(100,30);
    
    //2.填充背景色
    //2.1给画布分配背景颜色
    $bg_color = imagecolorallocate($img,255,255,255);   #RGB三色组,纯白色
    
    //2.2填充颜色
    imagefill($img,0,0,$bg_color);                     #从0,0坐标处开始上色,自动渲染相同颜色像素点
    
    //3.写入字符串
    //3.1给要写入的字符串分配颜色
    $str_color = imagecolorallocate($img,150,150,150);  #比背景颜色稍深
    //3.2写入文字
    imagestring($img,5,30,10,'capcha',$str_color);
    
    //4.保存输出
    //4.1保存
    imagepng($img,'captcha.png');                      #保存到当前文件夹captcha.png
    //4.2输出
    header('content-type:image/png');
    imagepng($img);
    
    //5.销毁资源
    imagedestroy($img);
    
    1. 封装简单验证码制作函数
    <?php
    //封装验证码制作函数
    
    /*
     * 验证码制作函数
     * @param1 int $width 图片宽度
     * @param2 int $height 图片高度
     * @param3 int $lines = 10,干扰线数量,默认10条
     * @param4 int $length = 4 字符串长度,默认4个简单字符
     
    */
    function getCaptcha($width,$height,$lines = 10,$length = 4){
        //1.制作画布
        $img = imagecreatetruecolor($width,$height);
        
        //2.填充背景
        $bg_c = imagecolorallocate($img,mt_rand(200,255),mt_rand(200,255),mt_rand(200,255)); #随机淡色
        imagefill($img,0,0,$bg_c);
        
        //3.制作随机字符串
        $str_arr = range('A','Z');          #得到A-Z数组元素
        shuffle($str_arr);                  #打乱数组元素
        
        //定义一个字符串保留取出的所有字母
        $captcha = '';
        //循环取元素即可
        for($i = 0;$i < $length; $i++){
            //每取出一个符号就保留到$captcha
            $captcha .= $str_arr[$i];       #取乱序数组前4个元素
        }
        
        //写入图片
        $str_c = imagecolorallocate($img,mt_rand(0,100),mt_rand(0,100),mt_rand(0,100)); #随机深色
        imagestring($img,5,30,10,$captcha,$str_c);
        
        //4.制作干扰元素
        //循环制作多条
        for($i = 0;$i < $lines;$i++){
           $line_c = imagecolorallocate($img,mt_rand(120,180),mt_rand(120,180),mt_rand(120,180)); #中间颜色,每条颜色都不一样
            imageline($img,mt_rand(0,$width),mt_rand(0,$height),mt_rand(0,$width),mt_rand(0,$height),$line_c); #随机起始位置
        }
        
        //5.输出图片
        header('content-type:image/png');
        imagepng($img);
        
        //6.销毁资源
        imagedestroy($img);
    }
    

    总结

    1. 验证码指的是印在图片上的随机字符
    2. 验证码图片的制作流程:画布->背景色->随机字符串->写入字符串->干扰->输出图片->销毁画布
    3. 验证码的功能可以很丰富,需要使用更加复杂的函数和逻辑

    思考:随着版权意识越来越高,很多人已经开始给自己的图片做了版权保护处理,就是在上面增加了一些若影若现的文字或者图片,这个怎么实现呢?

    引入:图片上加入内容,其实就是制作水印的一个过程。验证码也可以理解为是一个带文字水印的图片。更多的水印是通过放置一张图片到上面来实现的。

    3. 制作水印图片【掌握】

    定义:制作水印图片,就是往一张图片上放入一些文字或者图片元素,在不是特别影响原图的使用的前提下,又能有版权追溯(防止别人盗图商用)。

    1. 水印制作流程(图片版)
    • 打开原图:imagecreatefromjpeg/png,从jpeg(基本上都是)打开原图资源
    • 打开水印图:与原图一样,只是图片通常是png
    • 复制水印图合并到原图上:imagecopymerge
    • 保存图片:imagejpeg/png
    • 关闭资源
    1. 实现水印图(原图desktop.jpg,水印图php.png)
    <?php
    //制作水印图
    
    //1.打开要添加水印图的资源
    $dst = imagecreatefromjpeg('desktop.jpg');
    
    //2.打开水印图片资源
    $src = imagecreatefrompng('php.png');
    
    //3.采样复制合并:全部水印图放到原图左上角
    $src_info = getimagesize('php.jpg'); #获取图片信息返回数组,0元素为宽,1元素为高
    imagecopymerge($dst,$src,0,0,0,0,$src_info[0],$src_info[1],50); #透明度50
    
    //4.保存图片
    header('content-type:image/jpeg');
    imagejpeg($dst);
    imagejpeg($dst,'water.jpg');
    
    //5.销毁资源
    imagedestroy($dst);
    imagedestroy($src);
    
    1. 封装水印图制作函数
    <?php
        
    //封装水印图制作函数
    /*
     * 制作水印图
     * @param1 string $image,要添加水印的图片地址
     * @param2 string $path,水印图制作完成后存储路径
     * @param3 string $water,水印图图片地址
     * @param4 int $pct = 50,透明度,默认50
     * @return string 新生成图片的名字
    */
    function getWatermark($image,$path,$water,$pct = 50){
        //1.打开原图资源
        $dst = imagecreatefromjpeg($image);
        
        //2.打开水印图资源
        $src = imagecreatefrompng($water);
        
        //3.采样复制合并:存放到做上角(不需要计算)
        $src_info = getimagesize($water);       
        imagecopymerge($dst,$src,0,0,0,0,$src_info[0],$src_info[1],$pct);
        
        //4.保存图片
        //获取原图片路径和名字信息
        $image_info = pathinfo($image); #返回数组:extension是后缀名,filename是纯名字
        //拼凑新文件名字
        $water_name = $image_info['filename'] . '_water' . '.' . $image_info['extension'];
        imagejpeg($dst,$path . '/' . $water_name);
        
        //5.销毁资源
        imagedestroy($dst);
        imagedestroy($src);
        
        //6.返回文件名
        return $water_name;
    }
    

    总结

    1. 水印图分为文字水印图(验证码)和图片水印图
    2. 水印图的制作流程:打开原图->打开水印图->采样复制合并->保存图片->销毁资源
    3. 水印图不像验证码,一般是规定位置规定水印图样章的

    思考:在很多网站上,上传图片的时候都会有个小图可以看的,那么是怎么实现的呢?

    引入:其实小图的本质并不是用户上传的,而是系统根据系统需求在用户上传原图的时候,制作的一个小图。这个小图就是缩略图。

    4. 制作缩略图【掌握】

    定义:制作缩略图,就是将原图放到一个固定的大小的图片资源里,形成一张新的图片。通常是把大图做成小图,因此叫做缩略图。

    1. 缩略图制作原理
    • 打开原图资源:imagecreatefromjpeg
    • 创建缩略图资源:imagecreatetruecolor
    • 采样复制合并:imagecopyresampled(不失真)
    • 保存缩略图资源:imagejpeg(较多)
    • 销毁资源
    1. 实现缩略图
    <?php
        
    //制作缩略图
    //1.打开原图资源
    $src = imagecreatefromjpeg('desktop.jpg');
    
    //2.创建缩略图资源
    $dst = imagecreatetruecolor(100,100);
    
    //3.采样复制合并
    $src_info = getimagesize('desktop.jpg');
    imagecopyresampled($dst,$src,0,0,0,0,100,100,$src_info[0],$src_info[1]);
    
    //4.保存输出
    header('content-type:image/jpeg');
    imagejpeg($dst);
    imagejpeg($dst,'desktop_thumb.jpg');
    
    //5.销毁资源
    imagedestroy($src);
    imagedestroy($dst);
    
    1. 缩略图注意事项:原图与缩略图比例不一样采用全部填充满,会导致缩略图“变形”,这种时候的解决方案如下
    • 求出原图的宽高比
    • 求出缩略图的宽高比
    • 比较原图的宽高比和缩略图的宽高比
      • 原图宽高比大于缩略图宽高比,说明原图太宽,应该让缩略图的宽占满,高按比例求出来
      • 原图宽高比小于缩略图宽高比,说明原图太高,应该让缩略图的高占满,宽按比例求出来
    • 不管哪种情况,势必会有缩略图部分区域没有放上内容,这个时候缩略图背景填充为白色(补白)
    • 根据计算出来的实际宽高像素,将图片居中到缩略图中
    1. 制作缩略图函数(补白)
    <?php
        
    //制作补白效果缩略图
    
    /*
     @param1 string $image,原图地址
     @param2 string $path,缩略图存储路径
     @param3 int $width = 100,缩略图宽
     @param4 int $height = 100,缩略图高
    */
    function getThumb($image,$path,$width = 100,$height = 100){
        //1.打开原图资源
        $src = imagecreatefromjpeg($image);
        
        //2.创建缩略图画布
        $thu = imagecreatetruecolor($width,$height);
        
        //3.补白:背景填充白色
        $white = imagecolorallocate($thu,255,255,255);
        imagefill($thu,0,0,$white);
        
        //4.计算缩略图所放图片的实际宽和高:通过原图宽高比和缩略图宽高比来比较
        $src_info = getimagesize($image);
        
        //原图宽高比
        $src_c = $src_info[0] / $src_info[1];
        $thu_c = $width / $height;
        
        //判定
        if($src_c > $thu_c){
            #原图宽高比大于缩略图,说明原图很宽,那么缩略图中宽度应该占满
            $thu_w = $width;    #占满缩略图宽
            $thu_h = ceil($thu_w / $src_c); #取整
        }else{
            #原图宽高比小于缩略图,说明原图很高,那么缩略图中高度应该占满
            $thu_h = $height;
            $thu_w = ceil($thu * $src_c);
        }
        
        //5.采样复制粘贴:还需让缩略图居中
        $x = ceil(abs($thu_w - $width) / 2);    //绝对值除以2取整
        $y = ceil(abs($thu_h - $height) / 2);
        imagecopyresampled($thu,$src,$x,$y,0,0,$thu_w,$thu_h,$src_info[0],$src_info[1]);
        
        //6.保存图片
        $image_info = pathinfo($image);
        //构造新文件名字
        $newname = $image_info['filename'] . '_thumb' . '.' . $image_info['extension'];
        
        imagejpeg($thu,$path . '/' . $newname);
        
        //7.销毁资源
        imagedestroy($src);
        imagedestroy($thu);
        
        //8.返回结果
        return $newname;
    }
    

    总结

    1. 缩略图是在用户上传原图的时候系统根据需求自动生成的
    2. 缩略图要保证与原图比例一致,就需要进行缩略图中图片实际的尺寸,并进行补白

    相关文章

      网友评论

          本文标题:11.GD图像处理

          本文链接:https://www.haomeiwen.com/subject/lyrbzqtx.html