PHP绘制渐变颜色图片


使用范例如下,基本函数封装在gd-gradient-fill.php中,

  1. require_once('/path/to/gd-gradient-fill.php');  
  2. $image = new gd_gradient_fill($width,$height,$direction,$startcolor,$endcolor,$step);   
gd_gradient_fill有5个必要参数和一个可选参数:
  1. integer $width
    Width of the image
  2. integer $height
    Height of the image
  3. string $direction
    The shape or direction of the gradient, which can be any of : vertical, horizontal, ellipse, ellipse2, circle, circle2, rectangle, diamond.
  4. string $startcolor
    Gradient start color, 3 or 6 digit hexadecimal ("#ff0" or "#dd4578")
  5. string $endcolor
    Gradient end color
  6. Optional : $step
    Breaks the gradient smooth blending

下面是一些实例,颜色从#101040渐变到#a1a1ff, 渐变方向不同, 鼠标移动到图片上可看到提示信息.


另外, 这个函数处理非矩形图片一样可以.


附函数源码如下:

  1. <?php  
  2. /* 
  3. Script Name: GD Gradient Fill 
  4. Script URI: http://planetozh.com/blog/my-projects/images-php-gd-gradient-fill/ 
  5. Description: Creates a gradient fill of any shape (rectangle, ellipse, vertical, horizontal, diamond) 
  6. Author: Ozh 
  7. Version: 1.1 
  8. Author URI: http://planetozh.com/ 
  9. */  
  10.   
  11. /* Release history : 
  12.  * 1.1 
  13.  *      - changed : more nicely packaged as a class 
  14.  *      - fixed : not displaying proper gradient colors with image dimension greater than 255 (because of a limitation in imagecolorallocate) 
  15.  *      - added : optional parameter 'step', more options for 'direction' 
  16.  * 1.0 
  17.  *      - initial release 
  18.  */  
  19.   
  20. /* Usage : 
  21.  * 
  22.  * require_once('/path/to/gd-gradient-fill.php'); 
  23.  * $image = new gd_gradient_fill($width,$height,$direction,$startcolor,$endcolor,$step); 
  24.  * 
  25.  * Parameters : 
  26.  *      - width and height : integers, dimesions of your image. 
  27.  *      - direction : string, shape of the gradient. 
  28.  *        Can be : vertical, horizontal, rectangle (or square), ellipse, ellipse2, circle, circle2, diamond. 
  29.  *      - startcolor : string, start color in 3 or 6 digits hexadecimal. 
  30.  *      - endcolor : string, end color in 3 or 6 digits hexadecimal. 
  31.  *      - step : integer, optional, default to 0. Step that breaks the smooth blending effect. 
  32.  * Returns a resource identifier. 
  33.  * 
  34.  * Examples : 
  35.  * 
  36.  * 1. 
  37.  * require_once('/home/ozh/www/includes/gd-gradient-fill.php'); 
  38.  * $image = new gd_gradient_fill(200,200,'horizontal','#fff','#f00'); 
  39.  * 
  40.  * 2. 
  41.  * require_once('c:/iis/inet/include/gd-gradient-fill.php'); 
  42.  * $myimg = new gd_gradient_fill(80,20,'diamond','#ff0010','#303060'); 
  43.  * 
  44.  */  
  45.   
  46.   
  47. // Test it :   
  48. // $image = new gd_gradient_fill(400,200,'ellipse','#f00','#000',0);   
  49.   
  50. class gd_gradient_fill {  
  51.       
  52.     // Constructor. Creates, fills and returns an image   
  53.     function gd_gradient_fill($w,$h,$d,$s,$e,$step=0) {  
  54.         $this->width = $w;  
  55.         $this->height = $h;  
  56.         $this->direction = $d;  
  57.         $this->startcolor = $s;  
  58.         $this->endcolor = $e;  
  59.         $this->step = intval(abs($step));  
  60.   
  61.         // Attempt to create a blank image in true colors, or a new palette based image if this fails   
  62.         if (function_exists('imagecreatetruecolor')) {  
  63.             $this->image = imagecreatetruecolor($this->width,$this->height);  
  64.         } elseif (function_exists('imagecreate')) {  
  65.             $this->image = imagecreate($this->width,$this->height);  
  66.         } else {  
  67.             die('Unable to create an image');  
  68.         }  
  69.           
  70.         // Fill it   
  71.         $this->fill($this->image,$this->direction,$this->startcolor,$this->endcolor);  
  72.           
  73.         // Show it         
  74.         $this->display($this->image);  
  75.           
  76.         // Return it   
  77.         return $this->image;  
  78.     }  
  79.       
  80.       
  81.     // Displays the image with a portable function that works with any file type   
  82.     // depending on your server software configuration   
  83.     function display ($im) {  
  84.         if (function_exists("imagepng")) {  
  85.             header("Content-type: image/png");  
  86.             imagepng($im);  
  87.         }  
  88.         elseif (function_exists("imagegif")) {  
  89.             header("Content-type: image/gif");  
  90.             imagegif($im);  
  91.         }  
  92.         elseif (function_exists("imagejpeg")) {  
  93.             header("Content-type: image/jpeg");  
  94.             imagejpeg($im"", 0.5);  
  95.         }  
  96.         elseif (function_exists("imagewbmp")) {  
  97.             header("Content-type: image/vnd.wap.wbmp");  
  98.             imagewbmp($im);  
  99.         } else {  
  100.             die("Doh ! No graphical functions on this server ?");  
  101.         }  
  102.         return true;  
  103.     }  
  104.       
  105.       
  106.     // The main function that draws the gradient   
  107.     function fill($im,$direction,$start,$end) {  
  108.           
  109.         switch($direction) {  
  110.             case 'horizontal':  
  111.                 $line_numbers = imagesx($im);  
  112.                 $line_width = imagesy($im);  
  113.                 list($r1,$g1,$b1) = $this->hex2rgb($start);  
  114.                 list($r2,$g2,$b2) = $this->hex2rgb($end);  
  115.                 break;  
  116.             case 'vertical':  
  117.                 $line_numbers = imagesy($im);  
  118.                 $line_width = imagesx($im);  
  119.                 list($r1,$g1,$b1) = $this->hex2rgb($start);  
  120.                 list($r2,$g2,$b2) = $this->hex2rgb($end);  
  121.                 break;  
  122.             case 'ellipse':  
  123.                 $width = imagesx($im);  
  124.                 $height = imagesy($im);  
  125.                 $rh=$height>$width?1:$width/$height;  
  126.                 $rw=$width>$height?1:$height/$width;  
  127.                 $line_numbers = min($width,$height);  
  128.                 $center_x = $width/2;  
  129.                 $center_y = $height/2;  
  130.                 list($r1,$g1,$b1) = $this->hex2rgb($end);  
  131.                 list($r2,$g2,$b2) = $this->hex2rgb($start);  
  132.                 imagefill($im, 0, 0, imagecolorallocate( $im$r1$g1$b1 ));  
  133.                 break;  
  134.             case 'ellipse2':  
  135.                 $width = imagesx($im);  
  136.                 $height = imagesy($im);  
  137.                 $rh=$height>$width?1:$width/$height;  
  138.                 $rw=$width>$height?1:$height/$width;  
  139.                 $line_numbers = sqrt(pow($width,2)+pow($height,2));  
  140.                 $center_x = $width/2;  
  141.                 $center_y = $height/2;  
  142.                 list($r1,$g1,$b1) = $this->hex2rgb($end);  
  143.                 list($r2,$g2,$b2) = $this->hex2rgb($start);  
  144.                 break;  
  145.             case 'circle':  
  146.                 $width = imagesx($im);  
  147.                 $height = imagesy($im);  
  148.                 $line_numbers = sqrt(pow($width,2)+pow($height,2));  
  149.                 $center_x = $width/2;  
  150.                 $center_y = $height/2;  
  151.                 $rh = $rw = 1;  
  152.                 list($r1,$g1,$b1) = $this->hex2rgb($end);  
  153.                 list($r2,$g2,$b2) = $this->hex2rgb($start);  
  154.                 break;  
  155.             case 'circle2':  
  156.                 $width = imagesx($im);  
  157.                 $height = imagesy($im);  
  158.                 $line_numbers = min($width,$height);  
  159.                 $center_x = $width/2;  
  160.                 $center_y = $height/2;  
  161.                 $rh = $rw = 1;  
  162.                 list($r1,$g1,$b1) = $this->hex2rgb($end);  
  163.                 list($r2,$g2,$b2) = $this->hex2rgb($start);  
  164.                 imagefill($im, 0, 0, imagecolorallocate( $im$r1$g1$b1 ));  
  165.                 break;  
  166.             case 'square':  
  167.             case 'rectangle':  
  168.                 $width = imagesx($im);  
  169.                 $height = imagesy($im);  
  170.                 $line_numbers = max($width,$height)/2;  
  171.                 list($r1,$g1,$b1) = $this->hex2rgb($end);  
  172.                 list($r2,$g2,$b2) = $this->hex2rgb($start);  
  173.                 break;  
  174.             case 'diamond':  
  175.                 list($r1,$g1,$b1) = $this->hex2rgb($end);  
  176.                 list($r2,$g2,$b2) = $this->hex2rgb($start);  
  177.                 $width = imagesx($im);  
  178.                 $height = imagesy($im);  
  179.                 $rh=$height>$width?1:$width/$height;  
  180.                 $rw=$width>$height?1:$height/$width;  
  181.                 $line_numbers = min($width,$height);  
  182.                 break;  
  183.             default:  
  184.         }  
  185.           
  186.         for ( $i = 0; $i < $line_numbers$i=$i+1+$this->step ) {  
  187.             // old values :   
  188.             $old_r=$r;  
  189.             $old_g=$g;  
  190.             $old_b=$b;  
  191.             // new values :   
  192.             $r = ( $r2 - $r1 != 0 ) ? intval$r1 + ( $r2 - $r1 ) * ( $i / $line_numbers ) ): $r1;  
  193.             $g = ( $g2 - $g1 != 0 ) ? intval$g1 + ( $g2 - $g1 ) * ( $i / $line_numbers ) ): $g1;  
  194.             $b = ( $b2 - $b1 != 0 ) ? intval$b1 + ( $b2 - $b1 ) * ( $i / $line_numbers ) ): $b1;  
  195.             // if new values are really new ones, allocate a new color, otherwise reuse previous color.   
  196.             // There's a "feature" in imagecolorallocate that makes this function   
  197.             // always returns '-1' after 255 colors have been allocated in an image that was created with   
  198.             // imagecreate (everything works fine with imagecreatetruecolor)   
  199.             if ( "$old_r,$old_g,$old_b" != "$r,$g,$b")   
  200.                 $fill = imagecolorallocate( $im$r$g$b );  
  201.             switch($direction) {  
  202.                 case 'vertical':  
  203.                     imagefilledrectangle($im, 0, $i$line_width$i+$this->step, $fill);  
  204.                     break;  
  205.                 case 'horizontal':  
  206.                     imagefilledrectangle( $im$i, 0, $i+$this->step, $line_width$fill );  
  207.                     break;  
  208.                 case 'ellipse':  
  209.                 case 'ellipse2':  
  210.                 case 'circle':  
  211.                 case 'circle2':  
  212.                     imagefilledellipse ($im,$center_x$center_y, ($line_numbers-$i)*$rh, ($line_numbers-$i)*$rw,$fill);  
  213.                     break;  
  214.                 case 'square':  
  215.                 case 'rectangle':  
  216.                     imagefilledrectangle ($im,$i*$width/$height,$i*$height/$width,$width-($i*$width/$height), $height-($i*$height/$width),$fill);  
  217.                     break;  
  218.                 case 'diamond':  
  219.                     imagefilledpolygon($imarray (  
  220.                         $width/2, $i*$rw-0.5*$height,  
  221.                         $i*$rh-0.5*$width$height/2,  
  222.                         $width/2,1.5*$height-$i*$rw,  
  223.                         1.5*$width-$i*$rh$height/2 ), 4, $fill);  
  224.                     break;  
  225.                 default:      
  226.             }         
  227.         }  
  228.     }  
  229.       
  230.     // #ff00ff -> array(255,0,255) or #f0f -> array(255,0,255)   
  231.     function hex2rgb($color) {  
  232.         $color = str_replace('#','',$color);  
  233.         $s = strlen($color) / 3;  
  234.         $rgb[]=hexdec(str_repeat(substr($color,0,$s),2/$s));  
  235.         $rgb[]=hexdec(str_repeat(substr($color,$s,$s),2/$s));  
  236.         $rgb[]=hexdec(str_repeat(substr($color,2*$s,$s),2/$s));  
  237.         return $rgb;  
  238.     }  
  239. }  
  240. ?>  

相关内容