PHP Conference Japan 2024

imagefilledpolygon

(PHP 4, PHP 5, PHP 7, PHP 8)

imagefilledpolygon绘制填充多边形

描述

PHP 8.0.0 版本的签名(不支持命名参数)

imagefilledpolygon(GdImage $image, array $points, int $color): bool

替代签名(自 PHP 8.1.0 起已弃用)

imagefilledpolygon(
    GdImage $image,
    array $points,
    int $num_points,
    int $color
): bool

imagefilledpolygon() 在给定的 image 中创建一个填充多边形。

参数

image

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

points

一个数组,包含多边形顶点的 xy 坐标。

num_points

点的总数(顶点),必须至少为 3。

如果根据第二个签名省略此参数,则 points 必须具有偶数个元素,并且假定 num_pointscount($points)/2
color

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

返回值

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

变更日志

版本 描述
8.1.0 参数 num_points 已被弃用。
8.0.0 image 现在需要一个 GdImage 实例;之前需要一个有效的 gd resource

范例

示例 #1 imagefilledpolygon() 示例

<?php
// 设置多边形的点数组
$values = array(
40, 50, // 点 1 (x, y)
20, 240, // 点 2 (x, y)
60, 60, // 点 3 (x, y)
240, 20, // 点 4 (x, y)
50, 40, // 点 5 (x, y)
10, 10 // 点 6 (x, y)
);

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

// 分配颜色
$bg = imagecolorallocate($image, 0, 0, 0);
$blue = imagecolorallocate($image, 0, 0, 255);

// 填充背景
imagefilledrectangle($image, 0, 0, 249, 249, $bg);

// 绘制多边形
imagefilledpolygon($image, $values, 6, $blue);

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

以上示例将输出类似于以下内容的结果

Output of example : imagefilledpolygon()

参见

添加注释

用户贡献的注释 9 条注释

martin at eksperimentrum dot dk
6 年前
如何绘制一个简单的六角星图像,其中 x,y 是星形的中心,s 是大小

function drawStar($img, $x, $y, $s, $color) {
$x=$x-$s/2;
$y=$y-$s/4;
$points=array($x,$y, $x+$s/2,$y+$s, $x+$s,$y);
imagefilledpolygon($img, $points, 3, $color);
$points=array($x,2/3*$s+$y, $x+$s/2,$y-$s/3, $x+$s,2/3*$s+$y);
imagefilledpolygon($img, $points, 3, $color);
}
Steween
7 年前
我的 drawStar 版本(包含示例)

<?php
header
("Content-type: image/png");

/* 绘制星形或正多边形
$x, $y -> 图像中的位置
$radius -> 星形的半径
$spikes -> 尖角数量 (最小 2)
$ratio -> 外部点和内部点之间的比率
$dir -> 旋转角度,270° 可使尖角向上 (当 ratio<1 时)
*/
function drawStar($x, $y, $radius, $spikes=5, $ratio=0.5, $dir=270) {
$coordinates = array();
$angle = 360 / $spikes ;
for(
$i=0; $i<$spikes; $i++){
$coordinates[] = $x + ( $radius * cos(deg2rad($dir+$angle*$i)));
$coordinates[] = $y + ( $radius * sin(deg2rad($dir+$angle*$i)));
$coordinates[] = $x + ($ratio*$radius * cos(deg2rad($dir+$angle*$i + $angle/2)));
$coordinates[] = $y + ($ratio*$radius * sin(deg2rad($dir+$angle*$i + $angle/2)));
}
return
$coordinates ;
}

// 14*20+24*2 = 328 个例子
$im = imagecreate(800,600);
imagecolorallocate($im, 0, 0, 0);
$w = imagecolorallocate($im, 255, 255, 255);
$r = imagecolorallocate($im, 255, 0, 0);
for (
$spikes=2; $spikes<16; $spikes++) { //[2-15]
for ($ratio=1; $ratio<21; $ratio++) { //[0.1-2.0]
$values = drawStar(40*$ratio-20, $spikes*40-60, 10, $spikes, $ratio/10);
imagefilledpolygon($im, $values, count($values)/2, ($ratio % 5 == 0) ? $r : $w);
}
}
for (
$dir=0; $dir<24; $dir++) {
$values = drawStar(30*$dir+20, 580, 10, 2, 1.5, $dir*15);
imagefilledpolygon($im, $values, count($values)/2, $w);
$values = drawStar(30*$dir+20, 580, 10, 2, 0.2, $dir*15);
imagefilledpolygon($im, $values, count($values)/2, $r);
}
imagepng($im);
imagedestroy($im);
?>
[email protected]
9年前
在处理将地理边界打印到图像时发现:如果提供浮点数顶点,则小数部分会自动截断。这会导致使用浮点数顶点绘制的图像略微向左上角偏移。我个人的解决方案是将所有顶点四舍五入到最接近的整数值,这消除了这种偏移。
[email protected]
15年前
实际上,它允许的最小值是3。它说“顶点的总数必须大于3”,但它允许3……
[email protected]
17年前
只是觉得'[email protected]' 的函数中有一些冗余代码,所以我尝试对其进行“改进”。现在您可以选择可变数量的尖角。

<?php
error_reporting
(E_ALL);
function
drawStar($x, $y, $radius, $spikes=5) {
// $x, $y -> 图片中的位置
// $radius -> 星星的半径
// $spikes -> 角的个数

$coordinates = array();
$angel = 360 / $spikes ;

// 获取星星外轮廓的坐标
$outer_shape = array();
for(
$i=0; $i<$spikes; $i++){
$outer_shape[$i]['x'] = $x + ($radius * cos(deg2rad(270 - $angel*$i)));
$outer_shape[$i]['y'] = $y + ($radius * sin(deg2rad(270 - $angel*$i)));
}

// 获取星星内轮廓的坐标
$inner_shape = array();
for(
$i=0; $i<$spikes; $i++){
$inner_shape[$i]['x'] = $x + (0.5*$radius * cos(deg2rad(270-180 - $angel*$i)));
$inner_shape[$i]['y'] = $y + (0.5*$radius * sin(deg2rad(270-180 - $angel*$i)));
}

// 将坐标按正确的顺序排列
foreach($inner_shape as $key => $value){
if(
$key == (floor($spikes/2)+1))
break;
$inner_shape[] = $value;
unset(
$inner_shape[$key]);
}

// 重置键
$i=0;
foreach(
$inner_shape as $value){
$inner_shape[$i] = $value;
$i++;
}

// 合并内外轮廓坐标
foreach($outer_shape as $key => $value){
$coordinates[] = $outer_shape[$key]['x'];
$coordinates[] = $outer_shape[$key]['y'];
$coordinates[] = $inner_shape[$key]['x'];
$coordinates[] = $inner_shape[$key]['y'];
}

// 返回坐标
return $coordinates ;
}

// 示例
$spikes = 5;

$values = drawStar(250, 250, 200, $spikes);
$im = imagecreate(500,500);
imagecolorallocate($im,0,0,0);
$w = imagecolorallocate($im, 255, 255, 255);
imagefilledpolygon($im, $values, $spikes*2, $w);
imageGIF($im);
imagedestroy($im);
?>
[email protected]
18年前
尽管它说明需要超过3个顶点,但使用此函数可以绘制三角形!
[email protected]
18年前
有一个简单的函数可以绘制一个具有所选半径和颜色的填充点。

<?php
function drawPoint($img, $radius, $origo_x, $origo_y, $pointColor)
{
for (
$i=0;$i<=360;$i++)
{
$pont[] = $origo_x + ($radius * sin(deg2rad($i)));
$pont[] = $origo_y - ($radius * cos(deg2rad($i)));
}
reset($pont);
ImageFilledPolygon ($img, $pont, (sizeof($pont)/2), $pointColor);
}
?>
[email protected]
18年前
<?php function _makeFiveSidedStar( $x, $y, $radius, $shape='polygon', $spiky=NULL ) {
// $x, $y 为原点坐标(像素),$radius 为半径(像素),$shape 为图形类型 - 'polygon' 或 'star',$spikiness 为尖锐度比率,取值范围为 0 到 1
$point = array() ;
$angle = 360 / 5 ;
$point[0]['x'] = $x ;
$point[0]['y'] = $y - $radius ;
$point[2]['x'] = $x + ( $radius * cos( deg2rad( 90 - $angle ) ) ) ;
$point[2]['y'] = $y - ( $radius * sin( deg2rad( 90 - $angle ) ) ) ;
$point[4]['x'] = $x + ( $radius * sin( deg2rad( 180 - ( $angle*2 ) ) ) ) ;
$point[4]['y'] = $y + ( $radius * cos( deg2rad( 180 - ( $angle*2 ) ) ) ) ;
$point[6]['x'] = $x - ( $radius * sin( deg2rad( 180 - ( $angle*2 ) ) ) ) ;
$point[6]['y'] = $y + ( $radius * cos( deg2rad( 180 - ( $angle*2 ) ) ) ) ;
$point[8]['x'] = $x - ( $radius * cos( deg2rad( 90 - $angle ) ) ) ;
$point[8]['y'] = $y - ( $radius * sin( deg2rad( 90 - $angle ) ) ) ;
if(
$shape == 'star' ) {
if(
$spiky == NULL ) $spiky = 0.5 ; // 默认值为 0.5
$indent = $radius * $spiky ;
$point[1]['x'] = $x + ( $indent * cos( deg2rad( 90 - $angle/2 ) ) ) ;
$point[1]['y'] = $y - ( $indent * sin( deg2rad( 90 - $angle/2 ) ) ) ;
$point[3]['x'] = $x + ( $indent * sin( deg2rad( 180 - $angle ) ) ) ;
$point[3]['y'] = $y - ( $indent * cos( deg2rad( 180 - $angle ) ) ) ;
$point[5]['x'] = $x ;
$point[5]['y'] = $y + ( $indent * sin( deg2rad( 180 - $angle ) ) ) ;
$point[7]['x'] = $x - ( $indent * sin( deg2rad( 180 - $angle ) ) ) ;
$point[7]['y'] = $y - ( $indent * cos( deg2rad( 180 - $angle ) ) ) ;
$point[9]['x'] = $x - ( $indent * cos( deg2rad( 90 - $angle/2 ) ) ) ;
$point[9]['y'] = $y - ( $indent * sin( deg2rad( 90 - $angle/2 ) ) ) ;
}
ksort( $point ) ;
$coords = array() ; // 新数组
foreach( $point as $pKey=>$pVal ) {
if(
is_array( $pVal ) ) {
foreach(
$pVal as $pSubKey=>$pSubVal ) {
if( !empty(
$pSubVal ) ) array_push( $coords, $pSubVal ) ;
}
}
}
return
$coords ;
}
$values = _makeFiveSidedStar( 100, 100, 50, 'star' ) ;
// 将值传入 imagepolygon 函数。你需要定义 $image 和 $color,并将结果输出到图像类型。?>
Arnapou
17年前
我发现 GD 的 imagefilledpolygon 函数在某些使用透明颜色的绘图中存在错误(例如 50% 红色:RGBA = 255, 0, 0, 64)。

我尝试绘制一个复杂的图形,其中包含许多非常靠近的点(1 像素距离)和透明红色。

问题是:imagefilledpolygon 函数没有绘制一些边界像素,但是 imagepolygon 函数却绘制了这些像素?!

所以我编写了自己的 imagefilledpolygon 函数,在我的所有测试用例中都运行良好。

<?php
// $points 应该是一个坐标数组,格式如下:
$points = array(
array(
0, 0),
array(
100, 50),
array(
90, 100),
array(
50, 50),
array(
70, 30),
array(
10, 10),
);
?>

<?php
function myimagefilledpolygon(& $img, $points, $color) {
$scanline = 99999;
// 计算边
$all_edges = array();
$n = count($points);
for(
$i=0; $i<$n; $i++) {
$p1 = $points[$i];
if (
$i == $n-1) { $p2 = $points[0]; } else { $p2 = $points[$i+1]; }
$x1 = $p1[0]; $y1 = $p1[1];
$x2 = $p2[0]; $y2 = $p2[1];
if (
$y1 != $y2) {
$invslope = ($x2 - $x1)/($y2 - $y1);
if (
$y1 < $y2 ) {
$ymin = $y1;
$xval = $x1;
$ymax = $y2;
} else {
$ymin = $y2;
$xval = $x2;
$ymax = $y1;
}
$all_edges[] = array($ymin, $ymax, $xval, $invslope);
if (
$ymin < $scanline) { $scanline = $ymin; }
} else {
if (
$y1 < $scanline) { $scanline = $y1; }
if (
$y2 < $scanline) { $scanline = $y2; }
}
}
// 绘制图形
$active = array();
do {
// 将边添加到活动数组
$tmp = array();
$n = count($all_edges);
for(
$i=0; $i<$n; $i++) {
if (
$all_edges[$i][0] == $scanline) {
$active[] = $all_edges[$i];
} else {
$tmp[] = $all_edges[$i];
}
}
$all_edges = $tmp;
// 从活动数组中删除以前的边
$tmp = array();
$n = count($active);
for(
$i=0; $i<$n; $i++) {
if (
$active[$i][1] > $scanline) {
$tmp[] = $active[$i];
}
}
$active = $tmp;
// 对活动标签进行排序
$n = count($active);
for(
$i=0; $i<$n-1; $i++) {
$min = $i;
for(
$k=$i+1; $k<$n; $k++) {
if (
$active[$k][2] < $active[$min][2]) { $min = $k; }
}
if (
$i != $min) {
$tmp = $active[$i];
$active[$i] = $active[$min];
$active[$min] = $tmp;
}
}
// 绘制图形
$n = count($active);
for(
$i=0; $i<$n; $i+=2) {
if (
$i+1 < $n) {
if (
$tmp[$i][2] == $active[$i+1][2]) {
imagesetpixel($img, round($active[$i][2]), $scanline, $color);
} else {
imageline($img, round($active[$i][2]), $scanline, round($active[$i+1][2]), $scanline, $color);
}
}
}
// 增加x值
$n = count($active);
for(
$i=0; $i<$n; $i++) { $active[$i][2] += $active[$i][3]; }
$scanline++;
} while (
count($all_edges) + count($active) > 0);
}
?>
To Top