Linfinity

Never say never.
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

php图像处理

Posted on 2019-01-07 23:15  Linfinity  阅读(171)  评论(0)    收藏  举报

一、PHP图像处理技术

1.1 图像处理基本介绍

所谓的PHP图像处理技术,就是通过php的函数进行绘制图像,然后可以输出到浏览器,也可以保存到本地

 

该绘图技术,需要开启php的一个扩展:GD2,该扩展提供了很多绘制图像的方法

 

PHP的图像处理技术的应用场景:

验证码(在图像上面绘制一些文字,人类很容易辨别出来,但是计算机脚本以目前的技术辨别图像中的字符是有很大的难度)

图像的压缩(;例如上传头像时,本地的图片很大,但是上传到服务器之后,会针对大图进行压缩处理)

 

1.2 PHP绘图坐标体系

在编程世界中坐标体系和我们上学时数学里面的坐标体系不一样的

 

1.3 PHP绘图的基本步骤

 

  1. 先在内存中,创建图像资源(理解成画布):imagecreatetruecolor
  2. 给画布分配颜色(默认画布的颜色是真空的黑色):imagecolorallocate()
  3. 给画笔分配颜色 imagecolorallocate
  4. 开始绘制 imageline
  5. 直接在浏览器输出、保存到本地:header()   imagepng()
  6. 销毁画布资源 imagedestroy()

 

1.4 PHP绘图的具体演示

(1)绘制线条  imageline()

 

(2)绘制三角形:imageline()

 

(3)绘制矩形:imagerectangle()imagefilledrectangle()

描边矩形:imagerectangle()

填充矩形:imagefilledrectangle()

 

(4)绘制圆形 椭圆形:imageellipse() imagefilledellipse()

描边圆形:imageellipse

填充圆形:imagefilledellipse

 

(5)将图片绘制到画布上:imagecopy()

 

(6)绘制字符串:imagestring()  (不常用,不可选字体,角度等。。。)

 

(7)绘制文字:imagettftext()   

可以指定使用哪个字体来绘制文字

 

(8)绘制弧形:imagearc()

说明:三点钟的位置是起点(0度)

 

 

二、PHP图像处理技术应用

 

2.1 验证码的使用

 

验证码(CAPTCHA)是“Completely Automated Public Turing test to tell Computers and Humans Apart”(全自动区分计算机和人类的图灵测试)的缩写,是一种区分用户是计算机还是人的公共全自动程序。可以防止:恶意破解密码、注册刷票、论坛灌水,有效防止某个黑客对某一个特定注册用户用特定程序暴力破解方式进行不断的登陆尝试

 

 

2.2 封装验证码类

<?php
/*
 * 封装验证码类
 */
class Captcha
{
    //成员属性
    private $width = 100;   //画布的宽度
    private $height = 30;   //画布的高度
    private $number = 4;    //验证码的字符个数
    private $font_file = 'STHUPO.TTF';  //验证码的字体文件
    private $font_size = 20;    //验证码的字体大小
    
    public function __set($p,$v)
    {
        if(property_exists($this, $p)){
           $this -> $p = $v; 
        }
    }
    public function __get($p)
    {
        if(property_exists($this, $p)){
            return $this -> $p;
        }
    }
    //开始绘制验证码
    public function makeImage()
    {
        //1. 创建画布,背景颜色应该是随机产生的,尽量背景颜色浅一点
        $image = imagecreatetruecolor($this->width, $this->height);
        //2. 分配颜色        
        $color = imagecolorallocate($image, mt_rand(100,255), mt_rand(100,255), mt_rand(100,255));
        imagefill($image, 0, 0, $color);
        
        //3. 开始绘制文字
        $code = $this->makeCode();
        for($i=0;$i<strlen($code);$i++){
            imagettftext($image, $this->font_size, mt_rand(-30,30), ($this->width/$this->number)*$i+5, 20, mt_rand(0,100), $this->font_file, $code[$i]);
            
        }        
        //绘制100个干扰像素点
        for($i=0;$i<100;$i++){
            imagesetpixel($image, mt_rand(0,$this->width), mt_rand(0,$this->height), mt_rand(0,100));
        }
        
        //练习:绘制10条干扰线条
        for($i=0;$i<10;$i++){
            $color = imagecolorallocate($image, mt_rand(100,150), mt_rand(100,150), mt_rand(100,150));
            imageline($image, mt_rand(0,$this->width), mt_rand(0,$this->height), mt_rand(0,$this->width), mt_rand(0,$this->height), $color);
        }
        
        //3. 输出到浏览器
        header("Content-Type:image/png");
        imagepng($image);
        //4. 销毁图像资源
        imagedestroy($image);
    }
    //生成随机的字符
    public function makeCode()
    {
        //大写字母,range()用来生成一个数组,包含从指定的开始字符到结束字符范围内的元素的数组
        $upper = range('A','Z');
        //小写字母
        $lower = range('a','z');
        //数字,避免0、1、2
        $number = range(3,9);
        //把3个数组合并成一个数组
        $code = array_merge($lower,$upper,$number);
        //打乱数组顺序
        shuffle($code);
        //根据属性中指定的字符个数,创建字符
        $str = '';
        for($i=0;$i<$this->number;$i++){
            $str .= $code[$i];
        }
        //echo '<pre>';
        //var_dump($str);
        return $str;
    }   
    
}

$captcha = new Captcha();
$captcha -> makeImage();
Captcha.class.php

 

 

三、PHP图像压缩处理

 

3.1 图像压缩介绍

 

我们之前学习过文件的上传(上传一个头像),但是上传的文件不能直接使用的,因为本地的文件可能会很大,在前端页面显示的时候,就会加载很长时间,所以我们通常会先压缩再使用

 

通常压缩的时候,一般是按照等比例压缩,所谓的等比例压缩就是宽度、高度同时压缩相同的比例,在实际开发的时候,我们通常会根据具体的需要(前端页面的需求)在指定的范围内进行等比例压缩

 

3.2 图像压缩入门案例

图像压缩非常简单,就是一个php的图像处理函数:imagecopyresampled

该函数有10个参数:

 

<?php
//制作缩略图、图像压缩
//参数1:目的地图像资源(通常指的是画布资源)
$dst_image = imagecreatetruecolor(100, 100);
$color = imagecolorallocate($dst_image, 22, 139, 0);
imagefill($dst_image, 0, 0, $color);
//参数2:原图资源(将该图片资源压缩之后,再保存到目的地画布中)
$src_image = imagecreatefrompng('bs.png');
//参数3、4:目的地(画布的起点坐标)
$dst_x = 0;
$dst_y = 0;
//参数5、6:原图的(起点坐标)
$src_x = 0;
$src_y = 0;
//参数7、8:目的地(画布的宽度、高度)
$dst_w = 100;
$dst_h = 100;
//参数9、10:原图的宽度、高度
//通过imagesx()函数获得图像资源的宽度、imagesy()获得图像资源的高度

$src_w = imagesx($src_image);
$src_h = imagesy($src_image);
imagecopyresampled($dst_image, $src_image, $dst_x, $dst_y, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h);

//可以保存、也可以输出到浏览器
//1. 直接在浏览器输出
header("Content-Type:image/png");
imagepng($dst_image);

//2. 保存到本地,只需要给imagepng()函数增加第二个参数(保存地址)即可
//imagepng($dst_image,'./thumb_bs.png');

 

 

3.3 图像压缩处理类

<?php
/*
 * 图像压缩
 */
class Thumb
{
    //成员属性
    private $file;          //原图文件
    private $thumb_path;    //压缩文本件保存的地址
    //创建原图资源的函数(文件的mime类型和创建资源的映射关系)
    private $create_func = array(
        'image/png'  =>  'imagecreatefrompng',
        'image/jpeg' =>  'imagecreatefromjpeg',
        'image/gif'  =>  'imagecreatefromgif'
    );
    //保存图像资源的函数
    private $output_func = array(
        'image/png'  =>  'imagepng',
        'image/jpeg' =>  'imagejpeg',
        'image/gif'  =>  'imagegif'
    );
    //图像的mime类型
    private $mime;
    
    public function __set($p,$v)
    {
        if(property_exists($this, $p)){
            $this->$p = $v;
        }
    }
    public function __get($p)
    {
        if(property_exists($this, $p)){
            return $this->$p;
        }
    }
    
    //构造函数用来初始化属性
    public function __construct($file)
    {
        if(!file_exists($file)){
            echo '文件无效,请选择正确的文件';
            exit;
        }
        //执行到中这里,说明文件有效
        $this->file = $file;
        $this->mime = getimagesize($file)['mime'];
    }
    
    //参数1:压缩的范围宽度
    //参数2:压缩的范围的高度
    function makeThumb($area_w,$area_h)
    {    
        //参数2:原图资源(将该图片资源压缩之后,再保存到目的地画布中)
        $create_func = $this->create_func;
        $src_image = $create_func[$this->mime]($this->file);
        //参数3、4:目的地(画布的起点坐标)
        $dst_x = 0;
        $dst_y = 0;
        //参数5、6:原图的(起点坐标)
        $src_x = 0;
        $src_y = 0;
        //参数9、10:原图的宽度、高度
        //通过imagesx()函数获得图像资源的宽度、imagesy()获得图像资源的高度
        $src_w = imagesx($src_image);
        $src_h = imagesy($src_image);
    
        //参数7、8:目的地(画布的宽度、高度)
        //计算压缩的比例
        if($src_w / $area_w >= $src_h / $area_h){
            $scale = $src_w / $area_w;
        }else{
            $scale = $src_h / $area_h;
        }
    
        $dst_w = (int)$src_w / $scale;
        $dst_h = (int)$src_h / $scale;
    
    
        //参数1:目的地图像资源(通常指的是画布资源)
        $dst_image = imagecreatetruecolor($dst_w, $dst_h);
        $color = imagecolorallocate($dst_image, 255, 255, 255);
        $color = imagecolortransparent($dst_image,$color);
        
        imagefill($dst_image, 0, 0, $color);
    
    
        imagecopyresampled($dst_image, $src_image, $dst_x, $dst_y, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h);
    
        //可以保存、也可以输出到浏览器
        //1. imagepng()增加第二个参数表示保存文件
        //通常会把压缩之后的图片保存到thumb子目录中,按照日期格式的子目录保存
        $sub_path = date('Ymd').'/';
        $path = $this -> thumb_path;
        if(!is_dir($path.$sub_path)){
           mkdir($path.$sub_path,0777,true); 
        }
        
        //压缩的图像的文件名,在原文件名的基础上增加前缀:thumb_bs.png
        $origin_filename = basename($this->file);
        $thumb_name = 'thumb_'.$origin_filename;
        
        //header("Content-Type:image/png");
        $output_func = $this->output_func;
        $output_func[$this->mime]($dst_image,$path.$sub_path.$thumb_name);
        
        //最后,一定要把文件地址返回(接收之后最后保存起来)
        return $sub_path.$thumb_name;
    }
}

$thumb = new Thumb('bs.png');
$thumb -> thumb_path = 'thumb/';
$file = $thumb -> makeThumb(50, 50);
var_dump($file);
Thumb.class.php