PHP动态图象的生成
By Brad Buylger 译者:sunnydogy
写在前面的话:
在我们开始之前,我先给你一个写PHP的建议:避免使用没有定义的变量,否则不
能很明确的看出变量是否为空。在一个比较函数中,如果有一个从未赋值的变量
就会产生错误。但如果已经设置了变量$what,那么可以通过函数isset($what)来
避免这个错误。
让我们看看下面的原代码,如果第一次浏览该页或者用户置表单为空,则默认值
为“Go!”;如果用户输入了信息并提交了表单,这段代码将被重新调用且进行
初始化。
<? If (!isset($string)||$string==””){$string=”Go!”;}?>
<form action=button.phtml>
Button text;
<input type=text name=string value=”<? pint $string; ?>”>
<input type=submit>
</form>
这个文件的其余的部分就是简单的在表格中输出一些元素和调用其他的文件。
现在,我们开始制作按钮。第一个例子是生成一个黑边儿绿底儿的椭圆文字按钮
。我们通过一个标准的<IMG>标签儿来显示按钮图象;SRC的值是生成按钮图象的
文件。
<img src=”green_ellipse.phtml?string=<? print rawurlencode($string);
?>
下面让我们看看生成椭圆的文件“green_ellipse.phtml”
生成椭圆
这里列出了green_ellipse.phtml的原代码,我们以Header()开头,可以向Apach
e服务器发从一个HTTP的头信息,这一步告诉Server使用的什么数据,在这里是G
IF的格式:
<?
Header(“Content-Type: image/gif”);
我们使用内嵌的五号字体来显示这个字符串。下面的两个函数返回这种字体的字
符高度和宽度(象素值)。这是一个定宽字体,所以我们得到字符串的精确的尺
寸。
$font_height=ImageFontHeight(5);
$font_width=ImageFontWidth(5);
$str_width=$font_width*$chars;
$str_height=$font_width,;
图象的尺寸就北定到了略高于40个象素,略宽于字符串的长度:
$img_width=$str_width+40;
$img_height=$str_height+40;
现在我们将生成一幅空的图象,置于内存,并且将其赋值给变量$id:
$id=ImageCreate($img_width,$img_height);
我们需要对图象加以润色,函数ImageColorAllocate()的最后三个参数被调节为
三部分,也就是从HTML的十六进制颜色代码调节为你常用的十进制代码(FF=255
)。
$black=ImageColorAllocate($id,0,0,0);
$green=ImageColorAllocate($id,0,255,0);
$white=ImageColorAllocate($id,255,255,255);
函数ImageColorTransparent()的作用是把图象中变量$white的值设为透明色。通
过初始化滤掉该颜色,使得我们将背景置为透明。
$trans=ImageColorTransparent($id,$white);
ImageFill($id,0,0,$white);
现在我们将以$img_center_x和$img_center_y为中心画一个弧,该弧应比字符串
略宽于28个象素,同时比字体略高28个象素。它将从0度角开始顺时针方向画过3
60度,作出一个闭合的椭圆。这将作为边缘,所以我们用变量$black定义的颜色
来填充它。
$img_center-x=$img_width/2;
$img_center_y=$img_height/2; ImageArc(
$id,$img_center_x,$img_center_y,$str_width+28,$str_height+28,0,360,$bl
ack);
我们必须再画一个比这两个尺寸小4个象素的椭圆,并用变量$green定义的颜色填
充这个按钮的主要区域。
ImageArc($id,$img_center_x,$img_center_y,$str_width+24,$st
r_height+24,0,360,$green);
ImageFill($id,$img_center_x,$img_center_y,$green);
接下来,我们将使用内嵌的五号字在按钮上写上文字,当然要把字的中心与椭圆
的中心重合了。最后给按钮上的文字设置变量$black的颜色:
ImageString($id
, 5
,($img_center_x-($str_width/2+1), img_center_y-(
$str_height/2))
, $string
, $black
);
最后,把图象从内存中道出到标准输出缓冲——这是Server将得到的图象的内容
:
ImageGIF($id);
?>
怎么样?很酷吧!!
但这只适合像”Go!”这样短的按钮,像”Submit Secure Order”这样的长字符
串就会不好看。没关系,看看下面这个圆边矩形。
更美观的图样
这个例子将生成一个黑边儿,黄色棱角的图样。你可以看到这种方法比第一个例
子更适合长字符串的按钮。
如果你看了前面的代码,这里的代码你就容易看懂了。我将从生成按钮的形状开
始。
在每一个字符串的结尾处建立20个象素的边缘,并在字符串的上下各建10个象素
的边缘:
$img_width=$str_width+40;
$img_height=$str_height+20;
$id=ImageCreate($img_width,$img_height);
$black=ImageColorAllocate($id,0,0,0);
$yellow=ImageColorAllocate($id,255,255,0);
$white=ImageColorAllocate($id,255,255,255);
$trans=ImageColorTransparent($id,$white);
ImageFill($id,0,0$white);
$img_center_x=$img_width/2;
$img_center_y=$img_height/2;
让我们先画一个“左括号”,我们将生成一个圆弧,圆心在字符串开始的地方(
x赋值为20,y赋值为图象的中心。我随意的断定宽度比字符串的高度宽20个象素
,并从90度画到270度(0度开始于3点的地方)
所有这些在图象的左端画了一个半圆,再从六点通过九点画到12点:
ImageArc($id,20,$img_center_y,20,$str_height+20,90,270,$black);
对于右端,是同上面一样的,只是从右端20象素开始画起,并且掠过相反的半圈
儿——从12点通过3点到六点:
ImageArc($id,($img_width-20),$img_center_y,20,$
img_height+20,270,90,$black);
最后,从一端的端顶向另一端画一条直线,同样在底部也画一条直线。这样闭合
了形状的内部。
ImageLine($id,20,0,($img_width-20),0,$black);
ImageLine($id,20,$img_height-1,($img_width-20),$img_hei
ght-1,$black);
在这个区域里填充变量$yellow所定义的颜色,并充满整个区域:
ImageFillToBorder($id,$img_center_x,$img_center_y,$black,$yellow);
再将字符串写入到图象中,之后向标准输出打印图象:
ImageString($id
, 5
, ($img_center_x-($str_width/2)+1,($img_center_y-($str_height/2))
, $string
, $black
);
ImageGIF($id);
?>
好了,现在你知道怎样画了,下面让我们看看怎样用PHP修改一幅已经存在的图象
。
修改一幅已经存在的图象
我们将修改一幅已经存在的图象,将其存为一幅新的图象文件,同时显示一幅动
态的图象。
(再一次声明,有些浏览器是有保护作用的,所以你看不到源代码)这里我将给
出原程序。
首先,我们把mymonkdy.gif调入内存,并将其赋值给$id。
<?
$id=ImageCreateFromGif(“mymonkey.gif”);
现在我们设置字体颜色,并将它放到图象上。
$yellow=ImageColorAllocate($id,,255,255,0);
以左上角为(0,0)点,从(10,20)地方开始用内嵌四号字体写上字符串,同
时我将它设为大写,并加了感叹号,以使其显得更加生动。
ImageString($id,4,10,20,strtoupper($string.”!”),$yellow);
现在我们将图象从内存存入文件newmonkey.gif。
ImageGIF($id,”newmonkey.gif”);
?>
这样就差不多了:newmonkey.gif可以用来显示了,浏览器的设置是这样的:
<td>
<img src=”newmonkey.gif” border=0>
</td>
</tr>
</table>
这样就好了
-------------------------------------------
图形处理函数库 画饼形图2D 3D
GetImageSize: 取得图片的长宽
用法解释:array getimagesize(string filename, array [imageinfo]);
可 用来取得 WWW 上 GIF、JPEG 及 PNG 三种图片的高与宽,不需要安装 GD library 就可以使用本函式。传回的阵列有四个元素。传回阵列的第一个元素 (索引值 0) 是图片的高度,单位是像素 (pixel)。第二个元素 (索引值 1) 是图片的宽度。第三个元素 (索引值 2) 是图片的档案格式,其值 1 为 GIF 格式、 2 为 JPEG/JPG 格式、3 为 PNG 格式。第四个元素 (索引值 3) 为图片的高与宽字串,height=xxx width=yyy。可省略的参数 imageinfo 用来取得一些图片的相关讯息,例如 IPTC (http://www.xe.net/iptc) 的 APP13 标记,就可以加在图片中,可利用 iptcparse() 来解析。
ImageArc: 画弧线。
用法解释:int imagearc(int im, int cx, int cy, int w, int h, int s, int e, int col);
本函式用来画弧线。原点坐标 (0,0) 为图片的左上角,参数 cx、cy 为椭圆心坐标,参数 w 为水平轴长,参数 h 为垂直轴长,参数 s 及 e 分别为起始角与结束角,参数 col 为弧线的颜色。参数 im 表示图形的 handle。
ImageChar: 写出横向字符。
用法解释:int imagechar(int im, int font, int x, int y, string c, int col);
本函式用来书写横向的字元。原点坐标 (0,0) 为图片的左上角,参数 font 表示字体的大小,从最小的 1 起,参数 x、y 是写入字元的坐标值,参数 c 为欲写出的字元,参数 col 为字的颜色。参数 im 表示图形的 handle。
ImageCharUp: 写出竖式字符。
用法解释:: int imagecharup(int im, int font, int x, int y, string c, int col);
本函式用来书写直式的字元。原点坐标 (0,0) 为图片的左上角,参数 font 表示字体的大小,从最小的 1 起,参数 x、y 是写入字元的坐标值,参数 c 为欲写出的字元,参数 col 为字的颜色。参数 im 表示图形的 handle。
ImageColorAllocate: 匹配颜色。
用法解释:int imagecolorallocate(int im, int red, int green, int blue);
本函式用来匹配图形的颜色,供其它绘图函式使用。参数 im 表示图形的 handle。参数 red、green、blue 是色彩三原色,其值从 0 至 255。
ImageColorTransparent: 指定透明背景色。
用法解释:int imagecolortransparent(int im, int [col]);
本函式用来指定某色为透明背景。参数 im 为使用 imagecreate() 打开图形的 handle。参数 col 为 ImageColorAllocate() 所匹配的颜色。传回值为新的透明背景色。
ImageCopyResized: 复制新图并调整大小。
用 法解释:int imagecopyresized(int dst_im, int src_im, int dstX, int dstY, int srcX, int srcY, int dstW, int dstH, int srcW, int srcH);
本函式可复制 新图,并重新调整图片的大小尺寸。参数都是目的在前,来源在后。参数 dst_im 及 src_im 为图片的 handle。参数 dstX、dstY、srcX、srcY 分别为目的及来源的坐标。参数 dstW、dstH、srcW、srcH 分别为来源及目的的宽及高,若欲调整新图的尺寸就在这儿设定
ImageCreate: 建立新图。
用法解释:: int imagecreate(int x_size, int y_size);
本函式用来建立一张全空的图形。参数 x_size、y_size 为图形的尺寸,单位为像素 (pixel)。
ImageDashedLine: 绘虚线。
用法解释:int imagedashedline(int im, int x1, int y1, int x2, int y2, int col);
本函式将在图形上画出一条虚线。从 x1、y1 连接到 x2、y2,原点 (0,0) 为图形的左上角。参数 col 为虚线的颜色。
ImageDestroy: 结束图形。
用法解释:: int imagedestroy(int im);
本函式将图片 handle 解散,释放内存空间。参数 im 为 ImageCreate() 所建立的图片 handle。
ImageFill: 图形着色。
用法解释:: int imagefill(int im, int x, int y, int col);
本函式将图片坐标 (x,y) 所在的区域着色。参数 col 表示欲涂上的颜色。
ImageFilledPolygon: 多边形区域着色。
用法解释:int imagefilledpolygon(int im, array points, int num_points, int col);
本 函式将图片的封闭多边形区域着色。参数 points 为阵列,代表多边形区域,阵列的偶数元素为 X 坐标,奇数元素为 Y 坐标,例如 points[0] = x0、points[1] = y0、points[2] = x1、points[3] = y1。参数 num_points 为多边形的转折点数目。参数 col 表示欲涂上的颜色。
ImageFilledRectangle: 矩形区域着色。
用法解释:int imagefilledrectangle(int im, int x1, int y1, int x2, int y2, int col);
本函式将图片的封闭长方形区域着色。参数 x1、y1 及 x2、y2 分别为矩形对角线的坐标。参数 col 表示欲涂上的颜色。
ImageFillToBorder: 指定颜色区域内着色。
用法解释:int imagefilltoborder(int im, int x, int y, int border, int col);
本函式将图片中指定的颜色做为边界,着色在其中的封闭区域之中。参数 x、y 为着色区内的坐标,原点 (0,0) 为图形的左上角。参数 border 为颜色值,表填入颜色的边界范围。参数 col 表示欲涂上的颜色。
ImageFontHeight: 取得字型的高度。
用法解释:int imagefontheight(int font);
本函式用来取得指定字型的高度,单位为像素 (pixel)。
ImageFontWidth: 取得字型的宽度。
用法解释:int imagefontwidth(int font);
本函式用来取得指定字型的宽度,单位为像素 (pixel)。
ImageInterlace: 使用交错式显示与否。
用法解释:int imageinterlace(int im, int [interlace]);
本函式用来决定图片是否使用交错式显示 (interlace)。欲使用交错式显示,则将参数 interlace 值设为 1。不想使用交错式显示图形则将之设为 0。传回值 1 表示已设定成交错式、0 表示已设成非交错式。
ImageLine: 绘实线。
用法解释: int imageline(int im, int x1, int y1, int x2, int y2, int col);
本函式将在图形上画出一条实线。从 x1、y1 连接到 x2、y2,原点 (0,0) 为图形的左上角。参数 col 为实线的颜色。
ImageLoadFont: 载入点阵字型。
用法解释:int imageloadfont(string file);
本函式用来载入使用者自订的点阵字型。传回值为字型的代号,此值为大于 5 的整数。
字型档格式的详细信息如下表
byte偏移 型态 说明
0-3 int 档案中字元的数目
4-7 int 字型的启始 ASCII 字元,例如从 ASCII 32 的空白开始
8-11 int 字元的宽度
12-15 int 字元的高度
16以后 char 字元的位元值,也就是点阵的内容
ImagePolygon: 绘多边形。
用法解释:int imagepolygon(int im, array points, int num_points, int col);
本 函式可在图片上绘出多边形。参数 points 为阵列,代表多边形区域,阵列的偶数元素为 X 坐标,奇数元素为 Y 坐标,例如 points[0] = x0、points[1] = y0、points[2] = x1、points[3] = y1。参数 num_points 为多边形的转折点数目。参数 col 表示多边形线的颜色。
ImageRectangle: 绘矩形。
用法解释:int imagerectangle(int im, int x1, int y1, int x2, int y2, int col);
本函式可在图片上绘出长方形。参数 x1、y1 及 x2、y2 分别为矩形对角线的坐标。参数 col 表示矩形边框的颜色。
ImageSetPixel: 绘点。
用法解释:int imagesetpixel(int im, int x, int y, int col);
本函式可在图片上绘出一点。参数 x、y 为欲绘点的坐标,参数 col 表示该点的颜色。
ImageString: 绘横式字符串。
用法解释:int imagestring(int im, int font, int x, int y, string s, int col);
本函式在图片上绘出水平的横式字串。参数 font 为字形,设为 1 到 5 表示使用内定字形。参数 x、y 为字串起点坐标。字串的内容放在参数 s 上。参数 col 表示字串的颜色。
ImageStringUp: 绘直式字符串。
用法解释:int imagestringup(int im, int font, int x, int y, string s, int col);
本函式在图片上绘出铅直的直式字串。参数 font 为字形,设为 1 到 5 表示使用内定字形。参数 x、y 为字串起点坐标。字串的内容放在参数 s 上。参数 col 表示字串的颜色。
ImageSX: 取得图片的宽度。
用法解释:int imagesx(int im);
参数 im 表示图形的 handle
ImageSY: 取得图片的高度。
用法解释:: int imagesy(int im);
参数 im 表示图形的 handle
ImageTTFBBox: 计算 TTF 文字所占区域。
用法解释:array ImageTTFBBox(int size, int angle, string fontfile, string text);
本 函式用来计算并传回 TTF 文字区域框 (bounding box) 大小。参数 size 为字形的尺寸;angle 为字型的角度;fontfile 为字型档名称,亦可是远端的档案;text 当然就是字串内容了。传回值为阵列,包括了八个元素,头二个分别为左下的 x、y 坐标,第三、四个为右下角的 x、y 坐标,第五、六及七、八二组分别为右上及左上的 x、y 坐标。值得注意的是欲使用本函式,系统要装妥 GD 及 Freetype 二个函数库。
ImageTTFText: 写 TTF 文字到图中。
用法解释:array ImageTTFText(int im, int size, int angle, int x, int y, int col, string fontfile, string text);
本 函式将 TTF (TrueType Fonts) 字型文字写入图片。参数 size 为字形的尺寸;angle 为字型的角度,顺时针计算,0 度为水平,也就是三点钟的方向 (由左到右),90 度则为由下到上的文字;x,y 二参数为文字的坐标值 (原点为左上角);参数 col 为字的颜色;fontfile 为字型档名称,亦可是远端的档案;text 当然就是字串内容了。传回值为阵列,包括了八个元素,头二个分别为左下的 x、y 坐标,第三、四个为右下角的 x、y 坐标,第五、六及七、八二组分别为右上及左上的 x、y 坐标。值得注意的是欲使用本函式,系统要装妥 GD 及 Freetype 二个函数库。
ImageColorAt: 取得图中指定点颜色的索引值。
用法解释:int imagecolorat(int im, int x, int y);
本函式可取得图形中某指定点的颜色索引值 (index)。
ImageColorClosest: 计算色表中与指定颜色最接近者。
用法解释: int imagecolorclosest(int im, int red, int green, int blue);
本函式用来计算调色盘中与指定 RGB 颜色最接近的颜色。参数 red、green、blue 分别为红、绿、蓝三原色,也就是所谓的 RGB 值。
ImageColorExact: 计算色表上指定颜色索引值。
用法解释:int imagecolorexact(int im, int red, int green, int blue);
本函式用来计算调色盘中指定 RGB 颜色的色素索引值。参数 red、green、blue 分别为红、绿、蓝三原色,也就是所谓的 RGB 值。若调色盘中没有指定的颜色,则传回 -1。
ImageColorResolve: 计算色表上指定或最接近颜色的索引值。
用法解释:int imagecolorresolve(int im, int red, int green, int blue);
本函式用来计算调色盘中指定 RGB 颜色的色素索引值。参数 red、green、blue 分别为红、绿、蓝三原色,也就是所谓的 RGB 值。若无指定颜色则取得最接近的颜色。无论如何本函式都会有索引值传回。
ImageColorSet: 设定色表上指定索引的颜色。
用法解释:boolean imagecolorset(int im, int index, int red, int green, int blue);
本函式用来设定调色盘上指定索引的颜色值。参数 index 为索引值。参数 red、green、blue 分别为红、绿、蓝三原色,也就是所谓的 RGB 值。此函式适合将图片上某颜色改掉,即利用索引的颜色更改图片颜色
ImageColorsForIndex: 取得色表上指定索引的颜色。
用法解释:array imagecolorsforindex(int im, int index);
本函式用来取得调色盘上指定索引的颜色值。参数 index 为索引值。阵列传回值分别为红、绿、蓝三原色的值。
ImageColorsTotal: 计算图的颜色数。
用法解释: int imagecolorstotal(int im);
本函式用来计算图片的调色盘有几种不同的颜色。
ImagePSLoadFont: 载入 Postscrīpt 字型。
用法解释: int imagepsloadfont(string filename);
本函式用来载入 Postscrīpt Type1 字型。参数 filename 为 Postscrīpt Type1 字型的名称
ImagePSFreeFont: 卸下 Postscrīpt 字型。
用法解释:void imagepsfreefont(int fontindex);
本函式将已载入 Postscrīpt Type1 字型卸下。参数 fontindex 为载入 Postscrīpt Type1 字型的 handle。
ImagePSEncodeFont: Postscrīpt 字型转成向量字。
用法解释:int imagepsencodefont(string encodingfile);
本 函式将 Postscrīpt Type1 字型转换成向量字。若需要西方语系的特殊文字则要 T1lib 函式库。目前 T1lib 提供 IsoLatin1.enc 和 IsoLatin2.enc 二套字。若常要使用向量字,可以在 php3.ini/php.ini 中设定 ps.default_encoding,PHP 系统会自动载入转换。
ImagePSText: 写 Postscrīpt 文字到图中。
用 法解释:array imagepstext(int image, string text, int font, int size, int foreground, int background, int x, int y, int space, int tightness, float angle, int antialias_steps);
本函式将 Postscrīpt Type1 字型文字写入图片。参数 image 为图形。text 参数为要写入的字串。参数 font 则为指定的字型。参数 size 为字的大小,单位为像素 (pixel)。参数 foreground 及 background 分别为前景及背景色,程式会依这二色来修正文字边缘的锯齿。参数 x,y 为文字的坐标,以左下角开始计算。space 参数为文字间的空隔大小。参数 tightness 为单字间的紧密度。angle 为角度。最后一个参数 antialias_steps 为边缘锯齿状修正的等级,范围为 4 至 16。传回阵列有四个元素,第一、二个分别为左下角的 x,y 值,第三、四个元素为右上角的 x,y 值。
ImagePSBBox: 计算 Postscrīpt 文字所占区域。
用法解释: array imagepsbbox(string text, int font, int size, int space, int width, float angle);
本 函式用来计算并传回 Postscrīpt 文字区域框 (bounding box) 大小。参数 text 为要写入的字串。参数 font 则为指定的字型。参数 size 为字的大小,单位为像素 (pixel)。参数 width 为的宽度。angle 为角度。传回阵列有四个元素,第一、二个分别为左下角的 x,y 值,第三、四个元素为右上角的 x,y 值。
ImageCreateFromPNG: 取出 PNG 图型。
用法解释:int imagecreatefrompng(string filename);
本函式用来取出一张 PNG 格式图形,通当取出当背景或者基本的画布样本使用。参数 filename 可以是本地端的档案,也可以是网路的 URL 位址。传回值为 PNG 的档案代码,可供其它的函式使用。本函式在 PHP 3.0.13 版之后才支援。
ImagePNG: 建立 PNG 图型。
用法解释:int imagepng(int im, string [filename]);
本 函式用来建立一张 PNG 格式图形。参数 im 为使用 ImageCreate() 所建立的图片代码。参数 filename 可省略,若无本参数 filename,则会将图片指接送到浏览器端,记得在送出图片之前要先送出使用 Content-type: image/png 的标头字串 (header) 到浏览器端,以顺利传输图片。本函式在 PHP 3.0.13 版之后才支援。
ImageCreateFromGIF: 取出 GIF 图型。
用法解释:int imagecreatefromgif(string filename);
本 函式用来取出一张 GIF 格式图形,通当取出当背景或者基本的画布样本使用。参数 filename 可以是本地端的档案,也可以是网路的 URL 位址。传回值为 GIF 的档案代码,可供其它的函式使用。本函式产生的 GIF 图,由于有版权的问题,因此在商业上的使用还要多加考量。
ImageGIF: 建立 GIF 图型。
用 法解释:int imagegif(int im, string [filename]); 传回值: 整数 函式种类: 图形处理 内容说明 本函式用来建立一张 GIF 格式图形。参数 im 为使用 ImageCreate() 所建立的图片代码。参数 filename 可省略,若无本参数 filename,则会将图片指接送到浏览器端,记得在送出图片之前要先送出使用 Content-type: image/gif 的标头字串 (header) 到浏览器端,以顺利传输图片。若要使用透明背景的 GIF 图,也就是 GIF89a 的格式,需要先使用 ImageColorTransparent() 设定透明背景。本函式产生的 GIF 图,由于有版权的问题,因此在商业上的使用还要多加考量。
-------------------------------------------
用PHP制作饼图调查表
在调查程序中,我们需要根据统计的数据来 生成各种图表来生动的表示调查的百分比 。在PHP在这方面也是不负众望,它中可以通过加载GD库来实现一开始。饼状图表对于查看一个值占总值的百分比是一个好的方法。现在我们就用PHP来实现 一个饼形图表,给大家讲述PHP在这方面的应用。它的设计思想是:首先以用imagecreate()来生成一个空白图形,然后在空白图形中用 imageare()圆弧函数先画圆弧,再画两条线连接圆心和圆弧端点(PHP图像函数不能画扇形),再用imagefilltoborder函数来填充 扇形。其程序实现如下:
<?php
/*
把角度转换为弧度
*/
function radians ($degrees)
{
return($degrees * (pi()/180.0));
}
/*
** 取得在圆心为(0,0)圆上 x,y点的值
*/
function circle_point($degrees, $diameter)
{
$x = cos(radians($degrees)) * ($diameter/2);
$y = sin(radians($degrees)) * ($diameter/2);
return (array($x, $y));
}
// 填充图表的参数
$ChartDiameter = 200; //图表直径
$ChartFont = 2; //图表字体
$ChartFontHeight = imagefontheight($ChartFont);//图表字体的大小
$ChartData = array( "75","45");//用于生成图表的数据,可通过数据库来取得来确定
//$ChartLabel = array("yes", "no"); //数据对应的名称
//确定图形的大小
$ChartWidth = $ChartDiameter + 20;
$ChartHeight = $ChartDiameter + 20 +
(($ChartFontHeight + 2) * count($ChartData));
//确定统计的总数
for($index = 0; $index < count($ChartData); $index++)
{
$ChartTotal += $ChartData[$index];
}
$ChartCenterX = $ChartDiameter/2 + 10;
$ChartCenterY = $ChartDiameter/2 + 10;
//生成空白图形
$image = imagecreate($ChartWidth, $ChartHeight);
//分配颜色
$colorBody = imagecolorallocate($image, 0xFF, 0xFF, 0xFF);
$colorBorder = imagecolorallocate($image, 0x00, 0x00, 0x00);
$colorText = imagecolorallocate($image, 0x00, 0x00, 0x00);
$colorSlice[] = imagecolorallocate($image, 0xFF, 0x00, 0x00);
$colorSlice[] = imagecolorallocate($image, 0x00, 0xFF, 0x00);
//填充背境
imagefill($image, 0, 0, $colorBody);
/*
** 画每一个扇形
*/
$Degrees = 0;
for($index = 0; $index < count($ChartData); $index++)
{
$StartDegrees = round($Degrees);
$Degrees += (($ChartData[$index]/$ChartTotal)*360);
$EndDegrees = round($Degrees);
$CurrentColor = $colorSlice[$index%(count($colorSlice))];
//画图F
imagearc($image,$ChartCenterX,$ChartCenterY,$ChartDiameter,
$ChartDiameter,$StartDegrees,$EndDegrees, $CurrentColor);
//画直线
list($ArcX, $ArcY) = circle_point($StartDegrees, $ChartDiameter);
imageline($image,$ChartCenterX,$ChartCenterY,floor($ChartCenterX + $ArcX),
floor($ChartCenterY + $ArcY),$CurrentColor);
//画直线
list($ArcX, $ArcY) = circle_point($EndDegrees, $ChartDiameter);
imageline($image,$ChartCenterX,$ChartCenterY,ceil($ChartCenterX + $ArcX),
ceil($ChartCenterY + $ArcY),$CurrentColor);
//填充扇形
$MidPoint = round((($EndDegrees - $StartDegrees)/2) + $StartDegrees);
list($ArcX, $ArcY) = circle_point($MidPoint, $ChartDiameter/2);
imagefilltoborder($image,floor($ChartCenterX + $ArcX),floor($ChartCenterY + $ArcY),
$CurrentColor,$CurrentColor);
}
//画边框
imagearc($image,
$ChartCenterX,
$ChartCenterY,
$ChartDiameter,
$ChartDiameter,
0,
180,
$colorBorder);
imagearc($image,
$ChartCenterX,
$ChartCenterY,
$ChartDiameter,
$ChartDiameter,
180,
360,
$colorBorder);
imagearc($image,
$ChartCenterX,
$ChartCenterY,
$ChartDiameter+7,
$ChartDiameter+7,
0,
180,
$colorBorder);
imagearc($image,
$ChartCenterX,
$ChartCenterY,
$ChartDiameter+7,
$ChartDiameter+7,
180,
360,
$colorBorder);
imagefilltoborder($image,
floor($ChartCenterX + ($ChartDiameter/2) + 2),
$ChartCenterY,
$colorBorder,
$colorBorder);
//画图例
for($index = 0; $index < count($ChartData); $index++)
{
$CurrentColor = $colorSlice[$index%(count($colorSlice))];
$LineY = $ChartDiameter + 20 + ($index*($ChartFontHeight+2));
//draw color box
imagerectangle($image,
10,
$LineY,
10 + $ChartFontHeight,
$LineY+$ChartFontHeight,
$colorBorder);
imagefilltoborder($image,
12,
$LineY + 2,
$colorBorder,
$CurrentColor);
//画标签
imagestring($image,
$ChartFont,
20 + $ChartFontHeight,
$LineY,
"$ChartLabel[$index]: $ChartData[$index]",
$colorText);
}
//到此脚本 已经生了一幅图像的,现在需要的是把它发到浏览器上,重要的一点是要将标头发给浏览器,让它知道是一个GIF文件。不然的话你只能看到一堆奇怪的乱码
header("Content-type: image/gif");
//输出生成的图片
imagegif($image);
?>
保存为chart.php,运行程序其结果如图1.
但这是在服务器端生在GIF图片,我们要在HTML文件中应用就需要如下格式来调用它:
<?php
echo "<img src='chart.php' > "
?>
注:运行环境为apache_1_3_12+php-4.0RC1+win98,windows平台下. 在PHP中图像函数都是在GD库中完成,GD库实际是处理GIF格式的免费软件。要加载GD扩展才能使用php4的GD库可以到 www.phpuser.com下载。解压COPY php_gd.dll文件到PHP的执行目录,然后编辑php.ini配置文件,找到配置文件中;extension=php_gd.dll"这行 去掉";"号,如果没有发现则在配置文件的'Dynamic Extensions' 后增加一行extension=php_gd.dl。最后运行phpinfo()函数,你就可以看到支持信息
3维饼图
一 直想发表点东西。最近刚把php4中的php_gd.dll搞定,就迫不及待的想做点图形程序玩玩。看到有许多php做饼图的例子,看了一下都是2维的, 于是就想做个3维的。经过努力pie3d完成了,好东西与大家分享。不过小弟是php新手,代码可能不够精炼,希望大家指教共同来完善这个程序。记得通知 我(estorm@yeah.net)
+------------------------+
| pie3dfun.php//公用函数 |
+------------------------+
<?
define("ANGLE_STEP",5);//定义画椭圆弧时的角度步长
function chx_getdarkcolor($img,$clr){//求$clr对应的暗色
$rgb=imagecolorsforindex($img,$clr);
return array($rgb["red"]/2,$rgb["green"]/2,$rgb["blue"]/2);
}
function chx_getexy($a,$b,$d){//求角度$d对应的椭圆上的点坐标
$d=deg2rad($d);
return array(round($a*Cos($d)),round($b*Sin($d)));
}
function chx_arc($img,$ox,$oy,$a,$b,$sd,$ed,$clr){//椭圆弧函数
$n=ceil(($ed-$sd)/ANGLE_STEP);
$d=$sd;
list($x0,$y0)=chx_getexy($a,$b,$d);
for($i=0;$i<$n;$i++){
$d=($d+ANGLE_STEP)>$ed?$ed:($d+ANGLE_STEP);
list($x,$y)=chx_getexy($a,$b,$d);
imageline($img,$x0+$ox,$y0+$oy,$x+$ox,$y+$oy,$clr);
$x0=$x;
$y0=$y;
}
}
function chx_sector($img,$ox,$oy,$a,$b,$sd,$ed,$clr){//画扇面
$n=ceil(($ed-$sd)/ANGLE_STEP);
$d=$sd;
list($x0,$y0)=chx_getexy($a,$b,$d);
imageline($img,$x0+$ox,$y0+$oy,$ox,$oy,$clr);
for($i=0;$i<$n;$i++){
$d=($d+ANGLE_STEP)>$ed?$ed:($d+ANGLE_STEP);
list($x,$y)=chx_getexy($a,$b,$d);
imageline($img,$x0+$ox,$y0+$oy,$x+$ox,$y+$oy,$clr);
$x0=$x;
$y0=$y;
}
imageline($img,$x0+$ox,$y0+$oy,$ox,$oy,$clr);
list($x,$y)=chx_getexy($a/2,$b/2,($d+$sd)/2);
imagefill($img,$x+$ox,$y+$oy,$clr);
}
function chx_sector3d($img,$ox,$oy,$a,$b,$v,$sd,$ed,$clr){//3d扇面
chx_sector($img,$ox,$oy,$a,$b,$sd,$ed,$clr);
if($sd<180){
list($R,$G,$B)=chx_getdarkcolor($img,$clr);
$clr=imagecolorallocate($img,$R,$G,$B);
if($ed>180) $ed=180;
list($sx,$sy)=chx_getexy($a,$b,$sd);
$sx+=$ox;
$sy+=$oy;
list($ex,$ey)=chx_getexy($a,$b,$ed);
$ex+=$ox;
$ey+=$oy;
imageline($img,$sx,$sy,$sx,$sy+$v,$clr);
imageline($img,$ex,$ey,$ex,$ey+$v,$clr);
chx_arc($img,$ox,$oy+$v,$a,$b,$sd,$ed,$clr);
list($sx,$sy)=chx_getexy($a,$b,($sd+$ed)/2);
$sy+=$oy+$v/2;
$sx+=$ox;
imagefill($img,$sx,$sy,$clr);
}
}
function chx_getindexcolor($img,$clr){//RBG转索引色
$R=($clr>>16) & 0xff;
$G=($clr>>8)& 0xff;
$B=($clr) & 0xff;
return imagecolorallocate($img,$R,$G,$B);
}
?>
+--------------------------+
| pie3d.php //三维饼图文件 |
+--------------------------+
<?
require("pie3dfun.php");
$a=150;//椭圆长半轴
$b=50;//椭圆段半轴
$v=20;//圆饼高度
$font=5;//字体
$ox=5+$a;
$oy=5+$b;
$fw=imagefontwidth($font);
$fh=imagefontheight($font);
$datLst=array(30,10,20,20,10,20,10,20);//数据
$labLst=array("a1","a2","a3","a4","a5","a6","a7","a8");//标签
$clrLst=array(0x99ff00,0xff6666,0x0099ff,0xff99ff,0xffff99,0x99ffff,0xff3333,0x009999);
$w=10+$a*2;
$h=10+$b*2+$v+($fh+2)*count($datLst);
$img=imagecreate($w,$h);
//转RGB为索引色
for($i=0;$i<count($clrLst);$i++) $clrLst[$i]=chx_getindexcolor($img,$clrLst[$i]);
$clrbk=imagecolorallocate($img,0xff,0xff,0xff);
$clrt=imagecolorallocate($img,0x00,0x00,0x00);
//填充背景色
imagefill($img,0,0,$clrbk);
//求和
$tot=0;
for($i=0;$i<count($datLst);$i++) $tot+=$datLst[$i];
$sd=0;
$ed=0;
$ly=10+$b*2+$v;
for($i=0;$i<count($datLst);$i++){
$sd=$ed;
$ed+=$datLst[$i]/$tot*360;
//画圆饼
chx_sector3d($img,$ox,$oy,$a,$b,$v,$sd,$ed,$clrLst[$i]);//$sd,$ed,$clrLst[$i]);
//画标签
imagefilledrectangle($img,5,$ly,5+$fw,$ly+$fh,$clrLst[$i]);
imagerectangle($img,5,$ly,5+$fw,$ly+$fh,$clrt);
imagestring($img,$font,5+2*$fw,$ly,
$labLst[$i].":".$datLst[$i]."(".(round(10000*($datLst[$i]/$tot))/100)."%)",
$clrt);
$ly+=$fh+2;
}
//输出图形
header("Content-type:image/gif");
imagegif($img);
?>