imagefilledarc

(PHP 4 >= 4.0.6, PHP 5, PHP 7, PHP 8)

imagefilledarc绘制部分圆弧并填充

说明

imagefilledarc(
    GdImage $image,
    int $center_x,
    int $center_y,
    int $width,
    int $height,
    int $start_angle,
    int $end_angle,
    int $color,
    int $style
): bool

在给定 image 中,绘制以指定坐标为中心的圆弧的一部分。

参数

image

一个 GdImage 对象,由某个图像创建函数(如 imagecreatetruecolor())返回。

center_x

中心的 x 坐标。

center_y

中心的 y 坐标。

width

圆弧的宽度。

height

圆弧的高度。

start_angle

圆弧的起始角度,以度为单位。

end_angle

圆弧的结束角度,以度为单位。0° 位于三点钟位置,圆弧按顺时针方向绘制。

color

使用 imagecolorallocate() 创建的颜色标识符。

style

以下选项的按位或

  1. IMG_ARC_PIE
  2. IMG_ARC_CHORD
  3. IMG_ARC_NOFILL
  4. IMG_ARC_EDGED
IMG_ARC_PIEIMG_ARC_CHORD 是互斥的;IMG_ARC_CHORD 只是用直线连接起始和结束角度,而 IMG_ARC_PIE 会产生圆角。IMG_ARC_NOFILL 表示应该描边圆弧或弦,而不是填充。IMG_ARC_EDGEDIMG_ARC_NOFILL 一起使用时,表示应该将起始和结束角度连接到中心 - 这是描边(而不是填充)“馅饼切片”的良好方法。

返回值

成功时返回 true,失败时返回 false

变更日志

版本 说明
8.0.0 image 现在需要一个 GdImage 实例;以前,需要一个有效的 gd 资源

范例

示例 #1 创建一个 3D 风格的馅饼

<?php

// 创建图像
$image = imagecreatetruecolor(100, 100);

// 分配一些颜色
$white = imagecolorallocate($image, 0xFF, 0xFF, 0xFF);
$gray = imagecolorallocate($image, 0xC0, 0xC0, 0xC0);
$darkgray = imagecolorallocate($image, 0x90, 0x90, 0x90);
$navy = imagecolorallocate($image, 0x00, 0x00, 0x80);
$darknavy = imagecolorallocate($image, 0x00, 0x00, 0x50);
$red = imagecolorallocate($image, 0xFF, 0x00, 0x00);
$darkred = imagecolorallocate($image, 0x90, 0x00, 0x00);

// 制作 3D 效果
for ($i = 60; $i > 50; $i--) {
imagefilledarc($image, 50, $i, 100, 50, 0, 45, $darknavy, IMG_ARC_PIE);
imagefilledarc($image, 50, $i, 100, 50, 45, 75 , $darkgray, IMG_ARC_PIE);
imagefilledarc($image, 50, $i, 100, 50, 75, 360 , $darkred, IMG_ARC_PIE);
}

imagefilledarc($image, 50, 50, 100, 50, 0, 45, $navy, IMG_ARC_PIE);
imagefilledarc($image, 50, 50, 100, 50, 45, 75 , $gray, IMG_ARC_PIE);
imagefilledarc($image, 50, 50, 100, 50, 75, 360 , $red, IMG_ARC_PIE);


// 输出图像
header('Content-type: image/png');
imagepng($image);
imagedestroy($image);
?>

上面的示例将输出类似于

Output of example : Creating a 3D looking pie

添加注释

用户贡献的注释 16 个注释

Mike
17 年前
前面的示例效果不好。这个更好更快

<?php
$Randomized
= rand(1,20);
for(
$i=0;$i<=$Randomized;$i++){$data[$i]=rand(2,20);};// 随机填充数据数组
$imgx='600';$imgy='400';// 设置图片大小,图像X,图像Y
$cx = '300';$cy ='150'; // 设置圆心位置,中心X,中心Y
$sx = '600';$sy='300';$sz ='100';// 设置圆饼尺寸,尺寸X,尺寸Y,尺寸Z

$data_sum = array_sum($data);
// 转换为角度
for($i=0;$i<=$Randomized;$i++){
$angle[$i] = (($data[$i] / $data_sum) * 360);
$angle_sum[$i] = array_sum($angle);
};
$im = imagecreate ($imgx,$imgy);
$background = imagecolorallocate($im, 255, 255, 255);
// 随机颜色
for($i=0;$i<=$Randomized;$i++){
$r=rand(100,255);$g=rand(100,255);$b=rand(100,255);
$colors[$i] = imagecolorallocate($im,$r,$g,$b);
$colord[$i] = imagecolorallocate($im,($r/1.5),($g/1.5),($b/1.5));
}
// 3D 效果
for($z=1;$z<=$sz;$z++){
// 第一层
imagefilledarc($im,$cx,($cy+$sz)-$z,$sx,$sy,0
,$angle_sum[0],$colord[0],IMG_ARC_EDGED);
for(
$i=1;$i<=$Randomized;$i++){
imagefilledarc($im,$cx,($cy+$sz)-$z,$sx,$sy,$angle_sum[$i-1]
,
$angle_sum[$i],$colord[$i],IMG_ARC_NOFILL);
};
};
// 最上层圆饼
// 第一层
imagefilledarc($im,$cx,$cy,$sx,$sy,0 ,$angle_sum[0], $colors[0], IMG_ARC_PIE);
for(
$i=1;$i<=$Randomized;$i++){
imagefilledarc($im,$cx,$cy,$sx,$sy,$angle_sum[$i-1] ,$angle_sum[$i], $colors[$i], IMG_ARC_PIE);
};
// 输出
header('Content-type: image/png');
imagepng($im);
imagedestroy($im);
?>
splogamurugan at gmail dot com
13 年前
一个简单的饼图生成脚本。
在中心弧线显示百分比,并用随机颜色显示图例。

<?php
class simplepie
{
function
__construct($width, $height, $dataArr)
{
$font = './verdana.ttf'; /** 从 c:/windows/fonts 目录获取 */
$this->image = imagecreate($width,$height);
$piewidth = $width * 0.70;/* 饼图区域 */
$x = round($piewidth/2);
$y = round($height/2);
$total = array_sum($dataArr);
$angle_start = 0;
$ylegend = 2;
imagefilledrectangle($this->image, 0, 0, $width, $piewidth, imagecolorallocate($this->image, 128, 128, 128));
foreach(
$dataArr as $label=>$value) {
$angle_done = ($value/$total) * 360; /** 计算 360 度的角度 */
$perc = round(($value/$total) * 100, 1); /** 计算百分比 */
$color = imagecolorallocate($this->image, rand(0, 255), rand(0, 255), rand(0, 255));
imagefilledarc($this->image, $x, $y, $piewidth, $height, $angle_start, $angle_done+= $angle_start, $color, IMG_ARC_PIE);
$xtext = $x + (cos(deg2rad(($angle_start+$angle_done)/2))*($piewidth/4));
$ytext = $y + (sin(deg2rad(($angle_start+$angle_done)/2))*($height/4));
imagettftext($this->image, 6, 0, $xtext, $ytext, imagecolorallocate($this->image, 0, 0, 0), $font, "$perc %");
imagefilledrectangle($this->image, $piewidth+2, $ylegend, $piewidth+20, $ylegend+=20, $color);
imagettftext($this->image, 8, 0, $piewidth+22, $ylegend, imagecolorallocate($this->image, 0, 0, 0), $font, $label);
$ylegend += 4;
$angle_start = $angle_done;
}
}
function
render()
{
header('Content-type: image/png');
imagepng($this->image);
}
}
/** 使用说明 */
$dataArr = array(2001=>10, 2002=>30, 2003=>50, 2004=>10);
$width=600;
$height=480;
$pie = new simplepie($width, $height, $dataArr);
$pie->render();
?>
vrp76 at mail dot ru
7 年前
该函数的模拟

<?php

function myimagefilledarc($image, $cx, $cy, $width, $height, $start, $end, $color, $style = IMG_ARC_PIE){

$delta = 0.1;
$twoPi = 2*pi();

$w = $width/2;
$h = $height/2;

if(
$h<=$w){
$kx=$w;
$ky=$w*$h/$w;
}else{
$kx=$h*$w/$h;
$ky=$h;
}

$StartRad = deg2rad($start);
$EndRad = deg2rad($end);

$array_points[] = $cx;
$array_points[] = $cy;

$a = $StartRad;

if(
$style==IMG_ARC_PIE
or $style==IMG_ARC_EDGED
or $style==(IMG_ARC_PIE|IMG_ARC_NOFILL)
or
$style==(IMG_ARC_EDGED|IMG_ARC_NOFILL)){

if(
$StartRad>=$EndRad){

$b[] = $twoPi;
$b[] = $EndRad;

}else
$b[] = $EndRad;

}else
$b[] = 0;

foreach(
$b as $vb){
do {
$array_points[] = $cx + $kx*cos($a);
$array_points[] = $cy + $ky*sin($a);
$a += $delta;
} while (
$a<$vb);
$a = 0;
}

$array_points[] = $cx + $kx*cos($EndRad);
$array_points[] = $cy + $ky*sin($EndRad);

$count_array_points = count($array_points);
$num_points = $count_array_points/2;

if(
$style==IMG_ARC_PIE or $style==IMG_ARC_EDGED or $style==IMG_ARC_CHORD){
imagefilledpolygon($image, $array_points, $num_points, $color);
}elseif(
$style==(IMG_ARC_PIE|IMG_ARC_NOFILL)){

$i = 1;
$c = $count_array_points - 1;

$x1 = $array_points[++$i];
$y1 = $array_points[++$i];

do {
$x2 = $array_points[++$i];
$y2 = $array_points[++$i];
imageline($image, $x1, $y1, $x2, $y2, $color);
$x1 = $x2;
$y1 = $y2;
} while (
$i<$c);

}elseif(
$style==(IMG_ARC_CHORD|IMG_ARC_NOFILL) or $style==(IMG_ARC_PIE|IMG_ARC_NOFILL)){
imageline($image, $array_points[2], $array_points[3], $array_points[4], $array_points[5], $color);
}else{
imagepolygon($image, $array_points, $num_points, $color);
}

}

$image = imagecreatetruecolor(900, 1250);

$white = imagecolorallocate($image, 0xFF, 0xFF, 0xFF);
$gray[] = imagecolorallocate($image, 0xC0, 0xC0, 0xC0);
$gray[] = imagecolorallocate($image, 0x90, 0x90, 0x90);
$navy[] = imagecolorallocate($image, 0x00, 0x00, 0x80);
$navy[] = imagecolorallocate($image, 0x00, 0x00, 0x50);
$red[] = imagecolorallocate($image, 0xFF, 0x00, 0x00);
$red[] = imagecolorallocate($image, 0x90, 0x00, 0x00);
$yellow[] = imagecolorallocate($image, 0xFF, 0xFF, 0x00);
$yellow[] = imagecolorallocate($image, 0x90, 0x90, 0x00);

$Cx = 200;
$Cy = 100;

$W = 300;
$H = 100;

$Dx = 500;
$Dy = 0;
$Dy_3d = 40;

$Angles['yellow'] = array(180,0);
$Angles['gray'] = array(0,88);
$Angles['navy'] = array(88,92);
$Angles['red'] = array(92,180);

$styles['IMG_ARC_PIE'] = IMG_ARC_PIE;

$styles['IMG_ARC_CHORD'] = IMG_ARC_CHORD;

$styles['IMG_ARC_PIE|IMG_ARC_NOFILL'] = IMG_ARC_PIE|IMG_ARC_NOFILL;

$styles['IMG_ARC_CHORD|IMG_ARC_NOFILL'] = IMG_ARC_CHORD|IMG_ARC_NOFILL;

$styles['IMG_ARC_PIE|IMG_ARC_EDGED|IMG_ARC_NOFILL'] = IMG_ARC_PIE|IMG_ARC_EDGED|IMG_ARC_NOFILL;

$styles['IMG_ARC_CHORD|IMG_ARC_EDGED|IMG_ARC_NOFILL'] = IMG_ARC_CHORD|IMG_ARC_EDGED|IMG_ARC_NOFILL;

imagestring($image, 5, 130, 15, 'imagefilledarc', $white);

imagestring($image, 5, 130 + $Dx, 15, 'myimagefilledarc', $white);

foreach(
$styles as $name_style => $style){


for (
$i = $Cy+$Dy_3d; $i > $Cy; $i--) {
foreach(
$Angles as $colors=>$angle){
imagefilledarc($image, $Cx, $i+$Dy, $W, $H, $angle[0], $angle[1],$$colors[1], $style);
}
}

foreach(
$Angles as $colors=>$angle){
imagefilledarc($image, $Cx, $Cy+$Dy, $W, $H, $angle[0], $angle[1],$$colors[0], $style);
}


for (
$i = $Cy+$Dy_3d; $i > $Cy; $i--) {
foreach(
$Angles as $colors=>$angle){
myimagefilledarc($image, $Cx+$Dx, $i+$Dy, $W, $H, $angle[0], $angle[1],$$colors[1], $style);
}
}

foreach(
$Angles as $colors=>$angle){
myimagefilledarc($image, $Cx+$Dx, $Cy+$Dy, $W, $H, $angle[0], $angle[1],$$colors[0], $style);
}

imagestring($image, 5, 450-strlen($name_style)*8/2, $Cy+$Dy+$H-10, $name_style, $yellow[0]);

$Dy+=200;
}


header('Content-type: image/png');
imagepng($image);
imagedestroy($image);

?>
caist - www.caist.com
20 年前
如果你想将文本放置在圆的边缘,你需要
获取圆上的一个点

$pos_x=$radius*sin(deg2rad($angle));
$pos_y=sqrt($radius*$radius-$pos_x*$pos_x);

如果你想让这个点位于一个扇形的中间
你需要一个起始角度和一个结束角度

$pos_x=$radius*sin(deg2rad($angle_end-($angle_start)/2));
$pos_y=sqrt($radius*$radius-$pos_x*$pos_x);

希望有帮助
xcoda3 at web dot de
9 年前
对于所有将 imageellipse() 用于边框(imagesetthickness() 不正确工作)的用户。
此函数模拟标准 gd 边框。

<?php

function imageEllipseWithBorder($image, $centerX, $centerY, $width, $height, $color, $borderWidth)
{
// 计算边框的内外强度
$borderOuterStrength = (($borderWidth - 1) / 2);
$borderInnerStrength = ((($borderWidth - 1) / 2) + 1);

// 计算从 0/0 位置到椭圆中心的 x/y 偏移量
$ellipseXOffset = $centerX - ($width / 2) - $borderOuterStrength;
$ellipseYOffset = $centerY - ($height / 2) - $borderOuterStrength;

// 创建用于编辑的临时图像
$tempImageWidth = $width + ($borderOuterStrength * 2) + 1;
$tempImageHeight = $height + ($borderInnerStrength * 2) + 1;
$tempImage = imagecreatetruecolor($tempImageWidth, $tempImageHeight);
imagealphablending($tempImage, false);

// 用“透明”颜色填充临时图像
$transparent = imagecolorallocatealpha($tempImage, 255, 255, 255, 127);
imagefill($tempImage, 0, 0, $transparent);

// 绘制外部椭圆(代表边框)
imagefilledellipse(
$tempImage,
$centerX - $ellipseXOffset,
$centerY - $ellipseYOffset,
$width + $borderOuterStrength * 2,
$height + $borderOuterStrength * 2,
$color
);

// 绘制内部椭圆(透明区域)
imagefilledellipse(
$tempImage,
$centerX - $ellipseXOffset,
$centerY - $ellipseYOffset,
$width - $borderInnerStrength * 2,
$height - $borderInnerStrength * 2,
$transparent
);

// 将椭圆(带有透明内部区域)“粘贴”到原始位置的图像中
imagealphablending($image, true);
imagecopy(
$image,
$tempImage,
$ellipseXOffset + ($borderWidth + 1) % 2,
$ellipseYOffset + ($borderWidth + 1) % 2,
0,
0,
$tempImageWidth,
$tempImageHeight
);
}

?>
floripondia dot 88 at hotmail dot com
10 年前
如果您想制作一个带有爆炸切片的饼图,并在每个切片上显示数据,并在数据右侧也显示数据,您可以使用此代码片段。
<?php
$values
= array("2010" => 1950, "2011" => 750, "2012" => 2100, "2013" => 580, "2014" => 5000);
$total = count($values);
$data = ($total == 0) ? array(360) : array_values($values);
$keys = ($total == 0) ? array("") : array_keys($values);
$radius = 30;
$imgx = 1800 + $radius;
$imgy = 600 + $radius;
$cx = 400 + $radius;
$cy = 200 + $radius;
$sx = 800;
$sy = 400;
$sz = 150;
$data_sum = array_sum($data);
$angle_sum = array(-1 => 0, 360);
$typo = "./helvetica.ttf";
$im = imagecreate($imgx, $imgy);
imagecolorallocate($im, 255, 255, 255);
$color = array(
array(
220, 20, 60),
array(
77, 33, 114),
array(
249, 141, 53),
array(
158, 37, 59),
array(
1, 128, 128),
array(
28, 94, 160),
//array(206, 16, 118),
array(43, 67, 86),
//array(155, 108, 166),
array(83, 69, 62)
);
shuffle($color);
shuffle($color);
shuffle($color);
$colors = array(imagecolorallocate($im, $color[0][0], $color[0][1], $color[0][2]));
$colord = array(imagecolorallocate($im, ($color[0][0] / 1.5), ($color[0][1] / 1.5), ($color[0][2] / 1.5)));
$factorx = array();
$factory = array();
for(
$i = 0; $i < $total; $i++){
$angle[$i] = (($data[$i] / $data_sum) * 360);
$angle_sum[$i] = array_sum($angle);
$colors[$i] = imagecolorallocate($im, $color[$i][0], $color[$i][1], $color[$i][2]);
$colord[$i] = imagecolorallocate($im, ($color[$i][0] / 1.5), ($color[$i][1] / 1.5), ($color[$i][2] / 1.5));
$factorx[$i] = cos(deg2rad(($angle_sum[$i - 1] + $angle_sum[$i]) / 2));
$factory[$i] = sin(deg2rad(($angle_sum[$i - 1] + $angle_sum[$i]) / 2));
}
for(
$z = 1; $z <= $sz; $z++){
for(
$i = 0; $i < $total; $i++){
imagefilledarc($im, $cx + ($factorx[$i] * $radius), (($cy + $sz) - $z) + ($factory[$i] * $radius), $sx, $sy, $angle_sum[$i - 1], $angle_sum[$i], $colord[$i], IMG_ARC_PIE);
}
}
for(
$i = 0; $i < $total; $i++){
imagefilledarc($im, $cx + ($factorx[$i] * $radius), $cy + ($factory[$i] * $radius), $sx, $sy, $angle_sum[$i - 1], $angle_sum[$i], $colors[$i], IMG_ARC_PIE);
imagefilledrectangle($im, 900, 50 + ($i * 50 * 2), 950, 100 + ($i * 50 * 2), $colors[$i]);
imagettftext($im, 50, 0, 970, 100 + ($i * 50 * 2), imagecolorallocate($im, 0, 0, 0), $typo, $keys[$i]);
imagettftext($im, 40, 0, $cx + ($factorx[$i] * ($sx / 4)) - 40, $cy + ($factory[$i] * ($sy / 4)) + 10, imagecolorallocate($im, 0, 0, 0), $typo, $data[$i]);
}
header('Content-type: image/png');
imagepng($im);
imagedestroy($im);
?>
Christopher Kramer
14 年前
如果由于您使用的是旧的 gdlib 版本而无法使用此函数,这里有一个解决方法,如果您想绘制饼图。

<?php

// 图片的宽度和高度
$width=200;
$height=200;

$simulate_old_gd=true; // 不使用 imagefilledarc 即使它可用?

// 饼图的块(以度数表示)
$pieces=array(180,90,45,25,15,5);

$diagram=imagecreate($width,$height);

// 背景颜色
$white=imagecolorallocate($diagram, 255, 255, 255);
imagefilledrectangle($diagram,0,0,$width,$height,$white);

// 圆圈比图片小 2 像素
$width-=2;
$height-=2;

// 我们需要边框颜色
$black=imagecolorallocate($diagram, 0, 0, 0);

// 绘制饼图的边框
imagearc($diagram, round($width/2), round($height/2),
$width, $height, 0, 360, $black);

// 放置下一块的位置(以度数表示)
$position=270;
// 我们将使用计算出的灰色用于简单示例
$gray=0;

foreach(
$pieces as $deg)
{
// 计算灰色
$gray+=30;
if(
$gray>255) $gray=0;
$color=imagecolorallocate($diagram,$gray,$gray,$gray);

// 位置必须保持 < 360
if($position>360) $position-=360;

if(!
$simulate_old_gd && is_callable('imagefilledarc'))
{
imagefilledarc($diagram, round($width/2),
round($height/2), $width, $height, $position,
$position+$deg, $color,IMG_ARC_EDGED);
}
else
{
// 我们使用一些数学来计算圆上的像素
$pix_x=round(floor(($width-2)/2)*cos($position/180*M_PI)
+
round($width/2));
$pix_y=round(floor(($height-2)/2)*sin($position/180*M_PI)
+
round($height/2));
// 现在我们从圆的中心到圆上计算出的像素点画一条线
//
imageline($diagram, round($width/2), round($height/2),
$pix_x, $pix_y, $black);
// 现在我们需要一个像素用于泛洪填充。
//- 我们可以使用数学来计算一块内部的像素点:
//$fill_x=round(floor(($width-10)/2)*
// cos(($position+2)/180*M_PI)+round($width/2));
//$fill_y=round(floor(($height-10)/2)*
// sin(($position+2)/180*M_PI)+round($height/2));
//- 或者我们可以使用一个通用像素,使用较少的数学运算 ;)
// (顶部中间):
$fill_x=floor($width/2)-2;
$fill_y=3;
// 现在我们对圆形进行泛洪填充
@imagefilltoborder ($diagram,$fill_x,$fill_y,$black,$color);
/* (这里填充的范围超过我们需要并不重要
因为下一块会修复它)
如果你只需要一块
(模拟 imagefilledarc)你必须绘制
两个边框线,然后进行泛洪填充 */
}
// 下一块的位置比 $deg 度更远
$position+=$deg;
}

// 输出图片
header('Content-type: image/png');
imagepng($diagram);
imagedestroy($digram);
?>
mateusz dot charytoniuk at gmail dot com
15 年前
下面的代码使用来自 "hans at lintoo dot dk" 的注释中的颜色。它提供了带有标签的饼图

<?php
$bright_list
= array(
array(
255, 203, 3),
array(
220, 101, 29),
array(
189, 24, 51),
array(
214, 0, 127),
array(
98, 1, 96),
array(
0, 62, 136),
array(
0, 102, 179),
array(
0, 145, 195),
array(
0, 115, 106),
array(
178, 210, 52),
array(
137, 91, 74),
array(
82, 56, 47)
);
$dark_list = array(
array(
205, 153, 0),
array(
170, 51, 0),
array(
139, 0, 1),
array(
164, 0, 77),
array(
48, 0, 46),
array(
0, 12, 86),
array(
0, 52, 129),
array(
0, 95, 145),
array(
0, 65, 56),
array(
128, 160, 2),
array(
87, 41, 24),
array(
32, 6, 0)
);

$data = array();
$angle = array();
$title = array();
$i = 0;
foreach(
$_GET as $key => $value ) {
$data[$i] = intval($value);
$title[$i++] = str_replace("_"," ",strval($key));
}
$sum = array_sum($data);
if(
$sum == 0 ) {
++
$sum;
}
$count = count($data);
for(
$i = 0; $i < $count; ++ $i ) {
$angle[$i] = floor($data[$i]/$sum*360);
if(
$angle[$i] == 0 ) {
++
$angle[$i];
}
}
$sum_angle = array_sum($angle);
if(
$sum_angle < 360 ) {
$angle[0]+=360-$sum_angle;
}

$height = $count*34;
if(
$height < 180 ) {
$height = 180;
}

$im = imagecreate (350, $height);
$background = imagecolorallocate($im, 226, 226, 226);
$border = imagecolorallocate($im,97,97,97);
$font_color = imagecolorallocate($im,0,0,0);
$font = 'yourfont.ttf';

$bright = array();
foreach(
$bright_list as $c ) {
$bright[] = imagecolorallocate($im,$c[0],$c[1],$c[2]);
}

$dark = array();
foreach(
$dark_list as $c ) {
$dark[] = imagecolorallocate($im,$c[0],$c[1],$c[2]);
}
$tmp = 0;
for(
$i =0; $i < $count; ++ $i ) {
for(
$j = 100; $j > 90; -- $j ) {
imagefilledarc($im, 100, $j, 180, 120, $tmp, $tmp+$angle[$i], $dark[$i], IMG_ARC_PIE);
}
$tmp += $angle[$i];
}

$tmp = 0;
for(
$i =0; $i < $count; ++ $i ) {
imagefilledarc($im, 100, 90, 180, 120, $tmp, $tmp+$angle[$i], $bright[$i], IMG_ARC_PIE);
$tmp += $angle[$i];
}
for(
$i = 0; $i < $count; ++ $i ) {
imagefilledrectangle($im, 209, 19+($i*30), 231, 41+($i*30), $border);
imagefilledrectangle($im, 210, 20+($i*30), 230, 40+($i*30), $bright[$i]);
imagefttext($im, 11, 0, 240, 34+($i*30), $font_color, $font, $title[$i]);
}
header('Content-type: image/png');
imagepng($im);
imagedestroy($im);
?>

尝试 'pie.php?foo=3&bar=4&baz=6'
imazir at gmail dot com
18 年前
前面的例子不起作用。尝试这些修改,你将得到预期的结果

<?
$Randomized = rand(1,20);
for($i=0;$i<=$Randomized;$i++){$data[$i]=rand(2,20);};// 用垃圾填充整个数组。
$imgx='200';$imgy='200';// 设置图片大小。ImageX,ImageY
$cx = '100';$cy ='50'; // 设置饼图位置。CenterX,CenterY
$sx = '200';$sy='100';$sz ='20';// 设置尺寸维度。SizeX,SizeY,SizeZ

$data_sum = array_sum($data);
// 转换为角度。
for($i=0;$i<=$Randomized;$i++){
$angle[$i] = (($data[$i] / $data_sum) * 360);
$angle_sum[$i] = array_sum($angle);
};
$im = imagecreate ($imgx,$imgy);
$background = imagecolorallocate($im, 255, 255, 255);
// 随机颜色。
for($i=0;$i<=$Randomized;$i++){
$r=rand(100,255);$g=rand(100,255);$b=rand(100,255);
$colors[$i] = imagecolorallocate($im,$r,$g,$b);
$colord[$i] = imagecolorallocate($im,($r/2),($g/2),($b/2));
}
// 3D 效果。
for($z=1;$z<=$sz;$z++){
for($i=1;$i<=$Randomized;$i++){
imagefilledarc($im,$cx,($cy+$sz)-$z,$sx,$sy,$angle_sum[$i-1]
,$angle_sum[$i],$colord[$i],IMG_ARC_PIE);
};
};
// 顶部饼图。
for($i=1;$i<=$Randomized;$i++){
imagefilledarc($im,$cx,$cy,$sx,$sy,$angle_sum[$i-1] ,$angle_sum[$i], $colors[$i], IMG_ARC_PIE);
};
// 输出。
header('Content-type: image/png');
imagepng($im);
imagedestroy($im);
?>
paulcharltonthomson at hotmail dot com
19 年前
这里有一个稍微更好的方法来获取饼图阴影墙的颜色,如 double-zonk at wp dot pl 所发布的。

<?php

$rgb0
= array (255, 153, 204);
$rgb1 = array (255, 153, 0);
$rgb2 = array (153, 204, 0);
$rgb3 = array (51, 153, 102);
$rgb4 = array (51, 204, 204);
$rgb5 = array (51, 102, 255);
$rgb6 = array (128, 0, 128);
$rgb7 = array (150, 150, 150);

for (
$r = 0; $r < 8; ++$r)
{
if(${
"rgb" . $r}[0] < 50) $shadowr = 0; else $shadowr = ${"rgb" . $r}[0] - 50;
if(${
"rgb" . $r}[1] < 50) $shadowg = 0; else $shadowg = ${"rgb" . $r}[1] - 50;
if(${
"rgb" . $r}[2] < 50) $shadowb = 0; else $shadowb = ${"rgb" . $r}[2] - 50;
${
"wall" . $r} = array ($shadowr, $shadowg, $shadowb);
}

for (
$s = 0; $s < 8; ++$s)
{
$kolor[$s] = imagecolorallocate($image, ${"rgb" . $s}[0], ${"rgb" . $s}[1], ${"rgb" . $s}[2]);
$cien[$s] = imagecolorallocate($image, ${"wall" . $s}[0], ${"wall" . $s}[1], ${"wall" . $s}[2]);
}

?>
rich at dicksonlife dot com
19 年前
更高效的代码

原始代码片段和以下建议效率低下,因为它们依赖于上层的 PHP 使用循环来垂直填充,而不是利用底层的绘图例程。此外,这是通过重复绘制填充的椭圆部分来完成的,而圆形计算通常很昂贵(PHP 可能会使用表格,我不确定)。原始代码可以重写为

<?php
// 添加底层。
imagefilledarc($image, 50, 60, 100, 50, 0, 45, $darknavy, IMG_ARC_PIE);
imagefilledarc($image, 50, 60, 100, 50, 45, 75 , $darkgray, IMG_ARC_PIE);
imagefilledarc($image, 50, 60, 100, 50, 75, 360 , $darkred, IMG_ARC_PIE);

// 现在做连接的部分。
// 注意:为了提高效率,预先计算余弦和正弦
$c1=50*cos(45/180*M_PI);
$s1=25*sin(45/180*M_PI);
$c2=50*cos(75/180*M_PI);
$s2=25*sin(75/180*M_PI);

$area1=array(100,60,100,50,50+$c1,50+$s1,50+$c1,60+$s1);
$area2=array(50+$c1,50+$s1,50+$c1,60+$s1,50+$c2,60+$s2,50+$c2,50+$s2);
// 注意,部分 3 会绕过拐角。所以我们只对最左边的范围感兴趣。您需要以编程方式执行此操作。此外,您不需要为任何完全位于饼图后部的段创建垂直部分(实际上,也不需要填充弧)
$area3=array(50+$c2,50+$s2,50+$c2,60+$s2,0,60,0,50);

imagefilledpolygon($image, $area1 , 4 , $darknavy);
imagefilledpolygon($image, $area2 , 4 , $darkgray);
imagefilledpolygon($image, $area3 , 4 , $darkred);

imagefilledarc($image, 50, 50, 100, 50, 0, 45, $navy, IMG_ARC_PIE);
imagefilledarc($image, 50, 50, 100, 50, 45, 75 , $gray, IMG_ARC_PIE);
imagefilledarc($image, 50, 50, 100, 50, 75, 360 , $red, IMG_ARC_PIE);
?>

注意,多边形可能效率略低。如果有一个 imagefilledtriangle,这段代码会更简单。考虑到三角形是多么基本,也许可以考虑在未来的版本中添加它?

Rich
hans at lintoo dot dk
20 年前
我在我的脚本中发现了一些错误,因此我发布了修复
错误
<?php
$drakcolor
[2] = imagecolorallocate($im, 139, 0, 1);
// 应该是
$darkcolor[2] = imagecolorallocate($im, 139, 0, 1);
?>

如果你稍微修改一下代码,然后将图片大小调整为 200x125,这样就不会浪费空间了。
修改内容
<?php
$im
= imagecreate (200, 125);
// AND
for ($i = 60; $i > 50; $i--) {
imagefilledarc($im, 100, $i, 200, 100, $anglesum[$f], $anglesum[$n], $darkcolor[$f], IMG_ARC_PIE);
}
// AND
imagefilledarc($im, 100, 50, 200, 100, $anglesum[$n], $anglesum[$i], $randcolor[$n], IMG_ARC_PIE);
?>
你可以在这里查看在线演示:http://webstatistik.lintoo.dk/
hans at lintoo dot dk
20 年前
我修改了代码,以便从其他地方收集的数据创建 3D 饼图......在本例中,它是用于统计页面......

测试时可以使用

享受

<?php
//Making a image 200 x 200
$im = imagecreate (200, 200);

//Setting background color
$background = imagecolorallocate($im, 226, 226, 226);

//Setting colors of elements
$randcolor[0] = imagecolorallocate($im, 255, 203, 3);
$randcolor[1] = imagecolorallocate($im, 220, 101, 29);
$randcolor[2] = imagecolorallocate($im, 189, 24, 51);
$randcolor[3] = imagecolorallocate($im, 214, 0, 127);
$randcolor[4] = imagecolorallocate($im, 98, 1, 96);
$randcolor[5] = imagecolorallocate($im, 0, 62, 136);
$randcolor[6] = imagecolorallocate($im, 0, 102, 179);
$randcolor[7] = imagecolorallocate($im, 0, 145, 195);
$randcolor[8] = imagecolorallocate($im, 0, 115, 106);
$randcolor[9] = imagecolorallocate($im, 178, 210, 52);
$randcolor[10] = imagecolorallocate($im, 137, 91, 74);
$randcolor[11] = imagecolorallocate($im, 82, 56, 47);

//Setting the darker alt color to the main color
$darkcolor[0] = imagecolorallocate($im, 205, 153, 0);
$darkcolor[1] = imagecolorallocate($im, 170, 51, 0);
$drakcolor[2] = imagecolorallocate($im, 139, 0, 1);
$darkcolor[3] = imagecolorallocate($im, 164, 0, 77);
$darkcolor[4] = imagecolorallocate($im, 48, 0, 46);
$darkcolor[5] = imagecolorallocate($im, 0, 12, 86);
$darkcolor[6] = imagecolorallocate($im, 0, 52, 129);
$darkcolor[7] = imagecolorallocate($im, 0, 95, 145);
$darkcolor[8] = imagecolorallocate($im, 0, 65, 56);
$darkcolor[9] = imagecolorallocate($im, 128, 160, 2);
$darkcolor[10] = imagecolorallocate($im, 87, 41, 24);
$darkcolor[11] = imagecolorallocate($im, 32, 6, 0);

//Getting the data from GET
$i = 0;
while (
$i <= 11) {
$data[$i] = $_GET[++$i];
}

//Getting ready
$datasum = array_sum($data);
$anglesum[0] = 0;
$angle[0] = 0;
$i = 0;

//Calc the start and end angle position of the elements
while ($i <= 11) {
++
$i;
$n = $i - 1;
$part[$i] = $data[$n] / $datasum;
$angle[$i] = floor($part[$i] * 360);
$anglesum[$i] = array_sum($angle);
}

/*
//DEBUGGING - only for testing purposes
echo "<pre>";
print_r($part);
print_r($anglesum);
print_r($angle);
*/

// make the 3D effect
$n = 0;$i=0;
while (
$n <= 11) {
++
$n;
$f = $n - 1;
if (
$angle[$n] != 0) {
for (
$i = 110; $i > 100; $i--) {
imagefilledarc($im, 100, $i, 200, 100, $anglesum[$f], $anglesum[$n], $darkcolor[$f], IMG_ARC_PIE);
}
}
}

//make the 2d data that sits above the 3deffect
$i = 0;
while (
$i <= 11) {
++
$i;
$n = $i - 1;
if (
$angle[$i] != 0) {
imagefilledarc($im, 100, 100, 200, 100, $anglesum[$n], $anglesum[$i], $randcolor[$n], IMG_ARC_PIE);
}
}

// flush image
header('Content-type: image/png');
imagepng($im);
imagedestroy($im);
?>
micha _a.t_ psytrance _d.o.t_ info
19 年前
为了获得漂亮的颜色和根据值数量调整的阴影,我尝试

<?php
function _errechne_gradzahlen( $werte ) { /* 计算度数 */
foreach( $werte as $wert ) { $sum += $wert; }
foreach(
$werte as $wert ) { $gradzahlen[] = 360 * ( $wert / $sum ); }
return
$gradzahlen;
}

function
_randomcol ( $im ) {
return
imagecolorallocate( $im, rand(100, 224), rand(100, 224), rand(128, 224) );
}

$values = array( 100, 200, 50, 100, 43, 32 ); /* 要显示的数据(实际值) */
$werte = _errechne_gradzahlen( $values ); /* 度数数组 */
$width = 200;
$height = 200;
$half_width = floor( $width / 2 );
$half_height = floor($height / 2);

$im = ImageCreateTrueColor( $width, $height );

foreach(
$werte as $key => $wert ) {
/* 获取颜色和阴影 */
$color = _randomcol( $im );
$shadow = $color - 20000; // 或更明亮的阴影,取 10000
$colors[] = $color;
$shadows[] = $shadow;
/* 3D 效果 */
for ($i = ($half_height + 10); $i > $half_height; $i--) {
imagefilledarc(
$im,
$half_width, $i,
$width, $half_height,
$offset, ($offset + $wert), // 从,到(度数)
$shadows[$key], IMG_ARC_NOFILL);
}
$offset = $offset + $wert;
}
$offset = 0;

foreach(
$werte as $key => $wert ) { /* 现在绘制顶部 */
imagefilledarc(
$im,
$half_width, $half_width,
$width, $half_height, // 半尺寸
$offset, ($offset + $wert),
$colors[$key], IMG_ARC_PIE);
$offset = $offset + $wert;
}
header( "Content-type: image/png" );
imagepng ( $im );
imagedestroy( $im );
?>

对不起,我的英语很蹩脚,代码也很乱,我之前从自己写的类中剪切并“翻译”了它。
poopie
20 年前
迄今为止,用于绘制 3D 风格饼图的示例非常低效,会导致绘制大量饼图的脚本性能下降,特别是那些对磁盘进行离线处理的脚本,而不是将单个饼图发送到浏览器(无论哪种方式,这种修改都会节省大量的 CPU 周期)。

修改创建 3D 效果的那部分代码,使其只绘制顶部填充饼图下方饼图层的轮廓(使用 IMG_ARC_NOFILL)。

// 制作 3D 效果(针对原始示例修改)
for ($i = 60; $i >= 50; $i--) {
imagefilledarc($image, 50, $i, 100, 50, 0, 45, $darknavy, IMG_ARC_NOFILL);
imagefilledarc($image, 50, $i, 100, 50, 45, 75 , $darkgray, IMG_ARC_NOFILL);
imagefilledarc($image, 50, $i, 100, 50, 75, 360 , $darkred, IMG_ARC_NOFILL);
}

请注意 for 循环中的 >=,它会填充没有 = 时产生的间隙。
t_therkelsen at hotmail dot com
19 年前
请注意,imageFilledArc() 和 imageArc() 都使用整数作为度数测量值。如果 *只* 使用 imageArc() 和/或 imageFilledArc(),这不成问题。但是,如果使用计算的度数并计划叠加其他绘图元素(例如,要在阴影 3D 效果之间绘制垂直线),则需要在将度数转换为弧度之前使用 floor() 函数,否则会出现精度错误。

一个小的示例说明了这个“功能”......

<?php
$img
= imageCreate(400, 400);
$back = imageColorAllocate($img, 0, 0, 0);
$front = imageColorAllocate($img, 255, 255, 255);

$sd = 45.5;
$ed = 130.5;

imageFilledArc($img, 200, 200, 300, 300, $sd, $ed,
$front, IMG_ARC_PIE|IMG_ARC_NOFILL|IMG_ARC_EDGED);
imageArc($img, 200, 230, 300, 300, $sd, $ed, $front);

imageLine($img,
cos(deg2rad($sd))*150+200, sin(deg2rad($sd))*150+200,
cos(deg2rad($sd))*150+200, sin(deg2rad($sd))*150+230,
$front);
imageLine($img,
cos(deg2rad($ed))*150+200, sin(deg2rad($ed))*150+200,
cos(deg2rad($ed))*150+200, sin(deg2rad($ed))*150+230,
$front);

header('Content-type: image/png');
imagepng($img);
imagedestroy($img);
?>

并且,它应该像这样...

<?php
$img
= imageCreate(400, 400);
$back = imageColorAllocate($img, 0, 0, 0);
$front = imageColorAllocate($img, 255, 255, 255);

$sd = floor(45.5);
$ed = floor(130.5);

imageFilledArc($img, 200, 200, 300, 300, $sd, $ed,
$front, IMG_ARC_PIE|IMG_ARC_NOFILL|IMG_ARC_EDGED);
imageArc($img, 200, 230, 300, 300, $sd, $ed, $front);

imageLine($img,
cos(deg2rad($sd))*150+200, sin(deg2rad($sd))*150+200,
cos(deg2rad($sd))*150+200, sin(deg2rad($sd))*150+230,
$front);
imageLine($img,
cos(deg2rad($ed))*150+200, sin(deg2rad($ed))*150+200,
cos(deg2rad($ed))*150+200, sin(deg2rad($ed))*150+230,
$front);

header('Content-type: image/png');
imagepng($img);
imagedestroy($img);
?>
To Top