文章目录
一、验证码的制作流程
1.创建画布资源
- 创建新的画布:imagecreate(宽,高):创建基于调色板的画布,支持颜色少
imagecreatetruecolor(宽,高):创建正彩色画布,支持颜色多 - 基于已有图像创建画布 imagecreatefromjpeg(图片地址),imagecreatefrompng/gif
2.操作画布
- 设置画布背景颜色:
1.分配颜色:RGB模式,格式:变量=imagecolorallocate(画布资源,颜色R,颜色G,颜色B)
2.填充画布:imagefill(画布资源,位置X,位置Y,颜色),左上角的坐标0,0;右下角的坐标width-1,height-1 - 将字符串写到画布上:
1.随机抽取文字
2.随机设置颜色
3.将文字放在画布上:imagettftext (画布资源 ,字体大小, 角度, 位置x,位置y,颜色 ,字体, 文字内容 )
4.将验证码连接后存入session中,以便后续验证 - 加上干扰元素:
1.加像素点(200个):imagesetpixel ( 画布资源 , 位置x, 位置y ,颜色)
2.加干扰直线(5条):imageline (画布资源,起始位置x , 起始位置y ,结束位置x , 结束位置y , 颜色)
3.导出 && 销毁
- 导出:imagepng/gif/jpeg(画布资源[,图片地址,图片质量])
如果没有图片地址的参数,则表示该图片直接在浏览器输出,需要告知浏览器输出图片header(‘content-type:image/png’);
图片质量:0~100,100质量最好 - 销毁:imagedestroy(画布资源)
4.前端
- 显示图片及点击更换验证码:
<img src=“code.php” οnclick=“this.src=‘code.php?’+Math.random()”>
加上Math.random()的参数可以防止服务器缓存,每次点击都是新的 - 输入框输入验证码,ajax请求,重新渲染页面,返回结果
如下图
github :https://github.com/YY-FS/Study/tree/master/GD/CAPTCHA
二、验证码的制作代码
1.PHP制作验证码
<?php
class Code
{
private $str = "023456789ABCDEFGHJKMNOPQRSTUVWXYZ";//验证码的字符,去除1,i,l,因为有点像
private $len, $width, $height; //定义验证码的字符数量,宽,高
private $im; //画布资源
public function __construct($len = 4, $width = 30, $height = 50)
{
$this->width = $width; //初始化成员变量
$this->height = $height;
$this->len = $len;
session_start(); //开启session
$this->getCode(); //获得验证码图片
}
/**
* 获得验证码图片
*/
private function getCode()
{
//1.创建画布资源
$this->createPic();
//2.创建背景颜色
$gray = $this->createColor(176, 196, 222);
imagefill($this->im, 0, 0, $gray);
//3.加上验证码字
$this->addString();
//4.加干扰元素
$this->addPix();
$this->addLine();
}
/**
* 4.加干扰元素:加像素点
*/
private function addPix()
{
for ($i = 0; $i < 200; $i++) {
$color = $this->createColor(mt_rand(0, 100), mt_rand(0, 100), mt_rand(0, 100)); //随机获取颜色,取比较深的
//加像素点
imagesetpixel($this->im, mt_rand(1, ($this->width * $this->len) - 1), mt_rand(1, $this->height - 1),
$color);
}
}
/**
* 4.加干扰元素:加线
*/
private function addLine()
{
for ($i = 0; $i < 5; $i++) {
$color = $this->createColor(mt_rand(0, 180), mt_rand(0, 180), mt_rand(0, 180));
//画线
imageline($this->im, mt_rand(1, ($this->width * $this->len) - 1), mt_rand(1, $this->height - 1),
mt_rand(1, ($this->width * $this->len) - 1), mt_rand(1, $this->height - 1), $color);
}
}
/**
* 3.加字
*/
private function addString()
{
$lens = strlen($this->str); //计算验证码的长度
$sessStr = ''; //最终塞入session的验证码
for ($i = 0; $i < $this->len; $i++) {
//1.设置字体颜色
$str = $this->str[mt_rand(0, $lens)]; //随机取出一个字符
$sessStr .= $str; //连接验证码
$color = $this->createColor(mt_rand(0, 200), mt_rand(0, 200), mt_rand(0, 200)); //生成颜色
//2.加字,imagettftext可控制字体,大小,颜色,旋转角度,摆放位置
imagettftext($this->im, mt_rand(15, 25), mt_rand(-70, 70), $this->width * $i + mt_rand(5, 15),
mt_rand(20, 40), $color, 'consola.ttf', $str);
}
$_SESSION['code'] = $sessStr; //存入session中
}
/**
* 2.创建画布资源
*/
private function createPic()
{
$this->im = imagecreatetruecolor($this->width * $this->len, $this->height);
}
/**
* 创建颜色
* @param $r
* @param $g
* @param $b
* @return int
*/
private function createColor($r, $g, $b)
{
return imagecolorallocate($this->im, $r, $g, $b);
}
/**
* 输出验证码图片
*/
public function showCode()
{
header('content-type:image/png');
imagepng($this->im);
imagedestroy($this->im);
}
}
$q = new Code();
$q->showCode();
2.HTML显示验证码
<!DOCTYPE html>
<html>
<meta charset="utf-8">
<head>
<title>PHP验证码</title>
<!--引入jquerycdn-->
<script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.js"></script>
</head>
<body>
<!--引入获取验证码图片-->
<img src="code.php" onclick="this.src='code.php?'+Math.random()">
<!--输入验证码-->
<input id="code" type="text" name="code">
<!--AJAX提交-->
<input id="checkCode" type="button" value="检查验证码">
<!--输出结果-->
<div>结果:<span style="color:red" id="result"></span></div>
</body>
<script type="text/javascript">
$('#checkCode').click(function () {
$.ajax({
url: "checkCode.php",
method: "get",
data: {
code: $("#code").val() //传参
},
dataType: "json",
success: function (result) {
console.log(result)
$('#result').text(result.msg) //改变页面的值
}
})
})
</script>
</html>
3.PHP验证验证码
<?php
class CheckCode
{
public function __construct()
{
session_start();
}
public function check($code)
{
if ($code) {
if ($code == $_SESSION['code']) {
unset($_SESSION['code']);
$this->jsonOutPut('验证码正确');
} else {
$this->jsonOutPut('验证码错误');
}
} else {
$this->jsonOutPut('未输入验证码');
}
}
/**
* [输出json]
* @param [type] $msg [description]
* @return [type] [description]
*/
public function jsonOutPut($msg)
{
$data = [
'code' => 200,
'msg' => $msg
];
echo json_encode($data);
}
}
$code = strtoupper($_GET['code'] ?? ''); //获得参数,并且全部转换为大写字母
$check = new CheckCode();
$check->check($code); //检查并输出
三、缩略图的制作流程
1、获取原图像大小
- getimagesize():获取图像大小或类型
list($width,$heifht) = getimagesize($picInfo[‘tmp_name’]);
2、计算缩略图大小
- (1)$percent = 0.2;:计算缩放比例
$thuWidth = $width * $percent;
$thuHeight = $height * $percent; - (2)$thuWidth = 100;:定义缩略图的宽
$thuHeight = $thuWidth * $height / $width;
3、创建画布
- 同上验证码
4、生成缩略图
- imagecopyresized($dst,$src,0,0,0,0,$dstWidth,$dstHeight,$srcWidth,$srcHeight);
从原图像的原点坐标(0,0)位置开始,按照目标图像宽和高的比例进行缩放,并将其拷贝到目标图像的原点(0,0)位置 - 参数:
$dst:目标图像
$src:原图像
0,0,0,0:目标图像开始x,y坐标,原图像开始x,y坐标
$dstWidth:目标图像的宽度
$dstHeight:目标图像的高度
$srcWidth:拷贝原图像的宽度
$srcHeight:拷贝原图像的高度
5、导出 && 销毁
- 同上验证码
6、缩略图代码展示
github :https://github.com/YY-FS/Study/tree/master/GD/Thumbnail
<?php
$file = './LFF.jpg';
list($width, $height) = getimagesize($file);
$percent = 0.3; //定义缩放比例
$dstWidth = $percent * $width; //缩略图的宽
$dstHeight = $percent * $height; //缩略图的高
$srcim = imagecreatefromjpeg($file);//从原图创建画布
$dstim = imagecreatetruecolor($dstWidth, $dstHeight); //创建正彩色画布
imagecopyresized($dstim, $srcim, 0, 0, 0, 0, $dstWidth, $dstHeight, $width, $height); //创建缩略图
$newFile = './LFF_thumb.jpg'; //缩略图生成地址
imagejpeg($dstim, $newFile, 100); //导出
imagedestroy($dstim); //销毁图片资源
imagedestroy($srcim);
四、水印的制作流程
1、添加普通水印
- imagecopy($srcim, $waterim, 20, 20, 0, 0, $waterWidth, $waterHeight);
表示将 $waterim 图像中坐标从 0,0 开始,宽度为$waterWidth,高度为$waterHeight 的一部分拷贝到$srcim图像中坐标为 20,20(即左上角) 的位置上
2、添加半透明水印
- imagecopymerge($srcim, $waterim, 20, 20, 0, 0, $waterWidth, $waterHeight, 20);
参数与imagecopy几乎完全一样,多了最后一个参数控制透明度0~100,100时则与imagecopy效果一样
3、添加文字水印
- imagecolorallocate(画布资源,颜色R,颜色G,颜色B)
- imagefttext ($image, $size, $angle, $x, $y, $color, $fontfile, $text[, $extrainfo = null ])
参数:$image:画布资源
$size:字体大小
$angle:角度
$x,$y:文字在目标图像的横纵坐标
$color:字体的颜色
$fontfile:字体样式
$text:文字
4、水印代码展示
github :https://github.com/YY-FS/Study/tree/master/GD/WaterMark
<?php
$srcim = imagecreatefromjpeg('./LFF.jpg');
/************** 图片水印 **************/
$waterim = imagecreatefrompng('./cctv.png');
list($waterWidth, $waterHeight) = getimagesize('./cctv.png');
//普通水印
imagecopy($srcim, $waterim, 20, 20, 0, 0, $waterWidth, $waterHeight);
//半透明水印
imagecopymerge($srcim, $waterim, 20, 20, 0, 0, $waterWidth, $waterHeight, 20);
/************** 文字水印 **************/
$fontStyle = './consola.ttf'; //定义字体模式
$color = imagecolorallocate($srcim, 255, 255, 255); //RGB白色
imagefttext($srcim, 30, 0, 20, 50, $color, $fontStyle, 'YY-FS');
$file = './LFF_water.jpg';
imagejpeg($srcim, $file, 100); //输出图像
imagedestroy($waterim); //销毁资源
imagedestroy($srcim);
五、图片特效的制作流程
1、特效函数
- imagefilter ($image, $filtertype[, $arg1 = null, $arg2 = null, $arg3 = null, $arg4 = null])
过滤器 filtertype 应用到图像上,在需要时使用 arg1,arg2 和 arg3 - filtertype参数:
IMG_FILTER_NEGATE:将图像中所有颜色反转
IMG_FILTER_GRAYSCALE:将图像转换为灰度的
IMG_FILTER_BRIGHTNESS:改变图像的亮度。用 arg1 设定亮度级别
IMG_FILTER_CONTRAST:改变图像的对比度。用 arg1 设定对比度级别
IMG_FILTER_COLORIZE:与 IMG_FILTER_GRAYSCALE 类似,不过可以指定颜色。用 arg1,arg2 和 arg3 分别指定 red,blue 和 green。每种颜色范围是 0 到 255
IMG_FILTER_EDGEDETECT:用边缘检测来突出图像的边缘
IMG_FILTER_EMBOSS:使图像浮雕化
IMG_FILTER_GAUSSIAN_BLUR:用高斯算法模糊图像
IMG_FILTER_SELECTIVE_BLUR:模糊图像
IMG_FILTER_MEAN_REMOVAL:用平均移除法来达到轮廓效果
IMG_FILTER_SMOOTH:使图像更柔滑。用 arg1 设定柔滑级别
2、图片特效代码展示
github :https://github.com/YY-FS/Study/tree/master/GD/Special
- PHP后端代码
<?php
$fileInfo = $_FILES['file'];
switch ($fileInfo['type']) { //选择合适的方法创建画布
case 'image/jpeg':
case 'image/jpg':
$im = imagecreatefromjpeg($fileInfo['tmp_name']);
break;
case 'image/png':
$im = imagecreatefrompng($fileInfo['tmp_name']);
break;
case 'image/gif':
$im = imagecreatefromgif($fileInfo['tmp_name']);
break;
}
switch ($_POST['filter']) { //选择特效样式
case 1:
$filter = IMG_FILTER_NEGATE; //反色
break;
case 2:
$filter = IMG_FILTER_EMBOSS; //浮雕
break;
case 3:
$filter = IMG_FILTER_SELECTIVE_BLUR; //模糊
break;
case 4:
$filter = IMG_FILTER_GRAYSCALE; //灰度
break;
}
imagefilter($im, $filter); //图片特效绘制
$file = './filter.jpg';
imagejpeg($im, $file, 100); //输出图像
imagedestroy($im); //销毁图像
echo json_encode([
'code' => 0,
'msg' => 'success',
'src' => $file
]);
- HTML前端代码:注意文件的ajax传输
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>图片特效</title>
<!--引入jquerycdn-->
<script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.js"></script>
<style>
.box {
margin: 20px auto;
width: 400px;
}
#filter {
width: 100px;
font-size: 15px;
height: 25px;
}
.img{
width: 200px;
}
</style>
</head>
<body>
<div class="box">
<div>
<span>上传文件:</span>
<input type="file" id="file" name="file">
</div>
<div style="margin: 20px 0;">
<span>选择特效:</span>
<select name="filter" id="filter">
<option value="1">反色</option>
<option value="2">浮雕</option>
<option value="3">模糊</option>
<option value="4">灰度</option>
</select>
</div>
<button id="change">提交</button>
<div id="img"></div>
</div>
</body>
<script type="text/javascript">
$('#change').click(function () {
var form = new FormData();
form.append('file', $('#file')[0].files[0]);
form.append('filter', $('#filter').val());
$.ajax({
url: "special.php",
method: "post",
data: form,
processData: false, //很重要,告诉jquery不要对form进行处理
contentType: false, //很重要,指定为false才能形成正确的Content-Type
dataType: "json",
success: function (result) {
if(result.code == 0){
var img = '<img class="img" src="'+result.src+'">'
$('#img').html(img)
}
}
})
})
</script>
</html>
- 效果展示