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(
i
m
g
,
20
,
−
30
,
150
,
50
,
img,20,-30,150,50,
img,20,−30,150,50,color,==realpath(
f
o
n
t
)
=
=
,
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 点击验证码刷新
<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)中使用数据
- 在产生验证码的captcha.php文件中将验证码字符串写到$_SESSION中
//将随机生成的验证码写入session
session_start();
$_SESSION['code']=$code;
- 在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;
}