On: 2006/02/02
Shorter URL for this page: http://ozh.in/kw

Here is a small PHP function I wrote that emulates a gradient fill of an image.
Disclaimer : there are probably existing alternatives or classes, maybe in PEAR. I didn't check. I wanted to write a function myself, as part of my GD training grounds.

Usage

The function is packaged as a PHP class, the code you need is something like :

  1. require_once('/path/to/gd-gradient-fill.php');
  2. $image = new gd_gradient_fill($width,$height,$direction,$startcolor,$endcolor,$step);

The class call needs 5 arguments and accepts an optional 6th :

  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

Results

Here are a few examples of gradients from color #101040 to #a1a1ff. Hover the image for some unnecessary explanation.


Of course, the function handles non-square images just fine as well.

Get the function

Credits

I started from file header-img.php, part of WordPress core file, which contains a similar hack to draw a gradient fill from lines. I believe this smart code is from Andy Skelton.

If you happen to use this function in any project, be sure to let me know. This makes my day :)

Shorter URL

Want to share or tweet this page? Please use this short URL: http://ozh.in/kw

Metastuff

This page "PHP and GD : Emulate Gradient Fill" was posted on 02/02/2006 at 6:37 pm
Watch this discussion : Comments RSS 2.0.

66 Blablas

  1. Sander says:

    Hi There,

    While trying your gradient functions, i noticed that when you render an image wider than 256 pixels, the colors are incorrect.

    Try rendering this:
    $image = imagecreate(500,100);
    gd_gradient_fill($image,'horizontal','#fff','#000′);

    You'll see it does not end black, but gray.

    Could you please help me in finding out why?

    Regards,

    Sander

  2. Ozh says:

    This is fixed in version 1.1 uploaded today

  3. Sergey Choob says:

    Will you please tell me how to code a gradient figure with light in the middle and color at the ends (half one type – the other half opposite type). I would appriciate your help. Regards.

  4. Thomas Devol says:

    How did you do these corners on this form, this is totally awesome. I'm using your library to create a server side dynamic gradient generator, that I could also adopt to create soft shadows of any color dynamically, on the fly. I plan to implement caching as well.

  5. Thomas Devol says:

    I'm having a problem, no matter what I do – it comes out as an ellipse. Some type of caching issue?;

    $img=imagecreate(100,50);
    require_once('gd-gradient-fill.php');
    gd_gradient_fill($img,'hoizontal','#fff','#000′);
    header("Content-type: image/jpeg");
    imagejpeg($img);

  6. Dx says:

    Ozh is offline.. but maybe i can answer some questions ;)

    @Sergey Choob: I don't understand that, but try with ellipse and setting well the colors.

    @Thomas Devol[1]: it's a propietary addition of mozilla/firefox, that maybe will be implemented later as standard :)
    By now: -moz-border-radius: unit; -moz-border-radius-topleft: unit; -moz-border-radius-bottomleft: unit;
    and so.

    @Thomas Devol[2]: there says "hoizontal". Typo.

  7. tom says:

    Hello!

    And what about transparency?
    How to create .png image with gradient from color to transparency?

  8. DeadMeatGF says:

    I am trying to draw a gradient bar on a bar-graph, and the techniques I've tried so far basically allocate the colours as they draw the bar.
    However, I hace found that when the graph requires 2 or more bars, the second stops – investigation suggests that the image simply runs out of colours!
    With my limited knowledge of PHP, the class appears to return an image rather than adding to an existing one – so can I use this class to add gradiated bars to my chart, or will it need some alterations to the code?

  9. R.M.D. says:

    I modified the last line in the switch cases for circle2 and ellipse in the fill method so
    that the gradient fades into transparency. I found it useful. Maybe you will.

    $eCol = imagecolorallocate( $im, $r1, $g1, $b1 );
    imagecolortransparent($im,$eCol);
    imagefill($im, 0, 0, $eCol); // make this transparent

    Thanks for the library. It's great!

  10. Ryley says:

    Instead of tracking colors and dealing with allocation issues, try one of these two options:

    $fill = imagecolorresolve( $im, $r, $g, $b );

    That one should do the best job of find you your color… but for gradients it may not be good. Instead, this might be best:

    $fill = imagecolorexact( $im, $r, $g, $b );
    if ($fill === -1){
    $fill = imagecolorallocate( $im, $r, $g, $b );
    if ($fill === -1){
    $fill = imagecolorclosest( $im, $r, $g, $b );
    }
    }

    I use other libraries that do this to excellent effect (GD::Graph in perl for instance).

  11. Willy says:

    Hi,

    thank you for that class, it works realy great.

    I had first the same problem like Thomas Devol posted on July 06, all created pictures comes out as eclipse.

    Now I recognize the problem, if you test it you have to
    comment the line 48 in the file gd-gradient-fill.php, than it works fine.

    Best Regards from Berlin
    Willy

  12. Ozh says:

    Willy » well yeah, that line serves as an example :)

  13. Joe Auricchio says:

    Hi!

    I wanted to make a simple gradient across the top inch or so of my blog, fading from light grey into white. I knew recent versions of WP have a gradient-maker script, so I googled for some information on it. Google, in its infinite wisdom, brought me here instead.

    1. $image = new gd_gradient_fill(32,120,"vertical","#ccc","#fff",1);

    Tada! :)

    Thanks so much for the script.
    -joe

  14. Breachware says:

    This module is so cool. But does anyone know how to get it to fill diagonally?

  15. Jack says:

    Rectangle render doesn't work properly. This works better:

    imagefilledrectangle ($im, $i, $i*$height/$width, $width-$i+1, $height-($i*$height/$width) + 1, $fill);

    line 216

    Thanks

    Jack

  16. Os says:

    Rectangle render Problem. This works even better:

    if( $height <= $width ) { imagefilledrectangle ($im, $i, $i*$height/$width, $width-$i+1, $height-($i*$height/$width) + 1, $fill); } else { imagefilledrectangle ($im,$i*$width/$height , $i,$width-($i*$width/$height) + 1 ,$height-$i+1 , $fill); } [/php]

  17. Thomas Cayne says:

    Hi Ozh,

    Thanks for providing this great class. I find it very helpful to fill an entire image. I am trying to fill a gradient polygon ON an image, like a diagonal banner or a sash for a beauty pageant, done dynamically. For example, to fill within the $coords=array(0, 0, 249, 249, 249,164,85,0); with an image size 250px by 250px. I thought it would be simple to do but after 4 hours my eyes are really heavy.

    Thanks.

  18. Ozh says:

    Thomas » I guess simplest way of doing so is first generate the gradient image, then merge it with your original image with imagecopymerge

  19. Tiziano says:

    Hi, great piece of code.
    I'm trying to use the generated image as a table cell background, but i'm not able to do it.
    How can i do it?
    Thanks in advance.

  20. Orlando says:

    Hello Guys I'm kind of new in PHP and I'm just trying to use this library but I get this error

    Unable to create an image.

    Can you give an idea what it could cause this problem.

    THANKS

  21. Ozh says:

    Tiziano » this is a pure CSS issue. Something like the following would work:

    1. td {background-image: url('url/to/image.php')

    Where image.php would be the file that generates your gradient.

    Orlando » this requires PHP extension GD, which you probably don't have on your server then.

  22. Dragen says:

    hi,
    I've been testing your script for a while and am also using in some of my work, but during testing with ellipse and cirle it seems that ellipse is the same as circle2 and circle2 is the same as ellipse..
    Is this just me?

    Thanks

  23. kiuwenayk says:

    hi,
    how do i stretch a gradient image to fill up the entire screen to use as background color. Like one whole ellipse filling the entire screen. Great code indeed!

  24. fahad says:

    I used it in my site :)
    I used to use a static gradient, now I use your script, that either draws the static gradient, or uses the gradient stored in a cookie.

  25. Jordan Shaw says:

    This is great, thanks so much! works like a new million dollar bill.

  26. arne says:

    hello, does anyone know how to get a vertical gradient that fades from color to transparant? i can't get it to work :(

  27. Asad Hasan says:

    Amazing job, this is GD at its best!

  28. Osku says:

    Thanks so much for this class.

    However, I notice that :
    1) $r, $g, $b are not initialized in function fill
    2) when I choose 2 closed colours, I get : http://labo.sakeco.net/trunk/public/wsuper-images/top.png

    thanks for reply :)

  29. Ozh says:

    Osku » Dunno :)

  30. Osku says:

    Actually, I found it :
    The test

    1. if ( "$old_r,$old_g,$old_b" != "$r,$g,$b")

    is guilty :).
    With it, I got some black pixel in my picture, and without everything is fine.

  31. Foomagoo says:

    I'm trying to use this class for generating an image background but I'm unable to write text into the image when this generates the background. Any idea why?

  32. Hi,

    Thanks for this. I think I will use it as a plugin to render text fills in my Dynamic Text Replacement (DTR) script called True Font Family. The upcoming version will allow user plugins and effects. Already made the normal gradient fills myself, but these circle, rectangle and diamond look real nice also!

    Cheers and thanks for this.

  33. […] der Code zum generieren des Farbverlaufs enthalten. Benutzt wird die Klasse gradient.class.php von Planet OZH. Diese erzeugt den passenden Farbverlauf und muss dazu wieder in das selbe Verzeichnis gedownloaded […]

  34. JohnEke says:

    Testing it on my site… great job!

  35. Woudloper says:

    Great stuff you have created and I want to use it for an additional Kubrick version of a WordPress thema or has someone else already did something like this?

    Would it also be possible to add support for diagonally gradient fill from either topleft to rightbottom or vice versa? Or aren't you doing anything more with this code? I also took a look at the PEAR Image package which also contains gradient fill, but the main disadvantage I found of PEAR is that is to large and it is not being maintained since 2006.

  36. Antnee says:

    This is brilliant, thanks. I've embedded this in to a website where users can change the colour-scheme, but parts are gradient images, and I had to provide a selection before.

    Now I have users set their own. I create and save the gradients however, and delete any that don't exist in the database, rather than create them every time.

  37. TH says:

    Nice! …but, much more better if the script has the ability to draw gradients on a background image :)
    Do you have plan to add this feature to your script in future?

  38. fabian says:

    It is something to do with the fact it creates the image and not returns the image

  39. Marquis says:

    Great script, thanks. One thing caught me out, so just to make others aware. There are a couple of uninitialised variables in this code. So if your php.ini is setup with display_errors=on and error_reporting = E_ALL , the image might not generate.

    Not initialising variables in php is fairly common and not usually an issue. The program continues quite happily.
    In this case a problem arises because the warning message ends up bundled in amongst the generated image data.

    To resolve it, either turn off display_errors in the php ini or add the following lines to gd-gradient-fill.php :

    Add:

    1. $r=$r1; $g=$g1; $b=$b1;

    To Line 185, just before:

    1. for ( $i = 0; $i step ) {

    And also:

    1. $fill;

    To line 203, just before:

    1. $fill = imagecolorallocate( $im, $r, $g, $b );

    This fixed it for me. Hope it helps some other folk who encountered this problem.

  40. nico says:

    Thanks, great stuff!

    Only thing… "Hover the image for some unnecessary explanation." only works with non-standard-compliant browsers like IE, which uses alt properties for tooltips…
    You should use title instead.
    Good job anyway

  41. Ozh says:

    nico » You're right about the alt stuff. Fixed!

  42. Nicely done. However, I removed the $this->display from the class constructor so that I can choose to grab the image $obj->image; instead for further processing.

    Very nice function, written in '06, still standing in '09.

  43. Mike says:

    Great tool!

    A transparency option would be nice though. I'm still new at php scripting, but shouldn't it be possible to pass a special value for the either of the color codes (start color or end color) so that the functions recogize that value as indicating "transparent"?

    For example, instead of using #ff0000 and #0000ff to fade from red to blue, you could use #ff0000 and "transparent" to fade from red to transparent. The color values would have to be checked for the "transparent" value some time before the call to hex2rgb. Also, the fill function would have to be modified accordingly.

  44. Mike says:

    Ok, the refactoring to add the ability to use "transparent" as the starting or ending color is done.

    Ozh, I'll email you the revised code for review and posting.

  45. Marcus Vinicius e Sá says:

    Amendment to work on my server,
    because of the "Notice – undefined variable.

    line 190

    / / Marcus Alteracao
    $ r = isset ($ r)? $ r: NULL;
    $ g = isset ($ g)? $ g: NULL;
    $ b = isset ($ b)? $ b: NULL;

    Congratulations for the class and initiative.

    Marcus Sá
    Brazil

  46. Stefan says:

    Is there a chance to get the class with the transparency option?

    This could help me very much.

    Thank you very much in advance.

    Best Regards

    Stefan

  47. Philip says:

    I may be the last one to the party, but boy, am I enjoying myself! Fantastic class, and to mirror the comments above, written in '06 and going strong in '09.

    Any chance for the updated code guys?

    thx

  48. Ozh-

    Great piece of code. Anyway you can post a fix to get transparency? I thought I could just change imagecolorallocate to imagecolorallocatealpha and pass 0-127, but it's not working. I know it's in truecolor mode and I can generate transparent PNGs with imagefill.

    Any ideas? Thanks!

  49. Ah, jumped the gun.

    just needed to add these to the fill method:

    imagealphablending($im, false);
    imagesavealpha($im, true);

    Works like a charm!

  50. Mike says:

    Any example of handling non-square image using this function? I have a rounded corner image and would like to use this function to get the gradient effect. Thanks.

Leave a Reply

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>
Gravatars: Curious about the little images next to each commenter's name ? Go to Gravatar and sign for a free account
Spam: Various spam plugins may be activated. I'll put pins in a Voodoo doll if you spam me.