通过上一节,我们已经很好的掌握了图像处理的精髓。
通过我们所掌握的知识。进行一些简单的扩展,我们就可以写出:网上最常用的一个小东西——验证码。
验证码是为了防止机器自动注册、机器自动刷票最常用的手段之一。
我们来看一下验证码的效果:
![document/2015-09-21/55ff9eef8b3f0](http://box.kancloud.cn/document_2015-09-21_55ff9eef8b3f0.png)
我们根据上面的效果来推理实现的过程。
实现过程:
1. 生成指定宽高的画布
2. 准备好字好需要生成的字符串
3. 每次执行,让背景填充随机的颜色(浅色系)
4. 在画布上画上随机的干扰元素(随机点、随机线、随机弧形等均可,但不可过份影响用户的视觉)
5. 写上4个文字
6. 输出header头,告知浏览器按照某类型显示
7. 输出图像
8. 销毁图像资源
上面的步骤把实现验证码的每一步都讲清楚了。下面我们来根据这个过程来推理实现。
**第一步、创建画布**
> $img = imagecreate($width, $height);
我们可以定义一个自定义的宽和高。做一个函数将,可以通过函数传入宽和高。这样,可以修改验证码图像的大小。
~~~
function check_code($width = 100, $height = 50) {
$img = imagecreate($width, $height);
}
~~~
**第二步、生成验证码显示的文字**
验证码的文字通常有数字、字母。而为了区别验证码字符。我们可以用0-9A-Za-Z。但是0和o,l和I有的时候区分不清楚。我们如果不需要处理,可以想办法去除掉:
方案一:
循环4个ascii码,而ascii码,而chr或者sprintf('%c',第二个参数传ascii码) 将对应的字符转为指定的字符。
~~~
for ($i = 0; $i < $num; $i++) {
$rand = mt_rand(0, 2);
switch ($rand) {
case 0:
$ascii = mt_rand(48, 57); //0-9
break;
case 1:
$ascii = mt_rand(65, 90); //A-Z
break;
case 2:
$ascii = mt_rand(97, 122); //a-z
break;
}
//chr()
$string .= sprintf('%c', $ascii);
}
~~~
方案二:
方案一对很多人来说有点复杂,很多人理解不了ascci码。有没有更简单的方案呢。单然有。我可以准备好字符,然后用str_shuffle打乱字符后使用substr进行截取。
~~~
//没有0,i,l,o
$str = 'abcdefghijkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ123456789';
$str = str_shuffle($str);
$string = substr($str,0 ,3);
~~~
**三、 每次执行,让背景填充随机的颜色(浅色系)**
文字是深色的看得清楚,而背景是潜色的。
背景的RGB颜色表示通常是这样的,RGB颜色是三个色值,这三个色值都是从0-255。
而:
0-120 低数值是深色系。
130 - 255 通常为浅色系。
使用到图片颜色的地方挺多的。因此,我可以定义分配颜色的功能:
~~~
//浅色的背景函数
function randBg($img) {
return imagecolorallocate($img, mt_rand(130, 255), mt_rand(130, 255), mt_rand(130, 255));
}
//深色函数,深色的字或者点这些干 扰元素
function randPix($img) {
return imagecolorallocate($img, mt_rand(0, 120), mt_rand(0, 120), mt_rand(0, 120));
}
~~~
**四、在画布上画上随机的干扰元素**
我们可以随机的在图片中画上50个像素点。最小的位置为0,0。最大的位置为最大的宽或者最大的高。
然后使用mt_rand(0,最大宽)、mt_rand(0,最大高)。再使用randPix针对我们创建的画布来分配颜色。
~~~
//画干扰元素
for ($i = 0; $i < 50; $i++) {
imagesetpixel($img, mt_rand(0, $width), mt_rand(0, $height), randPix($img));
}
~~~
**五、写上4个文字**
$string是一个字符串,字符串$string[0]为字符的第一个字符,依此类类推。
因此,我可在使用imagechar函数在图像中写入文字。
而写入文字的x,y的坐标我们可以用一个公式推倒出来。
X位置 = 图像宽/字符个数(4) * 循环次数。 得到的结果取整后再乘以每次循环的次数。假设图像为100个宽度,那么:第一次写在0的位置,第二次为 25,第三次为50,第四次为75。
Y位置 = mt_rand(0,图像高- 15)。
我们可以推导出下面的代码,就可以写出对应的文字了:
~~~
for ($i = 0; $i < $num; $i++) {
$x = floor($width / $num) * $i;
$y = mt_rand(0, $height - 15);
imagechar($img, 5, $x, $y, $string[$i], randPix($img));
}
~~~
**六、输出header头,告知浏览器按照某类型显示**
我们知道图像类型的输出函数都有:imagejpeg,imagepng,imagegif等特点。
而图像的mime类型为image/jpeg,image/png,image/gif等。
因此,我们可以声明一个变量:
$imagetype = 'jpeg';
$imagetype = 'png';
$imagetype = 'gif';
输出header类型的时候执行:
$header = 'Content-type:image/' . $imagetype;
执行函数输出的可以拼接出一个变量函数:
$func = 'image' . $type;
如果我们的系统支持个类型,则使用function_exists检测函数是否存在。存在则系统支持该类型,不存在则不支持该类型。
所以代码可以写成这样:
~~~
$func = 'image' . $type;
$header = 'Content-type:image/' . $type;
if (function_exists($func)) {
header($header);
//变为了imagejpeg等
$func($img);
} else {
echo '图片类型不支持';
}
~~~
**八、销毁资源,返回字符**
以后在验证的时候,大家需要把验证码显示出来。并且,用户输出的验证字符还需要与图像中的验证字符匹配。
所以要将验证字符返回回来,供以后保存使用。
~~~
imagedestroy($img);
return $string;
~~~
我们来看一下全部的准备完成的PHP函数文件,我们将上面的代码封装成一个统一的函数供大家来学习使用:
~~~
<?php
check_code();
function check_code($width = 100, $height = 50, $num = 4, $type = 'jpeg') {
$img = imagecreate($width, $height);
$string = '';
for ($i = 0; $i < $num; $i++) {
$rand = mt_rand(0, 2);
switch ($rand) {
case 0:
$ascii = mt_rand(48, 57); //0-9
break;
case 1:
$ascii = mt_rand(65, 90); //A-Z
break;
case 2:
$ascii = mt_rand(97, 122); //a-z
break;
}
//chr()
$string .= sprintf('%c', $ascii);
}
//背景颜色
imagefilledrectangle($img, 0, 0, $width, $height, randBg($img));
//画干扰元素
for ($i = 0; $i < 50; $i++) {
imagesetpixel($img, mt_rand(0, $width), mt_rand(0, $height), randPix($img));
}
//写字
for ($i = 0; $i < $num; $i++) {
$x = floor($width / $num) * $i + 2;
$y = mt_rand(0, $height - 15);
imagechar($img, 5, $x, $y, $string[$i], randPix($img));
}
//imagejpeg
$func = 'image' . $type;
$header = 'Content-type:image/' . $type;
if (function_exists($func)) {
header($header);
$func($img);
} else {
echo '图片类型不支持';
}
imagedestroy($img);
return $string;
}
//浅色的背景
function randBg($img) {
return imagecolorallocate($img, mt_rand(130, 255), mt_rand(130, 255), mt_rand(130, 255));
}
//深色的字或者点这些干 扰元素
function randPix($img) {
return imagecolorallocate($img, mt_rand(0, 120), mt_rand(0, 120), mt_rand(0, 120));
}
?>
~~~
- 01. 为什么选择本书学习PHP
- 1.1 为什么学习PHP?
- 1.2 PHP是什么
- 1.3 零基础也能学习
- 1.4 为什么有些人学不会
- 02.PHP的环境安装
- 2.1开发环境是什么?
- 2.2 windows环境安装
- 2.3 Linux环境安装
- 2.4 其他开发环境
- 2.5 写代码的工具选择
- 03. PHP基本语法
- 3.1 PHP基本语法
- 3.1.1 写出你的第一段PHP代码
- 3.1.2 读过初中你就会变量
- 3.1.3 echo 显示命令
- 3.1.4 注释的功能很强大
- 3.2 数据类型并不神秘
- 3.2.1 整型就是整数
- 3.2.2 布尔就是易经的知识
- 3.2.3 字符串
- 3.2.4 浮点型
- 3.2.5 重要:if和else语法
- 3.2.6 NULL类型
- 3.2.7对象以后会学
- 3.2.8 数组会有单纯的一个章节
- 3.2.9 资源类型
- 3.2.10 眼前了解回调类型即可
- 3.2.11 查看和判断数据类型
- 3.2.12 数据类型的自动转换和强制转换
- 3.3 常量和变量
- 3.3.1 用常量限制用户跳过某些文件
- 3.3.2 可变变量
- 3.3.3 外部变量
- 3.3.4 环境变量
- 3.3.5 变量引用
- 3.4 PHP表达式与运算符
- 3.4.1 算术运算
- 3.4.2 赋值运算
- 3.4.3 自加、自减运算
- 3.4.4 比较运算
- 3.4.5 逻辑运算
- 3.4.6 位运算
- 3.4.7 运算符优先级
- 3.4.8 三元运算符和其它运算符
- 04. PHP中的流程控制
- 4.1 if条件结构流程
- 4.1.1 if语句
- 4.1.2 嵌套if...else...elseif结构
- 4.1.3 if语句多种嵌套
- 4.2 分支结构switch语句的使用
- 4.3 循环语句的使用
- 4.3.1 while循环
- 4.3.2 do...while循环的区别
- 4.3.3 for循环控制语句
- 4.3.4 goto语法
- 4.3.5 declare 语法
- 05.PHP的函数基本语法
- 5.1 自定义函数
- 5.2 自定义函数高级调用
- 5.2.1 回调函数
- 5.2.2 变量函数
- 5.2.3 匿名函数
- 5.2.4 内部函数
- 5.2.5 变量作用域
- 5.2.6 参数的引用
- 5.2.7 递归函数
- 5.2.8 静态变量
- 5.3 使用系统内置函数
- 5.4 文件包含函数
- 5.5 数学常用函数
- 5.6 日期常用函数
- 5.6.1 获取时期时间信息函数
- 5.6.2 日期验证函数
- 5.6.3 获取本地化时间戳函数
- 5.6.4 程序执行时间检测
- 5.7 字符串常用函数
- 06.PHP数组与数据结构
- 6.1 数组的定义
- 6.2 数组的操作
- 6.2.1 数组的计算
- 6.2.2 for循环遍历索引数组
- 6.2.3 foreach遍历关联数组
- 6.2.4 list、each函数遍历数组
- 6.2.5 常用操作数组函数
- 6.3 数组的常用函数
- 07. PHP中的正则达达式
- 7.1 正则表达示的定界符
- 7.2 正则表达示中的原子
- 7.3 正则表示中的元字符
- 7.4 正则达达示中的模式修正符
- 7.5 写正则的诀窍和常用正则
- 7.6 用正则写一个UBB文本编辑器
- 08.文件系统
- 8.1 读取文件
- 8.2 创建和修改文件内容
- 8.3 创建临时文件
- 8.4 移动、拷贝和删除文件
- 8.5 检测文件属性函数
- 8.6 文件常用函数和常量
- 8.7 文件锁处机制
- 8.8 目录处理函数
- 8.9 文件权限设置
- 8.10文件路径函数
- 8.11 小小文件留言本
- 8.12 修改配置文件的实例
- 09.PHP文件上传
- 9.1 文件上传需要注意php.ini文件
- 9.2 文件上传的步骤
- 9.3 文件上传表单注意事项
- 9.4 按照数组和步骤完成文件上传
- 9.5 多文件上传
- 9.6 文件上传进度处理
- 10.PHP图像处理
- 10.1 学习前的准备工作
- 10.2 用图片处理函数画一张图
- 10.3 生成验证码
- 10.4 图像缩放和裁剪技术
- 10.5 图片水印处理
- 11.错误处理
- 11.1 禁止显示错误
- 11.2 错误报告级别
- 11.3 错误记录日志
- 11.4 自定义错误处理函数
- 12.MySQL 入门
- 12.1 请进入《MySQL入门》
- 13. PHP操作mysql数据库
- 13.1 数据库连接步骤
- 13.2 通过步骤做一个用户注册
- 13.3 通过步骤做一个列表显示
- 13.4 把用户做个分页
- 13.5 批量和指定删除用户
- 13.6 修改用户信息
- 13.7 数据显示乱码终极解决办法
- 14.会话管理和控制
- 14.1 Cookie概述
- 14.2PHP中的Cookie
- 14.3 session概述
- 14.4 PHP中使用session
- 14.5 SESSION应用实例
- 15.通过cURL来做小偷程序
- 15.1 curl的使用步骤
- 15.2 自定义get方法抓取网页
- 15.3 使用post发送数据
- 16. 用PHP写一个论坛
- 16.1 web2.0始于论坛
- 16.2 需求:开发前你要知道他的样子
- 16.3 核心业务流程
- 16.3.1 用户注册流程
- 16.3.2 普通用户和管理员登陆流程
- 16.3.3 发贴流程
- 16.3.4 回复流程
- 16.3.5 版块管理流程
- 16.3.6 版主业务流程
- 16.3.7 金币奖励和消耗流程
- 16.4 数据库表设计
- 16.5 文件和代码规范
- 16.6 核心功能说明
- 16.6.1 项目目录结构说明
- 16.6.2 公共文件的使用
- 16.6.3 模板引擎讲解
- 16.6.4 用户注册、登陆功能讲解
- 16.6.5 发帖功能讲解
- 16.6.6 回帖功能讲解
- 16.6.7 项目安装模块讲解
- 附录1. 版权声明
- 附录2 . 学习PHP常用的英文单词