Click here to Skip to main content
15,881,898 members
Articles / Multimedia / GDI+
Article

An advanced gradient rendering class

Rate me:
Please Sign up or sign in to vote.
3.69/5 (16 votes)
21 Mar 2006CPOL3 min read 60.6K   1.5K   39   6
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, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior) Elektromehanika d.o.o. Nis
Serbia Serbia
He has a master degree in Computer Science at Faculty of Electronics in Nis (Serbia), and works as a C++/C# application developer for Windows platforms since 2001. He likes traveling, reading and meeting new people and cultures.

Comments and Discussions

 
GeneralThank you! :) Pin
leandrojardim21-Nov-09 12:10
leandrojardim21-Nov-09 12:10 
GeneralDeffusion Point Pin
theali8-Feb-07 19:57
theali8-Feb-07 19:57 
GeneralThanks for this Pin
roel_7-Dec-06 2:26
roel_7-Dec-06 2:26 
Questioncan you add a EXE file to demo archive? Pin
Ștefan-Mihai MOGA20-Mar-06 20:40
professionalȘtefan-Mihai MOGA20-Mar-06 20:40 
GeneralNice, but... Pin
Paul Selormey20-Mar-06 5:44
Paul Selormey20-Mar-06 5:44 
GeneralRe: Nice, but... Pin
darkoman20-Mar-06 11:29
darkoman20-Mar-06 11:29 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.