note 92622 added to function.imageantialias
| From: | dsl101 at osu1 dot php dot net | 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