使用PHP和GD进行图形处理(二)
时间:2007-02-17 来源:PHP爱好者
线形图形
为了开始,我们可以创建一个空的200x200像素的画布,并填充为灰色。在这上面可以绘制我们的线段。
我们可以为每个办公室分配一个颜色,红色代表伦敦,兰色代表亚特兰大。
现在可以开始取出数据并把它画出来了。需要牢记的一件重要的事就是在画线的时候,ImageLine 要求
我们告诉它开始处的x和y坐标还有线的结束坐标。现在如果从一个数据库中抓出数据,将一次只能得到一组
坐标。所以可以或者将数据存储在数组中,或使用一个临时变量来保存前一组坐标。我选择了使用数组。
除了将要绘制的实际坐标之外,还需要知道可达到的最大值(图形的顶部)还有信息列的数目(沿着x轴要
画的点的个数)。所以在与数据库连接之后,从数据库中选出了MAX(g_num) 值并将其保存起来为后面使用。
然后选出所以g_team等于'London'的所有记录,并得到返回的记录行数,所以我们将知道有多少要处理的数
据列数。从前面的表格中,你可以看到我们将处理6个月或列数据,并且最大值为410。
<?php
$columns = 6;
$max = 410;
?>
x值总是最容易处理的 -- 它的范围从0到图像的宽度,此处为200。我们将在0处理开始画线并希望在200
结束,所以在以$x=0开始之后,将需要增加$x值直到$columns-1次(此处为5)以达到200 -- 这样我们要画
6次,最后一次将在200处。记住这点以后我们可以创建一个名为$xincrement的变量,并赋给它200除以
($columns-1)的值。然后将给出$x一个开始值0 并且在每一次循环的底部,当从结果集中抓取记录行时,我
们可以给$x增加$xincement。
<?php
$xincrement = bcdiv(200,$columns-1,0);
?>
bcdiv用第二个参数除以第一个参数,并且返回根据第三个参数所指定的小数位数的值。为了使用BCMath
函数,你需要在Unix下将其编译到PHP中,但是Windows版本已经将其编译进去了。README.BCMATH在PHP源代
码的根目录中,它将解释在哪和如何做。
y值将与$max数值成比例,所以我们所能做的就是用$max来除g_num得到比例的小数值,然后乘以200 --
图像的高度。
<?php
$y = bcmul(bcdiv($salesRow[0],$max,2),200,2);
?>
$salesRow[0]是当前行的g_num值,除上$max,并且结果定为小数部分为2位。然后使用bcmul将结果与200
相乘。
然后可以做的就是在整个数组中循环,使用当前元素作为线的开始,当前元素+1作为线的结束。因为最
后一个元素将永远不会是一行的开始,我们必需将循环减1,所以将当小于或等于$columns-1 时循环改为小
于$columns-1时循环。
让我们看一下迄今为止的代码:
<?php
// 发送头信息和创建初始的空白画布
Header( "Content-type: image/gif");
$image = imagecreate(200,200);
// 分配一些颜色
$red = ImageColorAllocate($image,255,0,0);
$blue = ImageColorAllocate($image,0,0,255);
$white = ImageColorAllocate($image,255,255,255);
$grey = ImageColorAllocate($image,200,200,200);
// 创建一个初始的灰色矩形用于绘图
ImageFilledRectangle($image,0,0,200,200,$grey);
// 连接mysql服务器并选择数据库
$connect = mysql_connect("","root","");
mysql_select_db("graphing",$connect);
// 找到结果集中的最大数值
$sql = "SELECT MAX(g_num) FROM sales";
$maxResult = mysql_query($sql,$connect);
$max = mysql_result($maxResult,0,0);
// 得到伦敦的结果集
$sql = "SELECT g_num FROM sales WHERE g_team='London' ORDER BY g_month";
$salesResult = mysql_query($sql,$connect);
// 找到返回多少列,就是'columns'的数值
$columns = mysql_num_rows($salesResult);
// $x每次增加多少量?
$xincrement = bcdiv(200,$columns-1,0);
$x=0;
// $i 将记录行的数值
$i=0;
// 在我们所有的数据行中循环
while($salesRow=mysql_fetch_array($salesResult)) {
// 象上面所讨论地计算y的坐标值
$y = bcmul(bcdiv($salesRow[0],$max,2),200,2);
// 在$points数组中增加值
$points[$i][0] = $x;
$points[$i][1] = $y;
// 增加$x的值用$xincrement
$x+=$xincrement;
// 增加 $i
$i++;
}
// 现在我们在$points数组中循环,此时$i小于$columns-1
for($i=0;$i<$columns-1;$i++) {
// 我们传递 $points[$I][0] 作为第一个x坐标,$points[$I][1] 为第一个y坐标
// $points[$I+1][0], $points[$I+1][1] 将是下一个x,y坐标集
ImageLine($image,$points[$i][0],$points[$i][1],$points[$i+1][0],
$points[$i+1][1],$red);
}
// 输出GIF给浏览器并且释放内存
ImageGIF($image);
ImageDestroy($image);
?>
这样将给出我们如下的结果:
<img src="http://www.phpstar.com/pic/2000090702.gif">
它既不正确也很气人。问题在于我们是按传统的x和y坐标方法处理的,这种方法是从左下角向外发散的。
Image函数的坐标系统是从左上角发散的,所以这时我们的x位置是正确的,我们的y位置弄反了。
我们需要做的就是修改确定y位置的代码以便按相反的方式工作 -- 改变行
<?php
ImageLine($image,$points[$i][0],$points[$i][1],$points[$i+1][0],$points[$i+1][1],$red);
?>
变成读取:
<?php
ImageLine($image,$points[$i][0],200-$points[$i][1],$points[$i+1][0],200-$points[$i+1][1],$red);
?>
我们将得到图形:
<img src="http://www.phpstar.com/pic/2000090703.gif">
现在我们需要做的是加入一条线,它是将亚特兰大的数据进行了图形化。
<?php
$sql = "SELECT g_num FROM sales WHERE g_team='Atlanta' ORDER BY g_month";
$salesResult = mysql_query($sql,$connect);
$columns = mysql_num_rows($salesResult);
$xincrement = bcdiv(200,$columns-1,0);
$x=0;
$i=0;
while($salesRow=mysql_fetch_array($salesResult)) {
$y = bcmul(bcdiv($salesRow[0],$max,2),200,2);
$points[$i][0] = $x;
$points[$i][1] = $y;
$x+=$xincrement;
$i++;
}
for($i=0;$i<$columns-1;$i++) {
ImageLine($image,$points[$i][0],200-$points[$i][1],$points[$i+1][0],200-$points[$i+1][1],$blue);
}
?>
<img src="http://www.phpstar.com/pic/2000090704.gif">
我们用在这个例子中的数据是静态的,在以后的部分我们将看一下如何处理动态数据,并且看一下在图
表中增加一些轴线和标签。
译者注:
本文中的例子,我已经在php 3.0.16下,使用旧版的gd库测试成功。对于高版本的php(4.0以上版本)由于不再支持gif文件,所以我将Imagegif改成了ImagePNG函数执行后,成功。而且对于Header输出的MIME类型可以仍然使用image/gif格式说明。如果大家有什么建议欢迎来信。对于php 4.0.2版本与其使用的gd库均可从http://www.mm4.de/处下载。不过这个网站上则是全的文件包而不是独立的动态库。还有一点要说明的是这里我所说的版本全部是windows下的。至于linux则可以直接在编译时设定即可。
php爱好者站 http://www.phpfans.net 为phper提供一切资讯.
为了开始,我们可以创建一个空的200x200像素的画布,并填充为灰色。在这上面可以绘制我们的线段。
我们可以为每个办公室分配一个颜色,红色代表伦敦,兰色代表亚特兰大。
现在可以开始取出数据并把它画出来了。需要牢记的一件重要的事就是在画线的时候,ImageLine 要求
我们告诉它开始处的x和y坐标还有线的结束坐标。现在如果从一个数据库中抓出数据,将一次只能得到一组
坐标。所以可以或者将数据存储在数组中,或使用一个临时变量来保存前一组坐标。我选择了使用数组。
除了将要绘制的实际坐标之外,还需要知道可达到的最大值(图形的顶部)还有信息列的数目(沿着x轴要
画的点的个数)。所以在与数据库连接之后,从数据库中选出了MAX(g_num) 值并将其保存起来为后面使用。
然后选出所以g_team等于'London'的所有记录,并得到返回的记录行数,所以我们将知道有多少要处理的数
据列数。从前面的表格中,你可以看到我们将处理6个月或列数据,并且最大值为410。
<?php
$columns = 6;
$max = 410;
?>
x值总是最容易处理的 -- 它的范围从0到图像的宽度,此处为200。我们将在0处理开始画线并希望在200
结束,所以在以$x=0开始之后,将需要增加$x值直到$columns-1次(此处为5)以达到200 -- 这样我们要画
6次,最后一次将在200处。记住这点以后我们可以创建一个名为$xincrement的变量,并赋给它200除以
($columns-1)的值。然后将给出$x一个开始值0 并且在每一次循环的底部,当从结果集中抓取记录行时,我
们可以给$x增加$xincement。
<?php
$xincrement = bcdiv(200,$columns-1,0);
?>
bcdiv用第二个参数除以第一个参数,并且返回根据第三个参数所指定的小数位数的值。为了使用BCMath
函数,你需要在Unix下将其编译到PHP中,但是Windows版本已经将其编译进去了。README.BCMATH在PHP源代
码的根目录中,它将解释在哪和如何做。
y值将与$max数值成比例,所以我们所能做的就是用$max来除g_num得到比例的小数值,然后乘以200 --
图像的高度。
<?php
$y = bcmul(bcdiv($salesRow[0],$max,2),200,2);
?>
$salesRow[0]是当前行的g_num值,除上$max,并且结果定为小数部分为2位。然后使用bcmul将结果与200
相乘。
然后可以做的就是在整个数组中循环,使用当前元素作为线的开始,当前元素+1作为线的结束。因为最
后一个元素将永远不会是一行的开始,我们必需将循环减1,所以将当小于或等于$columns-1 时循环改为小
于$columns-1时循环。
让我们看一下迄今为止的代码:
<?php
// 发送头信息和创建初始的空白画布
Header( "Content-type: image/gif");
$image = imagecreate(200,200);
// 分配一些颜色
$red = ImageColorAllocate($image,255,0,0);
$blue = ImageColorAllocate($image,0,0,255);
$white = ImageColorAllocate($image,255,255,255);
$grey = ImageColorAllocate($image,200,200,200);
// 创建一个初始的灰色矩形用于绘图
ImageFilledRectangle($image,0,0,200,200,$grey);
// 连接mysql服务器并选择数据库
$connect = mysql_connect("","root","");
mysql_select_db("graphing",$connect);
// 找到结果集中的最大数值
$sql = "SELECT MAX(g_num) FROM sales";
$maxResult = mysql_query($sql,$connect);
$max = mysql_result($maxResult,0,0);
// 得到伦敦的结果集
$sql = "SELECT g_num FROM sales WHERE g_team='London' ORDER BY g_month";
$salesResult = mysql_query($sql,$connect);
// 找到返回多少列,就是'columns'的数值
$columns = mysql_num_rows($salesResult);
// $x每次增加多少量?
$xincrement = bcdiv(200,$columns-1,0);
$x=0;
// $i 将记录行的数值
$i=0;
// 在我们所有的数据行中循环
while($salesRow=mysql_fetch_array($salesResult)) {
// 象上面所讨论地计算y的坐标值
$y = bcmul(bcdiv($salesRow[0],$max,2),200,2);
// 在$points数组中增加值
$points[$i][0] = $x;
$points[$i][1] = $y;
// 增加$x的值用$xincrement
$x+=$xincrement;
// 增加 $i
$i++;
}
// 现在我们在$points数组中循环,此时$i小于$columns-1
for($i=0;$i<$columns-1;$i++) {
// 我们传递 $points[$I][0] 作为第一个x坐标,$points[$I][1] 为第一个y坐标
// $points[$I+1][0], $points[$I+1][1] 将是下一个x,y坐标集
ImageLine($image,$points[$i][0],$points[$i][1],$points[$i+1][0],
$points[$i+1][1],$red);
}
// 输出GIF给浏览器并且释放内存
ImageGIF($image);
ImageDestroy($image);
?>
这样将给出我们如下的结果:
<img src="http://www.phpstar.com/pic/2000090702.gif">
它既不正确也很气人。问题在于我们是按传统的x和y坐标方法处理的,这种方法是从左下角向外发散的。
Image函数的坐标系统是从左上角发散的,所以这时我们的x位置是正确的,我们的y位置弄反了。
我们需要做的就是修改确定y位置的代码以便按相反的方式工作 -- 改变行
<?php
ImageLine($image,$points[$i][0],$points[$i][1],$points[$i+1][0],$points[$i+1][1],$red);
?>
变成读取:
<?php
ImageLine($image,$points[$i][0],200-$points[$i][1],$points[$i+1][0],200-$points[$i+1][1],$red);
?>
我们将得到图形:
<img src="http://www.phpstar.com/pic/2000090703.gif">
现在我们需要做的是加入一条线,它是将亚特兰大的数据进行了图形化。
<?php
$sql = "SELECT g_num FROM sales WHERE g_team='Atlanta' ORDER BY g_month";
$salesResult = mysql_query($sql,$connect);
$columns = mysql_num_rows($salesResult);
$xincrement = bcdiv(200,$columns-1,0);
$x=0;
$i=0;
while($salesRow=mysql_fetch_array($salesResult)) {
$y = bcmul(bcdiv($salesRow[0],$max,2),200,2);
$points[$i][0] = $x;
$points[$i][1] = $y;
$x+=$xincrement;
$i++;
}
for($i=0;$i<$columns-1;$i++) {
ImageLine($image,$points[$i][0],200-$points[$i][1],$points[$i+1][0],200-$points[$i+1][1],$blue);
}
?>
<img src="http://www.phpstar.com/pic/2000090704.gif">
我们用在这个例子中的数据是静态的,在以后的部分我们将看一下如何处理动态数据,并且看一下在图
表中增加一些轴线和标签。
译者注:
本文中的例子,我已经在php 3.0.16下,使用旧版的gd库测试成功。对于高版本的php(4.0以上版本)由于不再支持gif文件,所以我将Imagegif改成了ImagePNG函数执行后,成功。而且对于Header输出的MIME类型可以仍然使用image/gif格式说明。如果大家有什么建议欢迎来信。对于php 4.0.2版本与其使用的gd库均可从http://www.mm4.de/处下载。不过这个网站上则是全的文件包而不是独立的动态库。还有一点要说明的是这里我所说的版本全部是windows下的。至于linux则可以直接在编译时设定即可。
php爱好者站 http://www.phpfans.net 为phper提供一切资讯.
相关阅读 更多 +