imageantialias

(PHP 4 >= 4.3.2, PHP 5)

imageantialias -- 是否使用抗锯齿(antialias)功能

说明

bool imageantialias ( resource im, bool on )

对线段和多边形启用快速画图抗锯齿方法。不支持 alpha 部分。使用直接混色操作。仅用于真彩色图像。

不支持线宽和风格。

使用抗锯齿和透明背景色可能出现未预期的结果。混色方法把背景色当成任何其它颜色使用。缺乏 alpha 部分的支持导致不允许基于 alpha 抗锯齿方法。

注: 本函数仅在 PHP 与其捆绑的 GD 库一起编译时可用。

参见 imagecreatetruecolor()


add a note add a note User Contributed Notes
Ulrich Mierendorff
11-Aug-2006 03:39
I've written a php function which draws antialiased and filled elliptic arcs (segments of ellipses or full ellipses). It does not require the imageantialias function of php!
It's available at
http://icewind.ic.funpic.de/index.php?content=ellipse
Best Regards,
Ulrich
php at 3d-box dot com
09-Jul-2006 12:55
This might help some people but I have created an antialiased, filled, ellipse function - the source for which is here:-

http://personal.3d-box.com/php/filledellipseaa.php

As the code is too much to put here!
jb at flamedesign dot dk
31-Mar-2006 06:37
n-dream at gmx dot ch
19-Feb-2006 02:18
The following function draws an AntiAliased (unfilled) Ellipse.
It is used just liked the nomral ImageEllipse function.
The optional parameter sets the number of segments...

function ImageEllipseAA( &$img, $x, $y, $w, $h,$color,$segments=70)
{
   $w=$w/2;
   $h=$h/2;
   $jump=2*M_PI/$segments;
   $oldx=$x+sin(-$jump)*$w;
   $oldy=$y+cos(-$jump)*$h;
   for($i=0;$i<2*(M_PI);$i+=$jump)
   {
       $newx=$x+sin($i)*$w;
       $newy=$y+cos($i)*$h;
       ImageLine($img,$newx,$newy,$oldx,$oldy,$color);
       $oldx=$newx;
       $oldy=$newy;
   }
}
klaas at kosmokrator dot com
15-Feb-2006 09:22
Here is an optimized version of the optimized version of the antialiased circle function by sebbi: (more than 20 times faster)...

<?php

  
function imageSmoothCircle( &$img, $cx, $cy, $cr, $color ) {
      
$ir = $cr;
      
$ix = 0;
      
$iy = $ir;
      
$ig = 2 * $ir - 3;
      
$idgr = -6;
      
$idgd = 4 * $ir - 10;
      
$fill = imageColorExactAlpha( $img, $color[ 'R' ], $color[ 'G' ], $color[ 'B' ], 0 );
      
imageLine( $img, $cx + $cr - 1, $cy, $cx, $cy, $fill );
      
imageLine( $img, $cx - $cr + 1, $cy, $cx - 1, $cy, $fill );
      
imageLine( $img, $cx, $cy + $cr - 1, $cx, $cy + 1, $fill );
      
imageLine( $img, $cx, $cy - $cr + 1, $cx, $cy - 1, $fill );
      
$draw = imageColorExactAlpha( $img, $color[ 'R' ], $color[ 'G' ], $color[ 'B' ], 42 );
      
imageSetPixel( $img, $cx + $cr, $cy, $draw );
      
imageSetPixel( $img, $cx - $cr, $cy, $draw );
      
imageSetPixel( $img, $cx, $cy + $cr, $draw );
      
imageSetPixel( $img, $cx, $cy - $cr, $draw );
       while (
$ix <= $iy - 2 ) {
           if (
$ig < 0 ) {
              
$ig += $idgd;
              
$idgd -= 8;
              
$iy--;
           } else {
              
$ig += $idgr;
              
$idgd -= 4;
           }
          
$idgr -= 4;
          
$ix++;
          
imageLine( $img, $cx + $ix, $cy + $iy - 1, $cx + $ix, $cy + $ix, $fill );
          
imageLine( $img, $cx + $ix, $cy - $iy + 1, $cx + $ix, $cy - $ix, $fill );
          
imageLine( $img, $cx - $ix, $cy + $iy - 1, $cx - $ix, $cy + $ix, $fill );
          
imageLine( $img, $cx - $ix, $cy - $iy + 1, $cx - $ix, $cy - $ix, $fill );
          
imageLine( $img, $cx + $iy - 1, $cy + $ix, $cx + $ix, $cy + $ix, $fill );
          
imageLine( $img, $cx + $iy - 1, $cy - $ix, $cx + $ix, $cy - $ix, $fill );
          
imageLine( $img, $cx - $iy + 1, $cy + $ix, $cx - $ix, $cy + $ix, $fill );
          
imageLine( $img, $cx - $iy + 1, $cy - $ix, $cx - $ix, $cy - $ix, $fill );
          
$filled = 0;
           for (
$xx = $ix - 0.45; $xx < $ix + 0.5; $xx += 0.2 ) {
               for (
$yy = $iy - 0.45; $yy < $iy + 0.5; $yy += 0.2 ) {
                   if (
sqrt( pow( $xx, 2 ) + pow( $yy, 2 ) ) < $cr ) $filled += 4;
               }
           }
          
$draw = imageColorExactAlpha( $img, $color[ 'R' ], $color[ 'G' ], $color[ 'B' ], ( 100 - $filled ) );
          
imageSetPixel( $img, $cx + $ix, $cy + $iy, $draw );
          
imageSetPixel( $img, $cx + $ix, $cy - $iy, $draw );
          
imageSetPixel( $img, $cx - $ix, $cy + $iy, $draw );
          
imageSetPixel( $img, $cx - $ix, $cy - $iy, $draw );
          
imageSetPixel( $img, $cx + $iy, $cy + $ix, $draw );
          
imageSetPixel( $img, $cx + $iy, $cy - $ix, $draw );
          
imageSetPixel( $img, $cx - $iy, $cy + $ix, $draw );
          
imageSetPixel( $img, $cx - $iy, $cy - $ix, $draw );
       }
   }

  
$img = imageCreateTrueColor( 320, 240 );

  
imageSmoothCircle( $img, 160, 120, 100, array( 'R' => 0xCC, 'G' => 0x33, 'B' => 0x00 ) );
  
imageSmoothCircle( $img, 170, 11075, array( 'R' => 0xDD, 'G' => 0x66, 'B' => 0x00 ) );
  
imageSmoothCircle( $img, 180, 10050, array( 'R' => 0xEE, 'G' => 0x99, 'B' => 0x00 ) );
  
imageSmoothCircle( $img, 1909025, array( 'R' => 0xFF, 'G' => 0xCC, 'B' => 0x00 ) );

  
header( 'Content-Type: image/png' );
  
imagePNG( $img );

?>
voinic at NOSgmailPAM dot com
13-Jan-2006 06:22
The only trick I found to draw an antialiased polygon AND keep it transparent (to use them as overlays in google maps for example)... make two images and merge them. Order of operations is important and the transparency color of the final image must be set after the merge:

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

$values = array(
          
4050// Point 1 (x, y)
          
20240, // Point 2 (x, y)
          
6060// Point 3 (x, y)
          
240, 20// Point 4 (x, y)
          
5040// Point 5 (x, y)
          
1010  // Point 6 (x, y)
          
);                   

$im = imagecreate(250, 250);
$bg = imagecolorallocate($im, 255, 255, 255);

$im2 = imagecreatetruecolor(250, 250);
$bg2 = imagecolorallocate($im2, 255, 255, 255);
imagefilledrectangle($im2,0,0,249,249,$bg2);
imagecolortransparent($im2, $bg);
imageantialias($im2, true);
$c_red = imagecolorallocate($im2, 255, 0, 0);
imagepolygon($im2, $values, 6, $c_red);
imageantialias($im2, false);

imagecopymerge($im, $im2,0,0,0,0,250,250,50);

imagecolortransparent($im, $bg);
$c_red_alpha = imagecolorallocatealpha($im, 255, 0, 0, 60);
imagefilledpolygon($im, $values, 6, $c_red_alpha);

imagepng($im);
imagedestroy($im);
imagedestroy($im2);
?>
sebbi at conceptT dot com
26-Sep-2005 10:06
I did a search in google and got following url:
http://www.isocalc.com/tutorials/antialias.htm
With this tutorial I was able to write a function to convert this algorithm into php, the result for a filled circel is this:
<?php
function imagefilledcircleantialiased(&$im, $cx, $cy, $r, $fgcolor, $bgcolor) {
 
$fgcolors = imagecolorsforindex($im,$fgcolor);
 
$bgcolors = imagecolorsforindex($im,$bgcolor);
  for (
$x = $cx - $r; $x <= $cx + $r; $x++ ) {
   for (
$y = $cy - $r; $y <= $cy + $r; $y++ ) {
    
$rx = $x - $cx; $ry = $y - $cy;
    
$ir = sqrt(( $rx == 0 ? 0 : pow($rx - 0.5*abs($rx)/$rx, 2) ) + ( $ry == 0 ? 0 : pow($ry - 0.5*abs($ry)/$ry, 2) ));
    
$or = sqrt(( $rx == 0 ? 0 : pow($rx + 0.5*abs($rx)/$rx, 2) ) + ( $ry == 0 ? 0 : pow($ry + 0.5*abs($ry)/$ry, 2) ));
     if (
$or <= $r ) {
      
imagesetpixel($im, $x, $y, $fgcolor);
     }
     elseif (
$ir < $r ) {
      
$filled = 0;
       for (
$xx = $x - 0.45; $xx < $x + 0.5; $xx+=0.1 ) {
         for (
$yy = $y - 0.45; $yy < $y + 0.5; $yy+=0.1 ) {
          
$rxx = $xx - $cx; $ryy = $yy - $cy;
           if (
sqrt(pow($rxx, 2) + pow($ryy, 2)) < $r ) $filled++;
         }
       }
      
$red = round($bgcolors['red'] + ( $fgcolors['red'] - $bgcolors['red'] ) * $filled / 100);
      
$green = round($bgcolors['green'] + ( $fgcolors['green'] - $bgcolors['green'] ) * $filled / 100);
      
$blue = round($bgcolors['blue'] + ( $fgcolors['blue'] - $bgcolors['blue'] ) * $filled / 100);
      
imagesetpixel($im, $x, $y, imagecolorclosest($im, $red, $green, $blue));
     }
   }
  }
}

$width = 160;
$height = 200;
$r = 20;
$bgc = "651713";
$fgc = "b12b2c";

$im = imagecreate($width, $height);
$bgcolor = imagecolorallocate($im, hexdec(substr($bgc, 0, 2)), hexdec(substr($bgc, 2, 2)), hexdec(substr($bgc, 4, 2)));
for(
$i = 0; $i < 100; $i++ ) {
  
imagecolorallocate($im, ( hexdec(substr($fgc, 0, 2)) + $i*hexdec(substr($bgc, 0, 2))) / ($i + 1), ( hexdec(substr($fgc, 2, 2)) + $i*hexdec(substr($bgc, 2, 2))) / ($i + 1), ( hexdec(substr($fgc, 4, 2)) + $i*hexdec(substr($bgc, 4, 2))) / ($i + 1));
}
$fgcolor = imagecolorclosest($im, hexdec(substr($fgc, 0, 2)), hexdec(substr($fgc, 2, 2)), hexdec(substr($fgc, 4, 2)));

imagefilledcircleantialiased($im, 80, 100, $r, $fgcolor, $bgcolor);

header("Content-Type: image/png");
imagepng($im);
?>
An improvement would be to draw the inner rectangle or more rectangles in the circle with the builtin rectangle function to reduce the usage of imagesetpixel() from (2*r)^2 to 2*Pi*(r + epsilon), in other words, the dependency on r would break down from square to linear.
Another improvement would be to determine filled and unfilled triangles in the observed pixel and calculate their areas, so we can get rid of the inner loops for getting the fraction filled/unfilled.
One can easily modify this function to solve other problems like lines, unfilled circles, etc.
trimbo
06-Sep-2005 03:25
So far using PHP 5.0.4 I've managed to get Imageantialias() to work well with:
ImageLine()
ImagePolygon()

but not with:
ImageArc()
ImageEllipse()
ImageFilled*()

You can still draw antialiased filled polygons by drawing a hollow polygon on top of a filled one with the same dimensions:
<?php
       $points
=array($x,$y, $x2,$y2, $x3,$y3);
      
imageFilledPolygon($im, $points, 3, $gray );
      
imagePolygon($im, $points, 3, $gray );
?>
klaas at kosmokrator dot com
24-May-2004 10:21
I have optimized the "imageSmoothLine" function by logang.

sample and download at:

http://www.kosmokrator.com/download/php/
logang at deltatee dot com
06-Aug-2003 06:28
I've writen some antialiasing functions for people who don't have the requirements for the builtin antialiasing.

You can download a copy at: http://grey.deltatee.com/image.phps
Igor Garcia
30-Jun-2003 05:57
This function its only available if you have the BUNDLED version of GD.
(PHP 4.3.2)