思考:在PHP开发中,应该会经常用到图形处理之类的,那么PHP能够处理图片吗?
引入:PHP作为一款强大的后台处理语言,操作图片是必不可少的,PHP本身不操作图片,但是可以借助强大的扩展库实现图片的操作。PHP主要使用GD库实现图片操作。
- 验证码制作
- 缩略图
- 水印图
总结:PHP可以利用GD库进行各种图像操作
1. 加载GD库【掌握】
-
GD库作为一种扩展项,需要事先加载才能使用,加载的方式就是在php.ini中开启GD扩展
- GD库加载后,内置了很多函数供开发人员操作,可以通过操作手册索引中输入
image
来检索
- 常用的GD函数列表
- imagecreatetruecolor:创建一张真彩画布
- imagecolorallocate:给画布分配颜色
- imagefill:填充颜色
- imagestring:水平写字符串(ASCII码)
- imagettftext:文本写入
- imageline:制作线段
- imagecreatefromjpeg:打开一张jpeg图片
- imagecreatefrompng:打开一张png图片
- imagecopymerge:拷贝图像合并到另外一张图片资源
- imagecopyresampled:不失真拷贝图片到另外一张图片资源
- imagepng:保存或者输出图片,保存格式为png
- imagejpeg:保存或者输出图片,保存格式为jpeg
- imagedestroy:销毁资源
- getimagesize:取得图片信息
- pathinfo:得到文件信息
总结
- GD库提供了很多函数来处理图片
- 根据不同的需求可以使用不同的函数来完成对应的功能
- 列出了制作验证码、水印和缩略图所需要的常用函数
思考:验证码图片是怎么做成的呢?
引入:在开发中,几乎所有的网站都有用到验证码功能,验证码不是一个简单的字符串,通常都是将字符串放到图片上,而且加上很多干扰内容来完成。
2. 制作验证码【掌握】
定义:验证码(CAPTCHA)是“Completely Automated Public Turing test to tell Computers and Humans Apart”(全自动区分计算机和人类的图灵测试)的缩写 ,是一种区分用户是计算机还是人的公共全自动程序。验证码由最初的简单字符串到现在各式各样复杂的图片、计算、问题等,只是因为计算机识别的功能已经越来越强大。
- 验证码制作流程
- 制作画布:imagecreatetruecolor
- 填充背景色:imagecolorallocate分配颜色,imagefill填充颜色
- 写入内容:imagestring写简单内容,imagettftext写入字体文字
- 增加干扰:imageline增加线段,imagestring增加其他符号
- 保存图片:imagepng输出或者保存图片
- 简单图片制作
<?php
//制作简单图片
//1.创建画布
$img = imagecreatetruecolor(200,200); //宽度和高度,像素单位,得到画布资源
//2.输出图片
header('content-type:image/png');
imagepng($img); //所有gd函数都需要图片资源
//3.销毁资源
imagedestroy($img);
- 简单验证码制作
<?php
//制作简单验证码图片
//1.创建画布资源
$img = imagecreatetruecolor(100,30);
//2.填充背景色
//2.1给画布分配背景颜色
$bg_color = imagecolorallocate($img,255,255,255); #RGB三色组,纯白色
//2.2填充颜色
imagefill($img,0,0,$bg_color); #从0,0坐标处开始上色,自动渲染相同颜色像素点
//3.写入字符串
//3.1给要写入的字符串分配颜色
$str_color = imagecolorallocate($img,150,150,150); #比背景颜色稍深
//3.2写入文字
imagestring($img,5,30,10,'capcha',$str_color);
//4.保存输出
//4.1保存
imagepng($img,'captcha.png'); #保存到当前文件夹captcha.png
//4.2输出
header('content-type:image/png');
imagepng($img);
//5.销毁资源
imagedestroy($img);
- 封装简单验证码制作函数
<?php
//封装验证码制作函数
/*
* 验证码制作函数
* @param1 int $width 图片宽度
* @param2 int $height 图片高度
* @param3 int $lines = 10,干扰线数量,默认10条
* @param4 int $length = 4 字符串长度,默认4个简单字符
*/
function getCaptcha($width,$height,$lines = 10,$length = 4){
//1.制作画布
$img = imagecreatetruecolor($width,$height);
//2.填充背景
$bg_c = imagecolorallocate($img,mt_rand(200,255),mt_rand(200,255),mt_rand(200,255)); #随机淡色
imagefill($img,0,0,$bg_c);
//3.制作随机字符串
$str_arr = range('A','Z'); #得到A-Z数组元素
shuffle($str_arr); #打乱数组元素
//定义一个字符串保留取出的所有字母
$captcha = '';
//循环取元素即可
for($i = 0;$i < $length; $i++){
//每取出一个符号就保留到$captcha
$captcha .= $str_arr[$i]; #取乱序数组前4个元素
}
//写入图片
$str_c = imagecolorallocate($img,mt_rand(0,100),mt_rand(0,100),mt_rand(0,100)); #随机深色
imagestring($img,5,30,10,$captcha,$str_c);
//4.制作干扰元素
//循环制作多条
for($i = 0;$i < $lines;$i++){
$line_c = imagecolorallocate($img,mt_rand(120,180),mt_rand(120,180),mt_rand(120,180)); #中间颜色,每条颜色都不一样
imageline($img,mt_rand(0,$width),mt_rand(0,$height),mt_rand(0,$width),mt_rand(0,$height),$line_c); #随机起始位置
}
//5.输出图片
header('content-type:image/png');
imagepng($img);
//6.销毁资源
imagedestroy($img);
}
总结
- 验证码指的是印在图片上的随机字符
- 验证码图片的制作流程:画布->背景色->随机字符串->写入字符串->干扰->输出图片->销毁画布
- 验证码的功能可以很丰富,需要使用更加复杂的函数和逻辑
思考:随着版权意识越来越高,很多人已经开始给自己的图片做了版权保护处理,就是在上面增加了一些若影若现的文字或者图片,这个怎么实现呢?
引入:图片上加入内容,其实就是制作水印的一个过程。验证码也可以理解为是一个带文字水印的图片。更多的水印是通过放置一张图片到上面来实现的。
3. 制作水印图片【掌握】
定义:制作水印图片,就是往一张图片上放入一些文字或者图片元素,在不是特别影响原图的使用的前提下,又能有版权追溯(防止别人盗图商用)。
- 水印制作流程(图片版)
- 打开原图:imagecreatefromjpeg/png,从jpeg(基本上都是)打开原图资源
- 打开水印图:与原图一样,只是图片通常是png
- 复制水印图合并到原图上:imagecopymerge
- 保存图片:imagejpeg/png
- 关闭资源
- 实现水印图(原图desktop.jpg,水印图php.png)
<?php
//制作水印图
//1.打开要添加水印图的资源
$dst = imagecreatefromjpeg('desktop.jpg');
//2.打开水印图片资源
$src = imagecreatefrompng('php.png');
//3.采样复制合并:全部水印图放到原图左上角
$src_info = getimagesize('php.jpg'); #获取图片信息返回数组,0元素为宽,1元素为高
imagecopymerge($dst,$src,0,0,0,0,$src_info[0],$src_info[1],50); #透明度50
//4.保存图片
header('content-type:image/jpeg');
imagejpeg($dst);
imagejpeg($dst,'water.jpg');
//5.销毁资源
imagedestroy($dst);
imagedestroy($src);
- 封装水印图制作函数
<?php
//封装水印图制作函数
/*
* 制作水印图
* @param1 string $image,要添加水印的图片地址
* @param2 string $path,水印图制作完成后存储路径
* @param3 string $water,水印图图片地址
* @param4 int $pct = 50,透明度,默认50
* @return string 新生成图片的名字
*/
function getWatermark($image,$path,$water,$pct = 50){
//1.打开原图资源
$dst = imagecreatefromjpeg($image);
//2.打开水印图资源
$src = imagecreatefrompng($water);
//3.采样复制合并:存放到做上角(不需要计算)
$src_info = getimagesize($water);
imagecopymerge($dst,$src,0,0,0,0,$src_info[0],$src_info[1],$pct);
//4.保存图片
//获取原图片路径和名字信息
$image_info = pathinfo($image); #返回数组:extension是后缀名,filename是纯名字
//拼凑新文件名字
$water_name = $image_info['filename'] . '_water' . '.' . $image_info['extension'];
imagejpeg($dst,$path . '/' . $water_name);
//5.销毁资源
imagedestroy($dst);
imagedestroy($src);
//6.返回文件名
return $water_name;
}
总结
- 水印图分为文字水印图(验证码)和图片水印图
- 水印图的制作流程:打开原图->打开水印图->采样复制合并->保存图片->销毁资源
- 水印图不像验证码,一般是规定位置规定水印图样章的
思考:在很多网站上,上传图片的时候都会有个小图可以看的,那么是怎么实现的呢?
引入:其实小图的本质并不是用户上传的,而是系统根据系统需求在用户上传原图的时候,制作的一个小图。这个小图就是缩略图。
4. 制作缩略图【掌握】
定义:制作缩略图,就是将原图放到一个固定的大小的图片资源里,形成一张新的图片。通常是把大图做成小图,因此叫做缩略图。
- 缩略图制作原理
- 打开原图资源:imagecreatefromjpeg
- 创建缩略图资源:imagecreatetruecolor
- 采样复制合并:imagecopyresampled(不失真)
- 保存缩略图资源:imagejpeg(较多)
- 销毁资源
- 实现缩略图
<?php
//制作缩略图
//1.打开原图资源
$src = imagecreatefromjpeg('desktop.jpg');
//2.创建缩略图资源
$dst = imagecreatetruecolor(100,100);
//3.采样复制合并
$src_info = getimagesize('desktop.jpg');
imagecopyresampled($dst,$src,0,0,0,0,100,100,$src_info[0],$src_info[1]);
//4.保存输出
header('content-type:image/jpeg');
imagejpeg($dst);
imagejpeg($dst,'desktop_thumb.jpg');
//5.销毁资源
imagedestroy($src);
imagedestroy($dst);
- 缩略图注意事项:原图与缩略图比例不一样采用全部填充满,会导致缩略图“变形”,这种时候的解决方案如下
- 求出原图的宽高比
- 求出缩略图的宽高比
- 比较原图的宽高比和缩略图的宽高比
- 原图宽高比大于缩略图宽高比,说明原图太宽,应该让缩略图的宽占满,高按比例求出来
- 原图宽高比小于缩略图宽高比,说明原图太高,应该让缩略图的高占满,宽按比例求出来
- 不管哪种情况,势必会有缩略图部分区域没有放上内容,这个时候缩略图背景填充为白色(补白)
- 根据计算出来的实际宽高像素,将图片居中到缩略图中
- 制作缩略图函数(补白)
<?php
//制作补白效果缩略图
/*
@param1 string $image,原图地址
@param2 string $path,缩略图存储路径
@param3 int $width = 100,缩略图宽
@param4 int $height = 100,缩略图高
*/
function getThumb($image,$path,$width = 100,$height = 100){
//1.打开原图资源
$src = imagecreatefromjpeg($image);
//2.创建缩略图画布
$thu = imagecreatetruecolor($width,$height);
//3.补白:背景填充白色
$white = imagecolorallocate($thu,255,255,255);
imagefill($thu,0,0,$white);
//4.计算缩略图所放图片的实际宽和高:通过原图宽高比和缩略图宽高比来比较
$src_info = getimagesize($image);
//原图宽高比
$src_c = $src_info[0] / $src_info[1];
$thu_c = $width / $height;
//判定
if($src_c > $thu_c){
#原图宽高比大于缩略图,说明原图很宽,那么缩略图中宽度应该占满
$thu_w = $width; #占满缩略图宽
$thu_h = ceil($thu_w / $src_c); #取整
}else{
#原图宽高比小于缩略图,说明原图很高,那么缩略图中高度应该占满
$thu_h = $height;
$thu_w = ceil($thu * $src_c);
}
//5.采样复制粘贴:还需让缩略图居中
$x = ceil(abs($thu_w - $width) / 2); //绝对值除以2取整
$y = ceil(abs($thu_h - $height) / 2);
imagecopyresampled($thu,$src,$x,$y,0,0,$thu_w,$thu_h,$src_info[0],$src_info[1]);
//6.保存图片
$image_info = pathinfo($image);
//构造新文件名字
$newname = $image_info['filename'] . '_thumb' . '.' . $image_info['extension'];
imagejpeg($thu,$path . '/' . $newname);
//7.销毁资源
imagedestroy($src);
imagedestroy($thu);
//8.返回结果
return $newname;
}
总结
- 缩略图是在用户上传原图的时候系统根据需求自动生成的
- 缩略图要保证与原图比例一致,就需要进行缩略图中图片实际的尺寸,并进行补白