作者

概述

GD 库是 php 处理图形的扩展库,GD 库提供了一系列用来处理图片的 API ,使用 GD 库可以处理图片,或者生成图片,也可以给图片加水印。在网站上 GD 库通常用来生成缩略图,或者用来对图片加水印,或者用来生成汉字验证码,或者对网站数据生成报表等。

配置

php.ini 配置文件中开启 GD 扩展即可使用

extension=php_gd2.dll    // 把前面的分号去掉

画布实现

实现画布所用到的函数:

名称、格式 注解
imageline($img , 起始位置x1 , 起始位置y1 , 结束位置x2 , 结束位置y2 , 颜色 ) 用颜色在图像 img 中从坐标 x1y1x2y2(图像左上角为 0, 0)画一条线段。
imagestring($img,字体,起始位置x,起始位置y,字符串,颜色) 用颜色将字符串画到 img 所代表的图像的 xy 坐标处
imagepng($img [,string $filename]) PNG 格式输出,如果用 filename 给出了文件名则将其输出到该文件
imagejpeg($img [,string $filename[,int $quality]]) filename 为文件名创建一个 JPEG 图像
imagedestroy($img) 释放与 img 关联的内存

首先,我们来画一个红色的正方形:

$image = imagecreatetruecolor(100, 100);    //创建100*100的画布
$red = imagecolorallocate($image, 255,0, 0); //设置一个颜色变量为红色
imagefill($image, 0, 0, $red);              //将背景颜色设置为红色
header('Content-type:image/png');
imagepng($image);
imagedestroy($image);

画一个线条和字符串:

$img = imagecreatetruecolor(100, 100);                  //创建空白图片
$red = imagecolorallocate($img, 0xFF, 0x00, 0x00);      //创建画笔
imageline($img, 0, 0, 100, 100, $red);                  //绘制线条

//imagestring($img, 5, 0, 13, "huangdj", $red);         // 绘制字符串

header("content-type: image/png");                      //输出图像到页面
imagepng($img);
imagejpeg($img, 'img.jpg', 100);                // 将图片保存到文件,直接可以打开,也可以用imagepng()函数保存为PNG格式的图片

imagedestroy($img);                             //释放图片资源

图片缩放

function thumb($filename, $width = 200, $height = 200)
{
    //获取原图像$filename的宽度$width_orig 和 高度$height_orig
    list($width_orig, $height_orig) = getimagesize($filename);
    //根据参数$width和$height值,换算出等比例缩放的高度和宽度
    if ($width && ($width_orig < $height_orig)) {
        $width = ($height / $height_orig) * $width_orig;
    } else {
        $height = ($width / $width_orig) * $height_orig;
    }

    //将原图缩放到这个新创建的图片资源中
    $image_p = imagecreatetruecolor($width, $height);
    //获取原图的图像资源
    $image = imagecreatefromjpeg($filename);

    //使用imagecopyresampled函数进行缩放设置
    imagecopyresampled($image_p, $image, 0, 0, 0, 0, $width, $height, $width_orig, $height_orig);

    //将缩放后的图片$image_p保存,100为最佳质量,文件最大
    imagejpeg($image_p, $filename, 100);
    imagedestroy($image_p);
    imagedestroy($image);
}

thumb("./go.jpg", 100, 100);

图片居中裁剪

function cut($filename, $width, $height)
{
    list($width_orig, $height_orig) = getimagesize($filename);

    //如果原始图片的宽小于等于你传的宽
    if ($width_orig <= $width) {
        $x = 0;
        $width = $width_orig;    //取原始宽
    } else {
        $x = $width_orig / 2 - $width / 2;  //找宽的原点
    }

    //如果原始图片的高小于等于你传的高
    if ($height_orig <= $height) {
        $y = 0;
        $height = $height_orig;     //取原始高
    } else {
        $y = $height_orig / 2 - $height / 2;  //找高的原点
    }

    $back = imagecreatefromjpeg($filename);  //创建背景图片资源
    $cutimg = imagecreatetruecolor($width, $height);    //创建一个可以保存裁剪后的图片资源
    imagecopyresampled($cutimg, $back, 0, 0, $x, $y, $width, $height, $width, $height);
    header("content-type: image/jpeg");
    $path = pathinfo($filename);     //获取原图的信息

    //拼接一个新的文件名用于保存裁剪过后的图片
    $new_name = basename($filename, '.' . $path['extension']) . "_cut." . $path["extension"];
    imagejpeg($cutimg, $new_name);

    imagedestroy($cutimg);
    imagedestroy($back);
}

cut('./123.jpg', 600, 400);

添加水印(图片水印)

function watermark($filename, $water)
{
    list($b_w, $b_h) = getimagesize($filename);
    list($w_w, $w_h) = getimagesize($water);
    $postX = rand(0, ($b_w - $w_w));
    $postY = rand(0, ($b_h - $w_h));

    $back = imagecreatefromjpeg($filename);
    $water = imagecreatefromgif($water);

    imagecopy($back, $water, $postX, $postY, 0, 0, $w_w, $w_h);

    imagejpeg($back, $filename);
    imagedestroy($back);
    imagedestroy($water);
}

watermark("./123.jpg", "./111.gif");

生成验证码(数字类型)

$img = imagecreatetruecolor(100, 40);
$black = imagecolorallocate($img, 0x00, 0x00, 0x00);
$green = imagecolorallocate($img, 0x00, 0xFF, 0x00);
$white = imagecolorallocate($img, 0xFF, 0xFF, 0xFF);
imagefill($img, 0, 0, $white);    //绘制底色为白色
//绘制随机的验证码
$code = '';
for ($i = 0; $i < 4; $i++) {
    $code .= rand(0, 9);
}
imagestring($img, 6, 13, 10, $code, $black);
//加入噪点干扰
for ($i = 0; $i < 50; $i++) {
    imagesetpixel($img, rand(0, 100), rand(0, 100), $black);
    imagesetpixel($img, rand(0, 100), rand(0, 100), $green);
}
//输出验证码
header("content-type: image/png");
imagepng($img);
imagedestroy($img);

练习

使用上面所学,自行完成如下要求的验证码

1、带数字字母区分大小写,随机取4个值

2、画布背景为白色,验证码字体为黑色,宽(100)高(40)

3、加入噪点和横线干扰

表单中应用验证码

本案例包含用户输入表单和匹配验证码两部分,在表单中获取并显示验证码图片,如果验证码看不清楚,可以通过单击它重新获取一张,按照验证码图片中显示的 文字输出后,提交给 PHP 端验证,从客户端中接收到的验证码与服务器中保留的验证码相同,则提交成功。

1、首先在项目根目录下创建 imageCode.php 文件,添加如下代码:

<?php
session_start();  //开启session
$array = array_merge(range('a', 'z'), range('A', 'Z'), range(0, 9)); //拼接多个数组
$array1 = array_rand($array, 4);  //从数组中随机抽取4个元素,注意,这里取出的是元素对应下标

shuffle($array1);        //打乱数组
$str = '';
foreach ($array1 as $k) {
    $str .= $array[$k];
};
$_SESSION['code'] = strtoupper(trim($str));  //获取验证码存入session

$img = imagecreate(100, 30);     //创建画布
imagecolorallocate($img, 0xFF, 0xFF, 0xFF);  //创建一个白色的背景
$black = imagecolorallocate($img, 0x00, 0x00, 0x00);  //创建黑色的字体
$green = imagecolorallocate($img, 0x00, 0xFF, 0x00);
$font = 5;
$x = (imagesx($img) - imagefontwidth($font) * strlen($str)) / 2;
$y = (imagesy($img) - imagefontheight($font)) / 2;

//加入噪点干扰
for ($i = 0; $i < 50; $i++) {
    imagesetpixel($img, rand(0, 100), rand(0, 100), $black);
    imagesetpixel($img, rand(0, 100), rand(0, 100), $green);
}

//加入横线干扰
imageline($img, 50, 20, 150, 80, $green);
imagestring($img, $font, $x, $y, $str, $black);
header('content-type:image/png');
imagepng($img);

2、在项目目录中创建模板文件 index.html 。里面添加如下代码:

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <!-- 上述3个meta标签*必须*放在最前面,任何其他内容都*必须*跟随其后! -->
    <title>验证码练习</title>
    <link href="bootstrap/css/bootstrap.min.css" rel="stylesheet">
</head>

<body>
<div class="container">
    <div class="row">
        <form class="form-horizontal" style="margin-top: 50px;" action="" method="post">
            <div class="form-group">
                <label class="col-sm-2 control-label">验证码:</label>
                <div class="col-sm-6">
                    <input type="text" class="form-control" name="code" placeholder="请输入验证码">
                </div>
                <div class="col-sm-4">
                    <img src="imageCode.php" alt="看不清,换一张" style="cursor:pointer;border: 1px solid #ccc;"
                         onclick="this.src='imageCode.php?'+ Math.random()">
                </div>
            </div>

            <div class="form-group">
                <div class="col-sm-offset-2 col-sm-10">
                    <button type="submit" class="btn btn-info" style="margin-left: 500px;margin-top: 30px;">提交</button>
                </div>
            </div>
        </form>
    </div>
</div>

<script src="https://cdn.bootcss.com/jquery/1.12.4/jquery.min.js"></script>
<script src="bootstrap/js/bootstrap.min.js"></script>
</body>
</html>

3、在项目根目录创建 index.php 文件,代码如下:

session_start();
if ($_POST) {
    $code = strtoupper(trim($_POST['code']));

    if ($code != $_SESSION['code']) {
        echo '<font color="red">验证码输入错误</font>';
    } else {
        echo '验证码输入成功';
    }
}

require 'index.html';

转载请注明,来自https://itfun.tv/news/163