imagefilledpolygon

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

imagefilledpolygon β€” РисуСт Π·Π°ΠΊΡ€Π°ΡˆΠ΅Π½Π½Ρ‹ΠΉ ΠΌΠ½ΠΎΠ³ΠΎΡƒΠ³ΠΎΠ»ΡŒΠ½ΠΈΠΊ

ОписаниС

Π‘ΠΈΠ³Π½Π°Ρ‚ΡƒΡ€Π°, которая дСйствуСт с PHP 8.0.0 (Π½Π΅ поддСрТиваСтся с ΠΈΠΌΠ΅Π½ΠΎΠ²Π°Π½Π½Ρ‹ΠΌΠΈ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Π°ΠΌΠΈ)

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

ΠΠ»ΡŒΡ‚Π΅Ρ€Π½Π°Ρ‚ΠΈΠ²Π½Π°Ρ сигнатура (устарСла с PHP 8.1.0)

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

Ѐункция imagefilledpolygon() создаёт Π·Π°ΠΊΡ€Π°ΡˆΠ΅Π½Π½Ρ‹ΠΉ ΠΌΠ½ΠΎΠ³ΠΎΡƒΠ³ΠΎΠ»ΡŒΠ½ΠΈΠΊ Π² ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠΈ image.

Бписок ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠ²

image
ΠžΠ±ΡŠΠ΅ΠΊΡ‚ GdImage, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π²Π΅Ρ€Π½ΡƒΠ»Π° функция imagecreatetruecolor() ΠΈΠ»ΠΈ другая функция Π³Π΅Π½Π΅Ρ€Π°Ρ†ΠΈΠΈ ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠΉ.
points

Массив с x- ΠΈ y-ΠΊΠΎΠΎΡ€Π΄ΠΈΠ½Π°Ρ‚Π°ΠΌΠΈ ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹Ρ… Π²Π΅Ρ€ΡˆΠΈΠ½ ΠΌΠ½ΠΎΠ³ΠΎΡƒΠ³ΠΎΠ»ΡŒΠ½ΠΈΠΊΠ°.

num_points

ΠžΠ±Ρ‰Π΅Π΅ количСство Ρ‚ΠΎΡ‡Π΅ΠΊ (Π²Π΅Ρ€ΡˆΠΈΠ½), Π΄ΠΎΠ»ΠΆΠ½ΠΎ Π±Ρ‹Ρ‚ΡŒ Π½Π΅ мСньшС 3.

ΠŸΡ€ΠΈ Π²Ρ‹Π·ΠΎΠ²Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ согласно сигнатурС Π±Π΅Π· этого ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π° массив points Π΄ΠΎΠ»ΠΆΠ΅Π½ ΡΠΎΠ΄Π΅Ρ€ΠΆΠ°Ρ‚ΡŒ Ρ‡Ρ‘Ρ‚Π½ΠΎΠ΅ количСство элСмСнтов, Ρ‚ΠΎΠ³Π΄Π° Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π° num_points функция вычислит ΠΊΠ°ΠΊ count($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, // Point 1 (x, y)
20, 240, // Point 2 (x, y)
60, 60, // Point 3 (x, y)
240, 20, // Point 4 (x, y)
50, 40, // Point 5 (x, y)
10, 10 // Point 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, $blue);

// Π’Ρ‹Π²ΠΎΠ΄ изобраТСния
header('Content-type: image/png');
imagepng($image);

?>

Π’Ρ‹Π²ΠΎΠ΄ ΠΏΡ€ΠΈΠ²Π΅Π΄Ρ‘Π½Π½ΠΎΠ³ΠΎ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π° Π±ΡƒΠ΄Π΅Ρ‚ ΠΏΠΎΡ…ΠΎΠΆ Π½Π°:

Π’Ρ‹Π²ΠΎΠ΄ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π°: imagefilledpolygon()

Π‘ΠΌΠΎΡ‚Ρ€ΠΈΡ‚Π΅ Ρ‚Π°ΠΊΠΆΠ΅

  • imagepolygon() - РисуСт ΠΌΠ½ΠΎΠ³ΠΎΡƒΠ³ΠΎΠ»ΡŒΠ½ΠΈΠΊ
οΌ‹Π”ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ

ΠŸΡ€ΠΈΠΌΠ΅Ρ‡Π°Π½ΠΈΡ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Π΅ΠΉ 9 notes

up
0
martin at eksperimentrum dot dk ΒΆ
8 years ago
How to draw a simple 6-sided star img where x,y is center of the star and s is the size:

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);
}
up
0
Steween ΒΆ
8 years ago
My version of drawStar (with examples)

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

/* drawStar or regular polygon
    $x, $y  -> Position in the image
    $radius -> Radius of the star
    $spikes -> Number of spikes (min 2)
    $ratio  -> Ratio between outer and inner points
    $dir    -> Rotation 270Β° for having an up spike( with 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 Examples
$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);
?>
up
0
rbenheidorn at gmail dot com ΒΆ
11 years ago
Discovered while working on printing geographical boundaries to an image: if you provide floating point vertices, then the decimal value is automatically truncated. This can cause images drawn with floating point vertices to shift slightly towards the top-left corner. My personal resolution is to round all of the vertices to their nearest whole values, which eliminates this shift.
up
0
austinoblouk at yahoo dot com ΒΆ
16 years ago
Actually the minimum it allows is 3. It says "Total number of vertices, which must be bigger than 3." but it allows 3...
up
0
webmaster at mywebsolution dot de ΒΆ
18 years ago
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(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);
?>
up
0
jylyn at hotmail dot com ΒΆ
19 years ago
In spite of what it says about requiring more than 3 vertices, it is possible to draw a triangle with this function!
up
0
tatlar at yahoo dot com ΒΆ
19 years ago
<?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 / 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 ;  // default to 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() ;  // 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 = _makeFiveSidedStar( 100, 100, 50, 'star' ) ;
// Put values into imagepolygon function. You need to define the $image and $color, and flush it out to an image type.?>
up
0
etnekor at tar dot hu ΒΆ
20 years ago
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);
}
?>
up
-2
Arnapou ΒΆ
18 years ago
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(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;
    // 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+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);
                }
            }
        }
        // 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);
}
?>