|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
[2003-02-06 22:18 UTC] ljpersson at hotmail dot com
(Using built-in GD 2.x in PHP 4.3.0) imagefilledellipse() creates moire' patterns inside the filled ellipse when alpha blending is enabled. The problem seems to be that the fill algorithm strokes the same point within the ellipse several times and due to the alpha blending of single pixels creates several color shades within the ellipse. This is fine as long as a solid fill is used but does not work together with alpha blending. PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
|
|||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Sat Oct 25 08:00:01 2025 UTC |
I wrote a drop in replacement for the GD gdImageFilledArc() which works with alpha-blending. Replace the gdImageFilledArc() in gd.c with the following function. Which is reasonable fast. void gdImageFilledArc (gdImagePtr im, int cx, int cy, int w, int h, int s, int e, int color, int style) { /* This replacement for the original gdImageFilledArc() completely mimics the original behavior. This includes the behaviour I would consider a bug where a style of IMG_ARC_CHORD is the same as IMG_ARC_PIE for filled arcs. The benefit of this implementation is that this will also work for colors where alpha-blending is used. This algorithm uses GD standard sin & cos tables for quick lookup. However, this also limits the accuracy to 1 degree. This means that very very large arc's will look "squarish". However for any normal sizes, say < 2000 pixels, this is not really a problem in practice. */ gdPoint p[362]; /* Sanity check */ if( w < 0 || h < 0 ) return; /* Make sure angles are positive and e > s */ while( s < 0 ) s += 360; while( e < 0 ) e += 360; while( e < s ) e += 360; s %= 360; if( e > 360 ) e %= 360; /* In the algorithm we need to ue the radius */ w /= 2; h /= 2; /* We handle the chord and pie cases separately */ if( style & gdChord ) { int x1,y1,x2,y2; x1 = cx + ((long) gdCosT[s] * (long) w / 1024 ); y1 = cy + ((long) gdSinT[s] * (long) h / 1024 ); x2 = cx + ((long) gdCosT[e] * (long) w / 1024 ); y2 = cy + ((long) gdSinT[e] * (long) h / 1024 ); if( style & gdNoFill ) { if( style & gdEdged ) { p[0].x = cx; p[0].y = cy; p[1].x = x1; p[1].y = y1; p[2].x = x2; p[2].y = y2; p[3].x = cx; p[3].y = cy; gdImagePolygon (im, p, 4, color); } else { gdImageLine (im, x1, y1, x2, y2, color); } } else { p[0].x = cx; p[0].y = cy; p[1].x = x1; p[1].y = y1; p[2].x = x2; p[2].y = y2; p[3].x = cx; p[3].y = cy; gdImageFilledPolygon (im, p, 4, color); } } else { /* style must be gdPie */ int i=0, a=s; if( style & gdEdged || ! (style & gdNoFill) ) { p[0].x = cx; p[0].y = cy; i=1; } while( a <= e ) { p[i].x = cx + ((long) gdCosT[a] * (long) w / 1024 ); p[i].y = cy + ((long) gdSinT[a] * (long) h / 1024 ); ++i; ++a; } if( style & gdEdged || ! (style & gdNoFill) ) { p[i].x = cx; p[i].y = cy; ++i; } if( style & gdNoFill ) { gdImagePolygon (im, p, i, color); } else { gdImageFilledPolygon (im, p,i , color); } } }