header-bg.jpg
PHP图像处理之封装一个属于自己的验证码工具类
发表于 2018-01-07 23:50
|
分类于 PHP
|
评论次数 0
|
阅读次数 1505

attachment/2018/01/09/12121515500697.png

一 序

PHP可以轻松快捷地处理多种数据格式,在图像处理上也拥有强大而且简单的实现方式 , 那么如何利用它来制作一张验证码呢? 可以分为以下简单3步:

1 制作背景图片与验证码文字

2 添加干扰图片

3 输出并销毁图片资源

二 需要使用的函数

imagecreatetruecolor( ) 新建一个色图像

?
1
2
3
//顾名思义 创建真彩图像资源
//创建出一副宽x高y的黑色图像
resource imagecreatetruecolor ( int $width , int $height )

imgfill( ) 区域填充

?
1
2
3
//imagefill() 在 image 图像的坐标 x,y(图像左上角为 0, 0)处用 color 颜色执行区域填充
//(即与 x, y 点颜色相同且相邻的点都会被填充)。
bool imagefill ( resource $image , int $x , int $y , int $color )

imagecolorallocate( ) 为一幅图像分配颜色

?
1
2
3
4
5
6
/**
 * imagecolorallocate() 返回一个标识符,代表了由给定的 RGB 成分组成的颜色。
 * red,green 和 blue 分别是所需要的颜色的红,绿,蓝成分。这些参数是 0 到 255 的整数或者十六进制的 0x00 到 0xFF。
 * imagecolorallocate() 必须被调用以创建每一种用在 image 所代表的图像中的颜色。
 */
int imagecolorallocate ( resource $image , int $red , int $green , int $blue )
imagettftext( ) 用 TrueType 字体向图像写入文本
?
1
2
3
4
5
6
7
8
9
10
11
12
/**
 * 使用 TrueType 字体将 指定的 text 写入图像。
 * $image 由图象创建函数(例如imagecreatetruecolor())返回的图象资源。
 * $size 字体的尺寸。根据 GD 的版本,为像素尺寸(GD1)或点(磅)尺寸(GD2)。
 * $angle 角度制表示的角度,0 度为从左向右读的文本。更高数值表示逆时针旋转。例如 90 度表示从下向上读的文本。
 * $x 由 x,y 所表示的坐标定义了第一个字符的基本点(大概是字符的左下角)。
 * $y Y 坐标。它设定了字体基线的位置,不是字符的最底端。
 * $color 颜色索引。使用负的颜色索引值具有关闭防锯齿的效果。见 imagecolorallocate()。
 * $fontfile 是想要使用的 TrueType 字体的路径。
 * $text UTF-8 编码的文本字符串。
 */
array imagettftext ( resource $image , float $size , float $angle , int $x , int $y , int $color , string $fontfile , string $text )

imageline( ) 画一条线段

?
1
2
//imageline() 用 color 颜色在图像 image 中从坐标 x1,y1 到 x2,y2(图像左上角为 0, 0)画一条线段。
bool imageline ( resource $image , int $x1 , int $y1 , int $x2 , int $y2 , int $color )
imagesetpixel( ) 画一个单一像素

?
1
2
//imagesetpixel() 在 image 图像中用 color 颜色在 x,y 坐标(图像左上角为 0,0)上画一个点。
bool imagesetpixel ( resource $image , int $x , int $y , int $color )
imagearc( ) 画椭圆弧

?
1
2
3
//imagearc() 以 cx,cy(图像左上角为 0, 0)为中心在 image 所代表的图像中画一个椭圆弧。w 和 h 分别指定了椭圆的宽度和高度,
//起始和结束点以 s 和 e 参数以角度指定。0°位于三点钟位置,以顺时针方向绘画。
bool imagearc ( resource $image , int $cx , int $cy , int $w , int $h , int $s , int $e , int $color )
imagejpeg( ) || imagepng( ) || imagegif( ) || imagewbmp( ) || imagexbm( ) 输出图象到浏览器或文件

?
1
2
3
//imagepng() 将 GD 图像流(image)以 PNG 格式输出到标准输出(通常为浏览器),
//或者如果用 filename 给出了文件名则将其输出到该文件。
bool imagepng ( resource $image [, string $filename ] )
imagedestroy( ) 销毁一图像

?
1
2
3
//imagedestroy() 释放与 image 关联的内存。
//image 是由图像创建函数返回的图像标识符,例如 imagecreatetruecolor()。
bool imagedestroy ( resource $image )
三 封装验证码类

1 Captcha类

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
<?php
class Captcha {
    //画布资源
    private $img;
    //验证码文字
    private $code = '';
    //验证码字体文件
    public $font;
    //图片宽度
    public $width = 400;
    //图片高度
    public $height = 300;
    //字体大小
    public $size = 50;
    //背景颜色
    public $bgColor = '#ffffff';
    //字体颜色
    public $fontColor;
    //验证码位数
    public $length = 4;
    //验证码种子
    public $seed = '0123456789abcdefghijklmnopqrstuvwxzyABCDEFGHIJKLMNOPQRSTUVWXYZ';
 
    /**
     * 输出验证码图片
     */
    public function show() {
        //验证GD库是否开启
        if( !$this->checkGD() ) {
            return FALSE;
        }
        //设置字体文件路径
        if( empty($this->font) ) {
            $this->font = __DIR__ . '/font.ttf';
        }
        //制作背景与验证码文字
        $this->createCode();
        //添加图片干扰
        $this->createInterference();
        //发送头标明文件类型为image
        header( 'Content-type:image/png' );
        //输出png格式的验证码图片
        imagepng( $this->img );
        //销毁图片资源
        imagedestroy( $this->img );
        exit;
    }

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
/**
 * 制作背景与验证码文字
 */
private function createCode() {
    //创建真彩画板
    $this->img = imagecreatetruecolor( $this->width, $this->height );
    //填充背景颜色
    imagefill( $this->img, 0, 0, hexdec( $this->bgColor ) );
    //生成验证码文字
    for( $i = 0; $i < $this->length; $i++ ) {
        $this->code .= $this->seed [ mt_rand( 0, strlen( $this->seed ) - 1 ) ];
    }
    //将验证码存入session中
    $_SESSION['code'] = $this->code;
    //判断用户是否指定字体颜色
    if( !empty( $this->fontColor ) ) {
        //调色
        $this->fontColor = imagecolorallocate( $this->img, hexdec( substr( $this->fontColor, 1,2 ) ), hexdec( substr( $this->fontColor, 3,2 ) ), hexdec( substr( $this->fontColor, 5,2 ) ) );
        for( $i = 0; $i < $this->length; $i++ ) {
            //逐个输出文字
            imagettftext( $this->img, $this->size, mt_rand( -30, 30 ), $this->width / $this->length * $i + mt_rand( $this->size / 3, $this->size ), ( $this->height + $this->size ) / 2, $this->fontColor, $this->font, $this->code[$i] );
        }
    }else{
        for( $i = 0; $i < $this->length; $i++ ) {
            //随机颜色
            $color = imagecolorallocate( $this->img, mt_rand( 50, 200 ), mt_rand( 50, 200 ), mt_rand(50, 200 ) );
            //逐个输出文字
            imagettftext( $this->img, $this->size, mt_rand( -30, 30 ), $this->width / $this->length * $i + mt_rand( $this->size / 4, $this->size / 3 ), ( $this->height + $this->size ) / 2, $color, $this->font, $this->code[$i] );
        }
    }
}
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
/**
 * 制作图片干扰
 */
private function createInterference() {
    //制作线条方格
    $line_color = "#dcdcdc";
    $color      = imagecolorallocate( $this->img, hexdec( substr( $line_color, 1, 2 ) ), hexdec( substr( $line_color, 3, 2 ) ), hexdec( substr( $line_color, 5, 2 ) ) );
    $l          = $this->height / 5;
    for ( $i = 1;$i < $l;$i ++ ) {
        $step = $i * 5;
        imageline( $this->img, 0, $step, $this->width, $step, $color );
    }
    $l = $this->width / 10;
    for ( $i = 1;$i < $l;$i ++ ) {
        $step = $i * 10;
        imageline( $this->img, $step, 0, $step, $this->height, $color );
    }
    //制作像素点
    $l = $this->width * $this->height / 25;
    for ( $i = 0;$i < $l; $i++ ) {
        $color = imagecolorallocate( $this->img, mt_rand( 0, 255 ), mt_rand( 0, 255 ), mt_rand( 0, 255 ) );
        imagesetpixel( $this->img, mt_rand( 0, $this->width), mt_rand(0, $this->height), $color);
    }
    //制作圆弧
    for ( $i = 0;$i < 5;$i ++ ) {
        // 设置画线宽度
        imagearc( $this->img, mt_rand( 0, $this->width ), mt_rand( 0, $this->height ), mt_rand( 0, $this->width ), mt_rand( 0, $this->height ), mt_rand( 0, 160 ), mt_rand( 0, 200 ), $color );
    }
}
?
1
2
3
4
5
6
/**
 * 验证GD库是否开启
 */
private function checkGD() {
    return extension_loaded('gd') && function_exists("imagepng");
}

2 调用方式 :

?
1
2
3
4
5
6
7
<?php
require './Captcha.php';
$captcha = new Captcha;
$captcha->width = 200;
$captcha->height = 80;
$captcha->size = 30;
$captcha->show();

调用时可指定的属性如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//验证码字体文件路径
$captcha->font = './style.ttf';
//图片宽度
$captcha->width = 400;
//图片高度
$captcha->height = 300;
//字体大小
$captcha->size = 50;
//背景颜色
$captcha->bgColor = '#ffffff';
//字体颜色
$captcha->fontColor = '#000000';
//验证码位数
$captcha->length = 4;
//验证码种子
$captcha->seed = '0123456789abcdefghijklmnopqrstuvwxzyABCDEFGHIJKLMNOPQRSTUVWXYZ';

调用后页面则输出如下图片 :


3 验证方式 :

?
1
2
//验证码的值存放在$_SESSION['code']中 验证用户输入验证码是否正确时 与该值比较即可
if( $_POST['code'] == $_SESSION['code'] ){ echo '验证码输入正确'; }

4 切换换图片 :

?
1
2
3
<!--利用JS更改图片的路径获取新图片 (根据以下两种url的形式 在路径后面增加?或者&) -->
<img src="./code.php" onclick="this.src += '?'">
<img src="?c=user&a=code" onclick="this.src += '&'">
本项目gayhub传送门


发布评论
还没有评论,快来抢沙发吧!