核心编程笔记 绘画 验证码 水印 缩略图

1.绘画的基本操作

1.1前提

默认PHP 是不支持绘画技术,需要我们开启PHP的扩展

但我个人的wamp64的php.ini里的gd2是默认开着的

使用phpinfo()函数可显示PHP配置,可查看gd

1.2创建画布 imagecreatetruecolor(w,h)

imagecreatetruecolor(w,h); -
w 表示的是所要创建的画布的宽
h 表示的是所要创建的画布的高

如果创建成功返回的一个gd资源:resource(2, gd)

1.3分配颜色 imagecolorallocate(img,r,g,b);

imagecolorallocate(img,r,g,b); -
img 画布资源(gd资源)
r,g,b 十进制的颜色表示方式(红、绿、蓝三色)

此函数仅是创建了一个颜色资源,但并没有使用

1.4填充颜色 imagefill(img,x,y,color);

imagefill(img,x,y,color); -
img 画布资源
x,y 画布上的某个点
color 所要填充的颜色
//1.创建画布
$w=400;
$h=200;
$img=imagecreatetruecolor($w,$h);

//2.分配颜色
$bg=imagecolorallocate($img,255,89,87);

//3.为画布填充颜色
imagefill($img,0,0,$bg);

//4.显示画布
header('content-type:image/jpeg');
imagejpeg($img);

1.5基本图形的绘制

1.5.1 绘制矩形 imagerectangle(img,x1,y1,x2,y2,color)

imagerectangle(img,x1,y1,x2,y2,color); -
rectangle1 矩形
img 画布资源
x1,y1 左上角顶点座标
x2.y2 右下角顶点座标
color 所要绘制的矩形边线的颜色

1.5.2 绘制直线 imageline(img,x1,y1,x2,y2,color)

imageline(img,x1,y1,x2,y2,color); -
img 画布资源
x1,y1 所要绘制的直线的起点座标
x2.y2 所要绘制的直线的终点座标
color 直线的颜色

1.5.3 绘制字母 imagestring(img,size,x,y,string,color)

imagestring(img,size,x,y,string,color); -
img 画布资源
size 文字大小,0到5个等级
x,y 所要绘制位置
string 所要绘制的内容
color 所要绘制的内容的颜色

imagestring只适合绘制字母,不能绘制汉字,不能选择字体,不能设置绘制的角度

1.5.4 绘制汉字 imagesttftext(img,size,angle,x,y,string,color,font,text)

imagesttftext(img,size,angle,x,y,string,color,font,text); -
img 画布资源
size 大小,单位像素
angle 角度
x,y 所要绘制的内容的左下角座标
string 所要绘制的内容
color 所要绘制的内容的颜色
font 所要绘制的内容的字体,字体文件名前需加绝对路径
text 所要绘制的内容

window操作系统的字体位于c:/windows/fonts目录内

特别说明:本人尝试了许久,font参数的文件必须写绝对路径,否则gd库无法找到字体,绝对路径可以用realpath()函数转换

imagettftext(img,20,30,150,50,img,20,-30,150,50,color,==realpath(font)==,font)==,text);

1.6输出画布

imagejpeg(img【,filename】);

imagepng(img【,filename】);

imagegif(img【,filename】);

filename表示是所要保存的文件名,可以省略,如果省略表示输出到浏览器

在输出到浏览器之前必须设置header(‘content-type:image/gif’)

在将画布输出到浏览器时,不要有任何多余的输出

如果无法显示图片,需要将header()注释掉才可以看到错误信息

1.7从图片创建画布 imagecreatefromjpeg();

imagecreatefromjpeg(); imagecreatefrompng(); imagecreatefromgif();

$file=realpath('jietu.jpg');//依然需要绝对路径
$img=imagecreatefrompng($file);
//var_dump($img);//测试是否接收到gd资源
header('content-type:image/jpeg');

file是所要读取的文件

以上函数会根据file图片的宽高来创建一个画布,并将图片的原内容读取到画布中。

什么样类型的图片就必须使用相应的类型函数

$file=realpath('ok.png');
$info=getimagesize($file);  //利用getimagesize()函数。

switch ($info['mime']){
    case 'image/jpeg':
        $img=imagecreatefrompng($file);
        break;
    case 'image/png':
        $img=imagecreatefrompng($file);
        break;
    case 'image/gif':
        $img=imagecreatefromgif($file);
        break;
}
header('content-type:image/jpeg');
imagepng($img);

2验证码

2.1什么是验证码

CAPTCHA 全自动区分人与计算机的图灵测试

计算机可以获取页面上html中的信息,但是不能获取图片上的文字信息,想获取必须借助人眼识别信息

2.2作用

验证码用于区分计算机与人,为了降低在很少的时间内对我们站点的一个访问频率

原理:就是将一组随机生成的字符串画到画布上

2.3制作验证码

2.3.1生成随机字符串

function getCode(){
    $charset='qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM0123456789';
    $code='';
    for ($i=0;$i<4;$i++){
        $code .= $charset[mt_rand(0,strlen($charset)-1)];
    }
    return $code;
}
echo getCode();

2.3.2 绘制验证码

//创建画布
$w=100;
$h=30;
$img=imagecreatetruecolor($w,$h);

//2.填充背景颜色
$bg=imagecolorallocate($img,mt_rand(210,255),mt_rand(210,255),mt_rand(210,255));
imagefill($img,0,0,$bg);

//3.绘制随机验证码
$code=getCode();
for ($i=0;$i<strlen($code);$i++) {
    $color=imagecolorallocate($img,mt_rand(100,200),mt_rand(100,200),mt_rand(100,200));
    imagettftext($img, mt_rand(18, 26), mt_rand(-20, 20), 18*($i+1), 25, $color, realpath('../public/simkai.ttf'), $code[$i]);
}
//4.增加干扰线
for($i=0;$i<4;$i++){
    $color=imagecolorallocate($img,mt_rand(100,200),mt_rand(100,200),mt_rand(100,200));
    imageline($img,mt_rand(0,100),mt_rand(0,30),mt_rand(0,100),mt_rand(0,30),$color);
}
//测试
header('content-type:image/jpeg');
imagejpeg($img);

2.4封装验证码函数

$w=100;
$h=30;
$len=4;
captcha($w,$h,$len);
function captcha($w,$h,$len)
{
    //创建画布
    $img = imagecreatetruecolor($w, $h);

    //2.填充背景颜色
    $bg = imagecolorallocate($img, mt_rand(210, 255), mt_rand(210, 255), mt_rand(210, 255));
    imagefill($img, 0, 0, $bg);

    //3.绘制随机验证码
    $code = getCode($len);
    for ($i = 0; $i < strlen($code); $i++) {
        $color = imagecolorallocate($img, mt_rand(100, 200), mt_rand(100, 200), mt_rand(100, 200));
        imagettftext($img, mt_rand(18, 26), mt_rand(-20, 20), 18 * ($i + 1), 25, $color, realpath('../public/simkai.ttf'), $code[$i]);
    }
    //4.增加干扰线
    for ($i = 0; $i < 4; $i++) {
        $color = imagecolorallocate($img, mt_rand(100, 200), mt_rand(100, 200), mt_rand(100, 200));
        imageline($img, mt_rand(0, 100), mt_rand(0, 30), mt_rand(0, 100), mt_rand(0, 30), $color);
    }
    //测试
    header('content-type:image/jpeg');
    imagejpeg($img);
}
//生成随机字符串
function getCode($len){
    $charset='qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM0123456789';
    $code='';
    for ($i=0;$i<$len;$i++){
        $code .= $charset[mt_rand(0,strlen($charset)-1)];
    }
    return $code;
}

2.5验证码应用

2.5.1 分析

验证码是以图片的形式显示在页面上,在页面上img标签

img标签的src属性,可以指向服务器的一个已经存在的图片的路径,也可以是一个PHP文件

但这个PHP文件要能够生产图片

2.5.2 login.html中展示验证码的img标签的src属性指向captcha.php文件

2.5.3 点击验证码刷新

==图片1==

<img id="code" class="pull-right img-rounded" 
style="border: 1px solid #ccc;" width="100;"
src="captcha.php" onclick="this.src='captcha.php?'+Math.random()">

2.5.4 校验验证码

过程:就用户输入的验证码与服务器产生的验证码进行比较

由于产生验证码的文件是captcha.php,而对验证码进行比较是在另一个validte.php文件,这就涉及到在不同的脚本(PHP)中使用数据

  1. 在产生验证码的captcha.php文件中将验证码字符串写到$_SESSION中
 //将随机生成的验证码写入session
    session_start();
    $_SESSION['code']=$code;
  1. 在validte.php文件中读取即可
//从session中读取验证码字符串
session_start();
$code=$_SESSION['code'];
if (strtolower($verify)!=strtolower($code)){
    header('location:login.php');
    exit;
}

3.水印

3.1.水印的作用

版本保护

宣传目的

3.2.水印的原理

在用户的图片上,“印上”公司的logo或写上公司的名、网址

3.3.制作水印

imagecopymerge(dest,src,d_x,d_y,s_x,s_y,s_w,s_h,op);

- -
dest 目标图片(用户图片)
src 原图片(公司logo)
d_x,d_y 目标图片上的某个点
s_x,s_y 原图片上的某个点
s_w,s_h 表示宽高
op 表示透明度

在src图片从s_x,s_y为起点,复制s_w为宽,s_h为高的区域,放在dest图片以d_x,d_y表示的一个点上

3.3.1简单实现

//用户上传的图片
$dest='th.jpg';
//logo图片
$src='logo.png';    //src_w:60,src_h:55

//将已有的图片读取到画布中
$imgDest=imagecreatefromjpeg($dest);
$imgSrc=imagecreatefrompng($src);

//制作水印
imagecopymerge($imgDest,$imgSrc,0,0,0,0,60,54,50);

header('content-type:image/png');
imagepng($imgDest);

3.3.2完善

//用户上传的图片
$dest='th.jpg';
//logo图片
$src='logo.png';    //src_w:60,src_h:55
$infoSrc=getimagesize($src);

//将已有的图片读取到画布中
$imgDest=createFrom($dest);
$imgSrc=createFrom($src);

//制作水印
imagecopymerge($imgDest,$imgSrc,0,0,0,0,$infoSrc[0],$infoSrc[1],50);

header('content-type:image/png');
imagepng($imgDest);

//封装由图片创建画布的函数
function createFrom($file){
   
}

3.4.封装水印函数

//用户上传的图片
$dest='th.jpg';
//logo图片
$src='logo.png';    //src_w:60,src_h:55

water($dest,$src,4,50);
/**
 * @param1 $dest string 用户图片
 * @param2 $src string logo
 * @param3 $op int 透明度
 * @param4 int 表示logo的位置 1:左上角 2:右上角 3:左下角 4:右下角 5.中间
 */
function water($dest,$src,$pos,$op)
{
    $infoSrc = getimagesize($src);
    $infoDest= getimagesize($dest);

//将已有的图片读取到画布中
    $imgDest = createFrom($dest);
    $imgSrc = createFrom($src);

    switch ($pos){
        case 1:
            $d_x=0;
            $d_y=0;
            break;
        case 2:
            $d_x=$infoDest[0]-$infoSrc[0];
            $d_y=0;
            break;
        case 3:
            $d_x=0;
            $d_y=$infoDest[1]-$infoSrc[1];
            break;
        case 4:
            $d_x=$infoDest[0]-$infoSrc[0];
            $d_y=$infoDest[1]-$infoSrc[1];
            break;
        case 5:
            $d_x=($infoDest[0]-$infoSrc[0])/2;
            $d_y=($infoDest[1]-$infoSrc[1])/2;
            break;
    }

//制作水印
    imagecopymerge($imgDest, $imgSrc, $d_x, $d_y, 0, 0, $infoSrc[0], $infoSrc[1], $op);

    header('content-type:image/png');
    imagepng($imgDest);
}

//封装由图片创建画布的函数
function createFrom($file){
    $info = getimagesize($file);
    switch ($info['mime']) {
        case  'image/jpeg':
            $img = imagecreatefromjpeg($file);
            break;
        case  'image/png':
            $img = imagecreatefrompng($file);
            break;
        case  'image/gif':
            $img = imagecreatefromgif($file);
            break;
    }
    return $img;
}

4.缩略图

4.1.作用

节省带宽

增加用户体验度

4.2.原理

将用户图片等比例放到一个给定的画布中

4.3.制作缩略图

imagecopyresamepled(dest,src,d_x,d_y,s_x,s_y,d_w,d_h,s_w,s_h);

- -
dest 目标图片(框)
src 用户图片
d_x,d_y 目标图片上的某个点
d_w,d_h 表示宽、高
s_x,s_y 用户图片上的某个点
s_w,s_h 表示宽高
op 表示透明度

在src图片从s_x,s_y为起点,截取以s_w为宽,s_h为高的区域,放在dest画布上以d_x,d_y为顶点,以d_w为宽,d_h为高的区域

4.4.封装缩略图处理函数

//测试数据
$d_w = 500;
$d_h = 300;
$src = "th.jpg";
thumb($d_w,$d_h,$src);
function thumb($d_w,$d_h,$src)
{
//创建画布(框)
    $imgDest = imagecreatetruecolor($d_w, $d_h);//框
    $bg = imagecolorallocate($imgDest, 161, 130, 190);
    imagefill($imgDest, 0, 0, $bg);

//由用户图片创建画布
    $infoSrc = getimagesize($src);
    $s_w = $infoSrc[0];
    $s_h = $infoSrc[1];
    $imgSrc = createFrom($src);

    $f_h = $d_h;
    $f_w = $s_w / $s_h * $f_h;
    if ($f_w > $d_w) {
        $f_w = $d_w;
        $f_h = $s_h / $s_w * $f_w;
    }

//计算imgDestin上所放置的起点位置
    $posX = ($d_w - $f_w) / 2;
    $posY = ($d_h - $f_h) / 2;

//采样合并
    imagecopyresampled($imgDest, $imgSrc, $posX, $posY, 0, 0, $f_w, $f_h, $s_w, $s_h);
    header('content-type:image/jpeg');
    imagejpeg($imgDest);
}

//封装由图片创建画布的函数
function createFrom($file)
{
    $info = getimagesize($file);
    switch ($info['mime']) {
        case  'image/jpeg':
            $img = imagecreatefromjpeg($file);
            break;
        case  'image/png':
            $img = imagecreatefrompng($file);
            break;
        case  'image/gif':
            $img = imagecreatefromgif($file);
            break;
    }
    return $img;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章