GD and Image 函数
在线手册:中文  英文

imagefilledpolygon

(PHP 4, PHP 5)

imagefilledpolygon画一多边形并填充

说明

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

imagefilledpolygon()image 图像中画一个填充了的多边形。

points 参数是一个按顺序包含有多边形各顶点的 xy 坐标的数组。

num_points 参数是顶点的总数,必须大于 3。

Example #1 imagefilledpolygon() 例子

<?php
// 建立多边形各顶点坐标的数组
$values = array(
            
40,  50,  // Point 1 (x, y)
            
20,  240// Point 2 (x, y)
            
60,  60,  // Point 3 (x, y)
            
24020,  // Point 4 (x, y)
            
50,  40,  // Point 5 (x, y)
            
10,  10   // Point 6 (x, y)
            
);

// 创建图像
$image imagecreatetruecolor(250250);

// 设定颜色
$bg   imagecolorallocate($image200200200);
$blue imagecolorallocate($image00255);

// 画一个多边形
imagefilledpolygon($image$values6$blue);

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


GD and Image 函数
在线手册:中文  英文

用户评论:

austinoblouk at yahoo dot com (2009-09-05 20:28:18)

Actually the minimum it allows is 3. It says "Total number of vertices, which must be bigger than 3." but it allows 3...

Arnapou (2007-10-29 06:49:00)

I discovered that the GD imagefilledpolygon function is incorrect for some drawing with transparent color (for example red 50% : RGBA = 255, 0, 0, 64).

I tried to draw a complex form with lots of points really near (1 pixel of distance) and a transparent red.

The problem was : some border pixels were not drawn by the imagefilledpolygon but were drawn with imagepolygon !?!?

So I wrote my own imagefilledpolygon function which work very well in all case I tested.

<?php
// $points should be an array of coordinates like that :
$points = array(
    array(
00),
    array(
10050),
    array(
90100),
    array(
5050),
    array(
7030),
    array(
1010),
);
?>

<?php
function myimagefilledpolygon(& $img$points$color) {
    
$scanline 99999;
    
// compute edges
    
$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; }
        }
    }
    
// draw
    
$active = array();
    do {
        
// add edges to active array
        
$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;
        
// remove previous edges from active array
        
$tmp = array();
        
$n count($active);
        for(
$i=0$i<$n$i++) {
            if (
$active[$i][1] > $scanline) {
                
$tmp[] = $active[$i];
            }
        }
        
$active $tmp;
        
// sort active tab
        
$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;
            }
        }
        
// draw
        
$n count($active);
        for(
$i=0$i<$n$i+=2) {
            if (
$i+$n) {
                if (
$tmp[$i][2] == $active[$i+1][2]) {
                    
imagesetpixel($imground($active[$i][2]), $scanline$color);
                } else {
                    
imageline($imground($active[$i][2]), $scanlineround($active[$i+1][2]), $scanline$color);
                }
            }
        }
        
// increment x values
        
$n count($active);
        for(
$i=0$i<$n$i++) { $active[$i][2] += $active[$i][3]; }
        
$scanline++;
    } while (
count($all_edges) + count($active) > 0);
}
?>

webmaster at mywebsolution dot de (2007-10-22 14:24:53)

Just thought that 'tatlar at yahoo dot com's function has some redundant code in it, so I tried to "improve" it. Now you can choose a variable number of spikes.

<?php
error_reporting
(E_ALL);
function 
drawStar($x$y$radius$spikes=5) {
    
// $x, $y -> Position in the image
    // $radius -> Radius of the star
    // $spikes -> Number of spikes

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

    
// Get the coordinates of the outer shape of the star
    
$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)));
    }

    
// Get the coordinates of the inner shape of the star
    
$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)));
    }

    
// Bring the coordinates in the right order
    
foreach($inner_shape as $key => $value){
        if(
$key == (floor($spikes/2)+1))
             break;
        
$inner_shape[] = $value;
        unset(
$inner_shape[$key]);
    }

    
// Reset the keys
    
$i=0;
    foreach(
$inner_shape as $value){
        
$inner_shape[$i] = $value;
        
$i++;
    }

    
// "Merge" outer and inner shape
    
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 the coordinates
    
return $coordinates ;
}

// Example
$spikes 5;

$values drawStar(250250200$spikes);
$im imagecreate(500,500);
imagecolorallocate($im,0,0,0);
$w imagecolorallocate($im255255255);
imagefilledpolygon($im$values$spikes*2$w);
imageGIF($im);
imagedestroy($im);
?>

jylyn at hotmail dot com (2006-10-16 17:11:12)

In spite of what it says about requiring more than 3 vertices, it is possible to draw a triangle with this function!

tatlar at yahoo dot com (2006-09-11 17:08:22)

<?php function _makeFiveSidedStar$x$y$radius$shape='polygon'$spiky=NULL ) {
    
// $x, $y co-ords of origin (in pixels), $radius (in pixels), $shape - 'polygon' or 'star', $spikiness - ratio between 0 and 1
    
$point = array() ;                                                                                                                    
    
$angle 360 ;                                                                                                                    
    
$point[0]['x'] = $x ;                                                                                                                 
    
$point[0]['y'] = $y $radius ;                                                                                                       
    
$point[2]['x'] = $x + ( $radius cosdeg2rad90 $angle ) ) ) ; 
    
$point[2]['y'] = $y - ( $radius sindeg2rad90 $angle ) ) ) ;
    
$point[4]['x'] = $x + ( $radius sindeg2rad180 - ( $angle*) ) ) ) ;
    
$point[4]['y'] = $y + ( $radius cosdeg2rad180 - ( $angle*) ) ) ) ;
    
$point[6]['x'] = $x - ( $radius sindeg2rad180 - ( $angle*) ) ) ) ;                                                            
    
$point[6]['y'] = $y + ( $radius cosdeg2rad180 - ( $angle*) ) ) ) ;
    
$point[8]['x'] = $x - ( $radius cosdeg2rad90 $angle ) ) ) ;                                                                   
    
$point[8]['y'] = $y - ( $radius sindeg2rad90 $angle ) ) ) ;
    if( 
$shape == 'star' ) {
        if( 
$spiky == NULL $spiky 0.5 ;  // default to 0.5
        
$indent $radius $spiky ;
        
$point[1]['x'] = $x + ( $indent cosdeg2rad90 $angle/) ) ) ;                                                             
        
$point[1]['y'] = $y - ( $indent sindeg2rad90 $angle/) ) ) ;                                                     
        
$point[3]['x'] = $x + ( $indent sindeg2rad180 $angle ) ) ) ;                                                              
        
$point[3]['y'] = $y - ( $indent cosdeg2rad180 $angle ) ) ) ;
        
$point[5]['x'] = $x ;                                                                                                             
        
$point[5]['y'] = $y + ( $indent sindeg2rad180 $angle ) ) ) ;
        
$point[7]['x'] = $x - ( $indent sindeg2rad180 $angle ) ) ) ;                                                              
        
$point[7]['y'] = $y - ( $indent cosdeg2rad180 $angle ) ) ) ;                                                              
        
$point[9]['x'] = $x - ( $indent cosdeg2rad90 $angle/) ) ) ;                                                             
        
$point[9]['y'] = $y - ( $indent sindeg2rad90 $angle/) ) ) ;
    }
    
ksort$point ) ;
    
$coords = array() ;  // new 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 _makeFiveSidedStar10010050'star' ) ;
// Put values into imagepolygon function. You need to define the $image and $color, and flush it out to an image type.?>

etnekor at tar dot hu (2006-01-22 13:18:16)

There is a simple function to draw a filled point with a chosen radius and color.

<?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);
}
?>

易百教程