Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

An advanced gradient rendering class

0.00/5 (No votes)
21 Mar 2006 1  
An article on rendering different gradients.

CGradientTest Project

Introduction

This article is about gradients (simple and those not so simple). A simple class is developed in order to help render different gradient types like: horizontal, vertical, diagonal, radial, two-color and multi-color, and as a special case, custom gradients (based on user-created regions). Also, this class has a built-in gamma correction method with adjustable gamma threshold values.

Background

There are many resources available (on the CodeProject and on the Internet) considering gradients, so this article is just another way the problem can be solved.

Using the code

Using this class is as simple as it can be. You should include the class header file Gradient.h, and after that, you will able to create as many instances of the CGradient class. But they all do the same thing described below:

#include "Gradient.h"


/* Somewhere in OnDraw method */
CGradient gradient;
RECT rect = {100, 100, 200, 200};
COLORREF colorStart = RGB(255,0,0);
COLORREF colorEnd = RGB(0,0,255);

gradient.HorizontalGradient(pDC->m_hDC, rect, 
                          colorStart, colorEnd);

And this would be enough to get a horizontal two-color gradient. In the base, all methods of the CGradient class work in the same manner. The last two params of the methods are BOOL and double which turn on/off the gamma correction and set the gamma correction value, respectively. See the "Gradient.h" header file for details.

The following gradients can be drawn:

  • Two-color horizontal gradient
  • Two-color vertical gradient
  • Two-color forward diagonal gradient
  • Two-color backward diagonal gradient
  • Two-color radial gradient
  • Multi-color horizontal gradient
  • Multi-color vertical gradient
  • Multi-color radial gradient
  • Custom two-color horizontal gradient
  • Custom two-color vertical gradient
  • Custom multi-color horizontal gradient
  • Custom multi-color vertical gradient

What about custom gradients?

Well, instead of passing a RECT variable as an argument for the two-color or multi-color horizontal and vertical gradients, we can pass a HRGN variable. There are overloaded methods for this (the last four in the list above). In this way, beautiful effects can be achieved with very little effort to create custom regions. I should mention here that if HRGN is used, the gradients are rendered slower than when RECT is used. It is primarily because the Win API method PtInRegion() must be called in this case to check if a pixel belongs to the region or not.

What about gamma correction?

Gamma correction is used to get a smooth gradient scale. It is well known that different monitors apply different intensity of light (based on the input voltage) for different pixel intensity values. This means if a pixel has an intensity of 255 it should be white, with maximum intensity of light. And the one with intensity of 128 (gray color) should have exactly one half of the light intensity than the previous one. Right? No, not at all. Maybe 73% or something, I don't know. But if you apply simple color processing features, you can get very good results and the speed of the algorithm is not degraded. It is a very simple equation:

color = ((color/maximumColor) ^ gamma) * maximumColor;

This is applied to all three channels (red, green, and blue) and you can see the result. The range of the gamma value goes from 0 to 2.5 or more (if necessary), and it depends on the monitor type. In this project, the gamma value of 0.4 is used. If you find this value not good for your case, you can use other values. Smaller values make images lighter, and larger makes them darker.

Conclusion

There are some methods that can be used to make custom gradients render better, and I am still researching.

Points of Interest

I was impressed by the GDI+ brushes (specially LinearGradientBrush) which can create wonderful gradients and is also able to adjust the gamma value.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here