note 92622 added to function.imageantialias

From: Date: Fri, 31 Jul 2009 15:48:31 +0000
Subject: note 92622 added to function.imageantialias
Groups: php.notes 
Request: Send a blank email to php-notes+get-158969@lists.php.net to get a copy of this message
Having tried long and hard to get a decent antialiased circle function, I finally gave in a wrote something from scratch. Its very very naive - basically examining every single pixel in the enclosing square, but as a result produces very nice antialiasing, with decent control over stroke width, antialiasing amount and tightness of antialiasing. I'm sure it could be optimised considerably, but it was fast enough for what I was doing. Hope its of some use. <?php function imagecircleaa($img, $cx, $cy, $r, $w, $s, $t, $color) // image, centerX, centerY, radius, stroke width, aa width, tightness, color { $adj = $w + $s; $sCol = imagecolorallocate($img, $color['r'], $color['g'], $color['b']); for($x = -$r - $adj; $x <= $r + $adj; $x++) { for($y = -$r - $adj; $y <= $r + $adj; $y++) { $d = sqrt($x * $x + $y * $y); // distance from pixel to center $err = abs($d - $r); // absolute distance from pixel to circle edge if($err <= $w / 2 + $s) // within the stroke width + smoothing radius { if($err <= $w / 2) // inside the stroke width so make it solid color { $aaCol = $sCol; } else // in the antialisaing region so make it a blended color { $err -= $w / 2; // adjust to the aliased part $err = 1 - $err / $s; // adjust to between 0 and 1 $err = ($err - 0.5) * $t * 2; // adjust to -$t to +$t for tightness $err = ($err / sqrt(1 + $err * $err) + 1) / 2; // sigmoid curve to smooth edges $rgb = imagecolorat($img, $x + $cx, $y + $cy); // Get current background color $rB = ($rgb >> 16) & 0xFF; $gB = ($rgb >> 8) & 0xFF; $bB = $rgb & 0xFF; $rDelta = ($rB - $color['r']); // change in Red from background $rComp = $rB - $rDelta * $err; // mix Red $gDelta = ($gB - $color['g']); // change in Red from background $gComp = $gB - $gDelta * $err; // mix Red $bDelta = ($bB - $color['b']); // change in Red from background $bComp = $bB - $bDelta * $err; // mix Red $aaCol = imagecolorallocate($img, $rComp, $gComp, $bComp); } imagesetpixel($img, $x + $cx, $y + $cy, $aaCol); } } } } $img = imagecreatetruecolor(500,500); $cBlack = imagecolorallocate($img, 0, 0, 0); $cGrey = imagecolorallocate($img, 120, 120, 120); $cWhite = imagecolorallocate($img, 255, 255, 255); imagefill($img, 0, 0, $cWhite); imagepolygon($img, array(0, 0,200, 0, 200, 200, 0, 200), 4, cBlack); $aWhite = array('r'=>255, 'g'=>255, 'b'=>255); $aBlack = array('r'=>0, 'g'=>0, 'b'=>0); $aRed = array('r'=>200, 'g'=>0, 'b'=>0); $aGreen = array('r'=>0, 'g'=>200, 'b'=>0); $aBlue = array('r'=>0, 'g'=>0, 'b'=>255); // standard ellipse function for comparison imageellipse($img, 100, 100, 50, 50, $cBlack); // compare different tightnesses - good values are between 2 and 8 // note overall width is stroke width + 2 * aa width (e.g. 12 pixels below) imagecircleaa($img, 50, 50, 25, 2, 5, 2, $aBlue); imagecircleaa($img, 50, 150, 25, 2, 5, 8, $aBlue); // different coloured background to show blending imagefilledrectangle($img, 150,150, 200, 200, $cGrey); imagecircleaa($img, 150, 150, 25, 3, 2, 2, $aRed); // overlapping circles still aa nicely, although the colour blending algorithm produces quite dark intermediate shades imagecircleaa($img, 150, 60, 25, 2, 3, 2, $aBlue); imagecircleaa($img, 150, 50, 25, 2, 3, 2, $aGreen); header("Content-type: image/png"); imagepng($img); imagedestroy($img); ?> ---- Server IP: 89.31.146.176 Probable Submitter: 95.170.17.42 ---- Manual Page -- http://www.php.net/manual/en/function.imageantialias.php Edit -- https://master.php.net/note/edit/92622 Del: integrated -- https://master.php.net/note/delete/92622/integrated Del: useless -- https://master.php.net/note/delete/92622/useless Del: bad code -- https://master.php.net/note/delete/92622/bad+code Del: spam -- https://master.php.net/note/delete/92622/spam Del: non-english -- https://master.php.net/note/delete/92622/non-english Del: in docs -- https://master.php.net/note/delete/92622/in+docs Del: other reasons-- https://master.php.net/note/delete/92622 Reject -- https://master.php.net/note/reject/92622 Search -- https://master.php.net/manage/user-notes.php

« previous php.notes (#158969) next »