note 78816 added to function.imagefilledpolygon

From: Date: Mon, 29 Oct 2007 14:49:00 +0000
Subject: note 78816 added to function.imagefilledpolygon
Groups: php.notes 
Request: Send a blank email to php-notes+get-131812@lists.php.net to get a copy of this message
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); } ?> ---- Server IP: 195.221.21.36 Probable Submitter: 171.16.2.5 ---- Manual Page -- http://www.php.net/manual/en/function.imagefilledpolygon.php Edit -- https://master.php.net/note/edit/78816 Del: integrated -- https://master.php.net/note/delete/78816/integrated Del: useless -- https://master.php.net/note/delete/78816/useless Del: bad code -- https://master.php.net/note/delete/78816/bad+code Del: spam -- https://master.php.net/note/delete/78816/spam Del: non-english -- https://master.php.net/note/delete/78816/non-english Del: in docs -- https://master.php.net/note/delete/78816/in+docs Del: other reasons-- https://master.php.net/note/delete/78816 Reject -- https://master.php.net/note/reject/78816 Search -- https://master.php.net/manage/user-notes.php

« previous php.notes (#131812) next »