GD库是php处理图形的扩展库,GD库提供了一系列用来处理图片的API,使用GD库可以处理图片,或者生成图片,也可以给图片加水印。最新版的GD库支持GIF、JPEG、PNG、WBMP、XBM等格式的图像文件,此外还支持winows下的ttf字体、FreeType等字体显示。通过GD库中的函数可以完成各种点、线、几何图形、文本、颜色的操作和处理。
GD库在PHP5之后的版本是默认安装的,但要设置php.ini文件激活,方法很简单,就是将该文件中的";extension=php_gd2.dll"选项前的分号";"删除,保存修改后的文件,再重新启动Apache服务器即可生效。
<!DOCTYPE>
<html>
<head>
<meta charset="utf-8">
<title>DB库生成随机验证码</title>
<style>
label{
cursor: pointer;/*鼠标悬停时的鼠标样式*/
display: inline-block;
text-align: left;
width: 70px;
vertical-align: bottom;/*把元素的顶端与行中最高元素的顶端对齐*/
}
input{
text-align: left;
width: 150px;
}
.sub{
text-align: center;
width:50px;
height:30px;
}
</style>
</head>
<body>
if(!isset($_SESSION))
{
session_start();//开启服务器与客户端的Session会话,才能使用PHP内置的Session变量
}
?>
if(!isset($_SESSION)){
session_start();//开启服务器与客户端的Session会话,才能使用PHP内置的Session变量
}
if(!empty($_POST["submit"])&&$_POST["submit"]!="")//通过表单name属性取出用户输入文本框的信息
{
$checks=$_POST["checks"];//获取用户提交的验证码信息
if($checks=="")
{
echo "";
}
if($checks==$_SESSION["check_checks"])
{
echo "验证码输入正确
";
}
else
{
echo "";
}
}
?>
<h2>用户登录</h2>
<form name="form" method="post" action=""><!--表单提交到当前页面-->
<fieldset><!--标签会在相关表单元素周围绘制边框。-->
<p>
<label for="txt_user">用户名:</label><!--"for" 属性可把 label 绑定到另外一个元素。请把 "for" 属性的值设置为相关元素的 id 属性的值。-->
<input type="text" name="txt_user" id="txt_user" size="20">
</p>
<p>
<label for="txt_pwd">密 码:</label>
<input type="password" name="txt_pwd" id="txt_pwd" size="20">
</p>
<p>
<label>验证码:</label>
<input type="text" name="checks" size="6">
<img src="checks.php" width="70" height="18" border="0">
</p>
<p>
<input type="submit" name="submit" value="登录" class="sub">
</p>
</fieldset>
</form>
</body>
</html>
if(!isset($_SESSION)){
session_start();//开启服务器与客户端的Session会话,才能使用PHP内置的Session变量
}
header("content-type:image/png"); //设置创建图像的格式//header("content-type:image/png");//在HTTP头部指定发送的内容类型为图片格式
$image_width=70;//图像宽度
$image_height=15;//图像高度
list($usec, $sec) = explode(' ', microtime());
srand((double)$sec+(double)$usec*100000);////以系统的的时间戳(时间一直在变,种子也在变)设置随机数的种子,起码能保证在本次刷新中四个验证码不出现相同
$new_number="";
for($i=0;$i<4;$i++)
{
$new_number.=dechex(rand(0,15));//dechex()将十进制数字转换为十六进制,这样验证码中还可能包含a~f这几个字母
}
$_SESSION['check_checks']=$new_number;//将获取的随机数验证码写入到Session变量check_checks中
//接下来利用GD库对$new_number进行上色
$num_image=imagecreate($image_width,$image_height);//创建一个画布
imagecolorallocate($num_image,255,255,255); //设置画布的背景颜色为白色
for($i=0;$i<strlen($_SESSION['check_checks']);$i++)//循环读取SESSION变量check_checks中的验证码
{//mt_rand()函数可以产生随机数值的平均速度比 libc 提供的 rand() 快四倍。
$font=mt_rand(3,5);
$x=mt_rand(1,8)+$image_width*$i/4;//设置随机字符所在位置的X坐标
$y=mt_rand(1,$image_height/4);//设置随机字符所在位置的Y坐标
$color=imagecolorallocate($num_image,mt_rand(0,255),mt_rand(0,255),mt_rand(0,255));
imagestring($num_image,$font,$x,$y,$_SESSION['check_checks'][$i],$color);//在图像中添加文字
}
imagepng($num_image); //生成PNG格式的图像
imagedestroy($num_image); //释放图像资源,画布的引用句柄如果不再使用,一定要将这个资源销毁,释放内存与该图像的存储单元。
?>
输出:
代码释疑:
checks.php只是帮助Index.php显示验证码的同时将验证码字符串的4个字符保存的服务器Session文件中(F:\WAMP_Environment\PHP7.1\tmp),处理逻辑都在index.php,我们将表单内容提交到服务器后,Apache服务器调用CGI语言PHP处理页面中的内容,查找Session文件中字符串是否匹配,若匹配,在原始index.php中显示的HTML内容上加上"
在GD函数库中,有一组专门用于导入外部图像的函数:
imagecreatefromgif ( string $filename ) : resource
由文件或 URL 创建一个新gif格式图象。
imagecreatefromjpeg ( string $filename ) : resource
由文件或 URL 创建一个新jpeg格式图象。
imagecreatefrompng ( string $filename ) : resource
由文件或 URL 创建一个新png格式图象。
test1.php
function LoadGif($imgname)
{
$im = @imagecreatefromgif($imgname);/* Attempt to open ,@是PHP提供的错误信息屏蔽的专用符号。*/
if(!$im)/* See if it failed */
{
$im = imagecreatetruecolor (150, 30);/* Create a blank image */
$bgc = imagecolorallocate ($im, 255, 255, 255);
$tc = imagecolorallocate ($im, 0, 0, 0);
imagefilledrectangle ($im, 0, 0, 150, 30, $bgc);
imagestring ($im, 1, 5, 5, 'Error loading ' . $imgname, $tc);/* Output an error message */
}
return $im;
}
header('Content-Type: image/gif');
$img = LoadGif('girl.gif');
imagegif($img);
imagedestroy($img);
图片是Web页面最为重要的组成元素之一,CSDN、微博网等这些大流量站点每天都会有用户上传大量图片,这些图片版权属于用户;还有一些比如类似新闻网的网站上发布的图片,这些图片的版权属于整个站点。但在图片上传到网站后,很有可能被网站其他浏览者保存到本地自己使用,然后又重新发布到网上,这样图片的版权问题就不能很好的保证。如果在上传图片过程中,动态地为图片添加水印效果,这样不仅可以对保证站点版权起到一定的作用,如果设计合理则有助于网站的推广。
font
存放imagettftext ( resource $image , float $size , float $angle , int $x , int $y , int $color , string $fontfile , string $text ) : array
需要用到的字体参数
images
模拟客户端浏览器待上传到服务器的图片
upfiles
模拟服务器端存放客户端上传的经过PHP脚本处理添加水印后的图片
index.php
创建一个交互表单前台页面,也是提交后的后台处理页面,进行图片格式判断以及后缀名提取,将客户端文件夹images的上传的图片保存到服务器端文件夹upfiles,接着调用AddWaterPress.php中的文件类方法在服务器端为图片绘制文字水印。
<!DOCTYPE>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<h2>图片上传</h2>
<form name="form1" method="post" action="$_SERVER['PHP_SELF']?>" enctype="multipart/form-data">
选择图片:
<input type="file" name="file" class="input">
<input type="hidden" name="flag" value="1">
<input type="submit" name="imageField" value="上传">
</form>
</body>
</html>
if(!empty($_FILES["file"])&&$_POST["flag"]=='1')//判断提交内容是否为空
{
$type=strstr($_FILES["file"]["name"],'.');//获取上传图片后缀
if($_FILES["file"]["name"]=='')//判断上传图片名称是否为空
{
echo "";
exit();
}
else if(!($type=='.jpg')&&!($type=='.png')&&!($type=='.gif'))//判断上传图片格式是否正确
{
echo "";
exit();
}
function getUpfileName($fileName)//定义上传文件在服务器中存储的名称
{
return 'waterpress'.strstr($fileName,".");//使用固定名称
}
$saveDir="upfiles/".getUpfileName($_FILES["file"]["name"]);//定义上传文件存储路径
if(move_uploaded_file($_FILES["file"]["tmp_name"],$saveDir))//执行文件上传操作
{
require_once 'AddWaterPress.php';//包含添加水印操作的文件
$addWaterPress=new addWaterPress();//类的实例化
$addWaterPress->add($saveDir, iconv("gb2312","utf-8","www.mysite.com"));//执行添加方法,传递参数,指定水印文字
echo "";
}
}
?>
class AddWaterPress//定义文件类
{
function getExtendsName($fileName)//获取上传图片后缀(小写)
{
return strtolower(strstr($fileName,"."));//返回图片后缀
}
function getImageRes($extendsName,$imageUrl)//根据上传图片的后缀,和上传文件的路径新建图像
{
switch($extendsName)//根据上传图片的后缀进行判断,利用不同的函数创建不同格式的图像画布
{
case '.gif':
$img=imagecreatefromgif($imageUrl);
break;
case '.jpg':
$img=imagecreatefromjpeg($imageUrl);
break;
case '.png':
$img=imagecreatefrompng($imageUrl);
break;
}
return $img;
}
function outPutImage($img,$extendsName,$imageUrl)//根据图像标识、图片后缀和路径输出图像
{
switch($extendsName)
{
case '.gif':
imagegif($img,$imageUrl);
break;
case '.jpg':
imagejpeg($img,$imageUrl);
break;
case '.png':
imagepng($img, $imageUrl);
break;
}
}
function add($imageUrl,$waterImageUrl)//服务器图片文件的相对路径,待添加到图片上的水印文字
{
$img=@$this->getImageRes($this->getExtendsName($imageUrl),$imageUrl);
$textcolor=imagecolorallocate($img,0,0,255);//设置颜色字体为红色
$font=str_replace('\\','/',__DIR__)."/font/Candara.ttf";//__DIR__则是php5.3版本新增的一个魔术变量,指向当前执行的PHP脚本所在的目录。
imagettftext($img,50,0,40,60,$textcolor,$font,$waterImageUrl);//使用TrueType字体向图像写入文本
$this->outPutImage($img,$this->getExtendsName($imageUrl),$imageUrl);
imagedestroy($img);//销毁图像
}
}
?>
基于上一个例子,稍加修改
index.php
<!DOCTYPE>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<h2>图片上传</h2>
<form name="form1" method="post" action="$_SERVER['PHP_SELF']?>" enctype="multipart/form-data">
选择图片:
<input type="file" name="file" class="input">
<input type="hidden" name="flag" value="1">
<input type="submit" name="imageField" value="上传">
</form>
</body>
</html>
if(!empty($_FILES["file"])&&$_POST["flag"]=='1')//判断提交内容是否为空
{
$type=strstr($_FILES["file"]["name"],'.');//获取上传图片后缀
if($_FILES["file"]["name"]=='')//判断上传图片名称是否为空
{
echo "";
exit();
}
else if(!($type=='.jpg')&&!($type=='.png')&&!($type=='.gif'))//判断上传图片格式是否正确
{
echo "";
exit();
}
function getUpfileName($fileName)//定义上传文件在服务器中存储的名称
{
return 'waterpress'.strstr($fileName,".");//使用固定名称
}
$saveDir="upfiles/".getUpfileName($_FILES["file"]["name"]);//定义上传文件存储路径
if(move_uploaded_file($_FILES["file"]["tmp_name"],$saveDir))//执行文件上传操作
{
require_once 'AddWaterPress.php';//包含添加水印操作的文件
$addWaterPress=new addWaterPress();//类的实例化
$addWaterPress->add($saveDir, "wateriImage/baidu.png",low_right,low_right);//执行添加方法,传递参数,指定水印文字
echo "";
}
}
?>
AddWaterPress.php
class AddWaterPress//定义文件类
{
function getExtendsName($fileName)//获取上传图片后缀(小写)
{
return strtolower(strstr($fileName,"."));//返回图片后缀
}
function getImageRes($extendsName,$imageUrl)//根据上传图片的后缀,和上传文件的路径新建图像
{
switch($extendsName)//根据上传图片的后缀进行判断,利用不同的函数创建不同格式的图像画布
{
case '.gif':
$img=imagecreatefromgif($imageUrl);
break;
case '.jpg':
$img=imagecreatefromjpeg($imageUrl);
break;
case '.png':
$img=imagecreatefrompng($imageUrl);
break;
}
return $img;
}
function outPutImage($img,$extendsName,$imageUrl)//根据图像标识、图片后缀和路径输出图像
{
switch($extendsName)
{
case '.gif':
imagegif($img,$imageUrl);
break;
case '.jpg':
imagejpeg($img,$imageUrl);
break;
case '.png':
imagepng($img, $imageUrl);
break;
}
}
function add($imageUrl,$waterImageUrl,$x,$y)//服务器图片文件的相对路径,待添加到图片上的水印文字
{
$img1=@$this->getImageRes($this->getExtendsName($imageUrl),$imageUrl);//获取客户端上传图像的图像标识
$img2=@$this->getImageRes($this->getExtendsName($waterImageUrl),$waterImageUrl);//获取水印图像的图像标识
$size1=getimagesize($imageUrl);
$size2=getimagesize($waterImageUrl);
if($x==null&&$y==null)//图片水印居中显示
{
$x1=($size1[0]-$size2[0])/2;
$y1=($size1[1]-$size2[1])/2;
}
else if($x==low_right&&$y==low_right)//图片水印右下角显示
{
$x1=$size1[0]-$size2[0];
$y1=$size1[1]-$size2[1];
}
else//直接使用坐标数据
{
$x1=$x;
$y1=$y;
}
imagecopy($img1,$img2,$x1,$y1,0,0,$size2[0],$size2[1]);
//将水印图像$img2的(0,0)开始像素大小为原始大小($size2[0],$size2[1])复制到$img1的($x1,$y1)位置
$this->outputImage($img1, $this->getExtendsName($imageUrl), $imageUrl);
imagedestroy($img1); //销毁图像
imagedestroy($img2); //销毁图像
}
}
?>
index.php
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<script>
function chkinput(form)
{
if(form.T1.value=='' || form.T2.value=='' || form.T3.value=='' || form.T4.value=='' || form.T5.value=='' || form.T6.value=='' || form.T7.value=='' || form.T8.value=='' || form.T9.value=='' || form.T10.value=='' || form.T11.value=='' || form.T12.value=='')
{
alert("表单中的数值不能为空!");
return false;
}
return true;
}
</script>
<style type="text/css">
form p{
float:left;
width:30%;
margin:10px;
}
</style>
</head>
<body>
<h2>网站月度流量统计</h2>
<form method="post" name="myform" action="img.php" onsubmit="return chkinput(this)">
<p>1月:<input name="T1" type="text" size="12"></p>
<p>2月:<input name="T2" type="text" size="12"></p>
<p>3月:<input name="T3" type="text" size="12"></p>
<p>4月:<input name="T4" type="text" size="12"></p>
<p>5月:<input name="T5" type="text" size="12"></p>
<p>6月:<input name="T6" type="text" size="12"></p>
<p>7月:<input name="T7" type="text" size="12"></p>
<p>8月:<input name="T8" type="text" size="12"></p>
<p>9月:<input name="T9" type="text" size="12"></p>
<p>10月:<input name="T10" type="text" size="12"></p>
<p>11月:<input name="T11" type="text" size="12"></p>
<p>12月:<input name="T12" type="text" size="12"></p>
<p><input type="hidden" name="flag" value="1"><input type="submit" value="提交" name="submit"></p>
</form>
</body>
</html>
img.php
header("Content-type:image/gif");
$data=array ($_POST ["T1"], $_POST ["T2"], $_POST ["T3"], $_POST ["T4"], $_POST ["T5"], $_POST ["T6"], $_POST ["T7"], $_POST ["T8"], $_POST ["T9"], $_POST ["T10"], $_POST ["T11"], $_POST ["T12"] );
$month=array("Jan", "Feb", "March", "April", "May", "June", "July", "Aug", "Sep", "Oct", "Nov", "Dec" );
$max=0;
for($i=0;$i<12;$i++)
{
$max=$max+$data[$i];//所有网站访问量的累加和
}
$im=imagecreate(550,300);
$green = imagecolorallocate ( $im, 214, 235, 214 ); //第一个imagecolorallocate()设置为背景色,后面多次调用不覆盖
$black = imagecolorallocate ( $im, 0, 0, 0 );
$red = imagecolorallocate ( $im, 255, 0, 0 );
$blue = imagecolorallocate ( $im, 0, 0, 255 );
imageline ( $im, 30, 250, 520, 250, $blue ); //设置X轴横坐标
imageline ( $im, 30, 10, 30, 250, $blue ); //设置Y轴纵坐标
imagestring ( $im, 5, 520, 255, "X", $black ); //输出字符X
imagestring ( $im, 5, 16, 1, "Y", $black ); //输出字符Y
$l=250;
$k1=30;
$k2=510;
for($j=0;$j<12;$j++)
{
imageline($im,$k1,$l,$k2,$l,$black);//设置X轴网格线横坐标
$l=$l-40;
}
$f = 70;
$z1 = 10;
$z2 = 250;
for($j = 0; $j < 12; $j ++) {
imageline ( $im, $f, $z1, $f, $z2, $black ); //设置Y轴网格线纵坐标
$f = $f + 40;
}
//输出Y轴坐标值
$l = 205;
for($j = 1; $j < 6; $j ++) {
imagestring ( $im, 2, 2, $l, 20 * $j . "%", $red );
$l = $l - 40;
}
$x = 20;
$y = 230;
for($i = 1; $i < 12; $i ++) {
$y_lt = $y - (($data [$i - 1] / $max) * 200); //设置网站访问量的纵坐标值
$y_ht = $y - (($data [$i] / $max) * 200); //获取每月网站访问量数的纵坐标值
imageline ( $im, $x * ($i * 2 - 1) + 30, $y_lt, $x * (($i + 1) * 2 - 1) + 30, $y_ht, $red ); //绘制网站访问量折线图
}
for($i = 1; $i < 13; $i ++) {
$r1 = round ( ( ($data [$i - 1]) / $max) * 100, 2 );
imagestring ( $im, 2, $x * ($i - 1) * 2 + 60, $y + 20, $month [$i - 1], $black ); //输出月份的值
imagestring ( $im, 2, $x * ($i - 1) * 2 + 55, $y + 30, $r1 . "%", $red ); //输出网站访问量的百分比
}
imagepng ( $im );
imagedestroy ( $im ); //释放图像资源
?>
该库的目的是使使用PHP脚本(非常)轻松地创建动态图像(又称图形)成为可能。该库将尽可能多地隐藏创建动态图像所需的所有细节。严格来说,绘制图像的所有基本底层功能都已在PHP中提供,因为PHP附带了核心GD库,该库是创建图像的最低层。GD库具有用于创建直线,圆,点等的图形基元,但是它没有内置的智能来处理刻度,标签,颜色等。从逻辑上讲,这使JpGraph库成为比原始GD库更易于访问的更高类型的库。
index.php
header ( "Content-type: text/html; charset=UTF-8" ); //设置文件编码格式
require_once ('../jpgraph-4.2.10/src/jpgraph.php'); //导入Jpgraph类库
require_once ('../jpgraph-4.2.10/src/jpgraph_bar.php'); //导入Jpgraph类库的柱状图功能
$data = array(78, 75, 78, 75, 82, 75 ,82 ,65, 84, 79, 85, 78); //设置统计数据
$graph = new Graph(600, 300); //设置画布大小
$graph->SetScale('textlin'); //设置坐标刻度类型
$graph->SetShadow(); //设置画布阴影
$graph->img->SetMargin(40, 30, 20, 40); //设置统计图边距
$barplot = new BarPlot($data); //实例化BarPlat对象
$barplot->SetFillColor('blue'); //设置柱形图前景色
$barplot->value->Show(); //输出数据
$graph->Add($barplot); //添加数据
$graph->title->Set(iconv("utf-8","gb2312",'公司年度收支')); //设置统计图标题
$graph->xaxis->title->Set(iconv("utf-8","gb2312",'月份')); //设置X轴名称
$graph->yaxis->title->Set(iconv("utf-8","gb2312",'总金额(万元)')); //设置y轴名称
$graph->title->SetFont(FF_SIMSUN, FS_BOLD); //设置标题字体
$graph->xaxis->title->SetFont(FF_SIMSUN,FS_BOLD); //设置X轴字体
$graph->yaxis->title->SetFont(FF_SIMSUN,FS_BOLD); //设置Y轴字体
$graph->Stroke(); //输出图像
?>
输出:
官方文档:https://jpgraph.net/download/manuals/chunkhtml/index.html有更多详细的例子