PHP笔记:GD库的应用实例

文章目录

  • 简介
  • 利用GD库生成4位随机验证码并利用Session保存
  • 导入外部图像
  • 为上传到网站的图片添加水印
    • 文字水印
    • 图片水印
  • 设计折线图
  • JpGraph图表类库

简介

GD库是php处理图形的扩展库,GD库提供了一系列用来处理图片的API,使用GD库可以处理图片,或者生成图片,也可以给图片加水印。最新版的GD库支持GIF、JPEG、PNG、WBMP、XBM等格式的图像文件,此外还支持winows下的ttf字体、FreeType等字体显示。通过GD库中的函数可以完成各种点、线、几何图形、文本、颜色的操作和处理。

GD库在PHP5之后的版本是默认安装的,但要设置php.ini文件激活,方法很简单,就是将该文件中的";extension=php_gd2.dll"选项前的分号";"删除,保存修改后的文件,再重新启动Apache服务器即可生效。

利用GD库生成4位随机验证码并利用Session保存

在这里插入图片描述

  • index.php
    设计一个用户登录表单,在验证码文本框后面插入一个标签,设置标签的src属性值为调用checks.php文件,生成一个随机验证码图像。
<!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>
  • checks.php
    使用GD2函数库创建一个4位的验证码,并且将生成的验证码保存在SESSION变量中。

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);     //释放图像资源,画布的引用句柄如果不再使用,一定要将这个资源销毁,释放内存与该图像的存储单元。
?>

输出:
PHP笔记:GD库的应用实例_第1张图片
PHP笔记:GD库的应用实例_第2张图片
代码释疑:
checks.php只是帮助Index.php显示验证码的同时将验证码字符串的4个字符保存的服务器Session文件中(F:\WAMP_Environment\PHP7.1\tmp),处理逻辑都在index.php,我们将表单内容提交到服务器后,Apache服务器调用CGI语言PHP处理页面中的内容,查找Session文件中字符串是否匹配,若匹配,在原始index.php中显示的HTML内容上加上"

验证码输入正确

"返回给客户端浏览器显示。这里额外提一点,就是格式验证通常利用javascript在客户端浏览器进行验证,而不是通过网络提交到服务器再利用PHP这种后端语言进行处理,再返回给客户端浏览器。

导入外部图像

在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、微博网等这些大流量站点每天都会有用户上传大量图片,这些图片版权属于用户;还有一些比如类似新闻网的网站上发布的图片,这些图片的版权属于整个站点。但在图片上传到网站后,很有可能被网站其他浏览者保存到本地自己使用,然后又重新发布到网上,这样图片的版权问题就不能很好的保证。如果在上传图片过程中,动态地为图片添加水印效果,这样不仅可以对保证站点版权起到一定的作用,如果设计合理则有助于网站的推广。

文字水印

PHP笔记:GD库的应用实例_第3张图片

  • 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 "";
  }
 }
 
?>
  • 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)//服务器图片文件的相对路径,待添加到图片上的水印文字
 {
  $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);//销毁图像
 }
}
?>

输出结果(在upfiles文件夹中):
PHP笔记:GD库的应用实例_第4张图片

图片水印

基于上一个例子,稍加修改
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);               //销毁图像
 }
}
?>

输出:
PHP笔记:GD库的应用实例_第5张图片
PHP笔记:GD库的应用实例_第6张图片

设计折线图

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笔记:GD库的应用实例_第7张图片

JpGraph图表类库

该库的目的是使使用PHP脚本(非常)轻松地创建动态图像(又称图形)成为可能。该库将尽可能多地隐藏创建动态图像所需的所有细节。严格来说,绘制图像的所有基本底层功能都已在PHP中提供,因为PHP附带了核心GD库,该库是创建图像的最低层。GD库具有用于创建直线,圆,点等的图形基元,但是它没有内置的智能来处理刻度,标签,颜色等。从逻辑上讲,这使JpGraph库成为比原始GD库更易于访问的更高类型的库。
PHP笔记:GD库的应用实例_第8张图片
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();     //输出图像
?>

输出:
PHP笔记:GD库的应用实例_第9张图片
官方文档:https://jpgraph.net/download/manuals/chunkhtml/index.html有更多详细的例子

你可能感兴趣的:(PHP)