Click here to Skip to main content
15,884,472 members
Articles / Programming Languages / C# 3.5

C# color gradient control

Rate me:
Please Sign up or sign in to vote.
4.54/5 (23 votes)
9 Sep 2015CPOL3 min read 30.1K   1.7K   20   3
An implementation of color gradient control in c#, and a use case applied to procedural landscape generation.

Image 1

Introduction

In procedural texture generation , that I've already faced here and in which I get involved here  , can become useful to have a tool to manage Color Gradients. Searching the web I didn't find a c# control to implement what I needed. I decide to do it my self.

Background

I faced two cases where may become usefully color control gradient, first is in the gdi+ .net library (here)  , the second in texture generation. I the second case you start with a noise function to generate a heightmap, than you may want to associate a height value to a color; here come in hand a color gradient.

Let's suppose we generate the following noise:

Image 2

applying a color gradient like this:  

Image 3

we get the following (landscape-like) bitmap:

Image 4

applying a different color gradient from the same starting noise we can get a (sky) bitmap like this:

Image 5

Using the code

Using the control in design

To add the control ColGradCtr at design drag it into your form and size it like you want. It contains two default colors White (starting) and Black (ending).

Then you can reset the two starting colors in the load event of the contol (or in the load event of the form). At the same time you can add others colors.

C#
        private void colGradCtr1_Load_1(object sender, EventArgs e)
        {
            colGradCtr1.reset(Color.Blue, Color.White); //redefine start and end color
            colGradCtr1.addColor(Color.FromArgb(0, 128, 128), 0.06f); //put a color in position 0.06
            colGradCtr1.addColor(Color.FromArgb(0, 0, 159), 0.60f);
            colGradCtr1.addColor(Color.FromArgb(6, 20, 203), 0.70f); 
            colGradCtr1.addColor(Color.FromArgb(146, 96, 53), 0.75f);
            colGradCtr1.addColor(Color.FromArgb(0, 100, 0), 0.80f);
            colGradCtr1.addColor(Color.FromArgb(64, 0, 0), 0.90f);
        }

The control need at leaast two colors (start and ending) that are respectively in position 0 and 1. All the other colors are in position >0 and <1.

Getting a sample color from ColGradCtr. If you give a float input >=0 and <=1 you get the corrisponding color.

Let's see the landscape generation routine:

C#
//paints Picturebox pct according to heightmap and ColGradCtr col
private void reColor(PictureBox pct, ColGradCtr col){
            Bitmap b2 = new Bitmap(pct.Width, pct.Height);
            for (int i = 0; i < pct.Width; i++)
                for (int j = 0; j < pct.Height; j++)
                {
                    b2.SetPixel(i, j, col.getColor(heightMap[i, j]));                    
                }
            pct.Image = b2;
}

where heightMap is a float matrix containing the samples (heights) between 0 and 1.

The gdi+ aproach. If you ned a linear gradient you can get it fom ColGradCtr  in this manner : 

C#
LinearGradientBrush br = new LinearGradientBrush(this.pictureBox1.ClientRectangle, Color.Black
, Color.Black,LinearGradientMode.BackwardDiagonal);
ColorBlend cb = BackGradCtr.getColorBlend();//here i get the blend from ctrl
br.InterpolationColors = cb;

offScreenDC.FillRectangle(br, this.pictureBox1.ClientRectangle);

Using the control at runtime. Pressing left mouse on a handle, you can move it, changing the color position. If you drag the handle out to the of control (to the right), you erase that color. Pressing right mouse near an handle let you modify the color value, pressing right mouse in empty place let you add a new color. Start and end colors can not be moved or erased, but you can change them.

The event management : I implemented two events , ColorChanged and ColorChanging. The first fires when you are moving a color , the second when you release mouse buttons and commit a change (modify a color, add a color , erase a color). Follows as I used ColorChanged event in thr example aplication:

C#
private void colGradCtr1_ColorChanged(object sender, EventArgs e)
{
    reColor(pictureBox2, colGradCtr1);
}

The example application

Image 6

Click "generate new noise" to test the gradients with a new noise.

Click gdi+ example to get the second example form: 

Image 7

Points of Interest

ColGradCtr is not a "wrapper" of gdi+ ColrBlend  , its a "wrapper" of the class 

C#
class Wgrad<T>

as I created it; its a "ordered" list of objects 

C#
public class gradObj<T>
{
    public T ele { get; set; }
    public float w {get;set;}
    public gradObj(T e, float p)
    {
        ele = e;
        //clamp
        if (p > 1f)
            p = 1f;
        if (p < 0f)
            p = 0f;
        w = p;
    }
}

where T in our case is Color, and w is the position in the 0..1 scale.

Follows an explanation of the data structure behind the color gradient:

Image 8

The class Wgrad<T> manages a List of obects T (in this case Color) mantaining them ordered depending on a float value that ranges between 0 and 1.

Some methods of Wgrad<T>:

public void <code>addEle</code>(T <code>ele</code> , float <code>p</code>) //Adds a Color in position p (0..1)

public gradObj<T> <code>delNearest</code>(float <code>p</code>) //Deletes the nearest Color to p (0..1)

public gradObj<T>[] <code>getEle</code>(float <code>p</code>) //Gets the 2 colors before and after p (0..1)

Finaly the noiseGen is the class i developed to manage noise functions. It contains a c# implementation of 2d Perlin Noise.

History

Added Wgrad<T> explanation.

 

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer
Italy Italy
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
PraiseGreat but Pin
User 1327559319-Nov-17 4:01
User 1327559319-Nov-17 4:01 
QuestionMy vote of 4 Pin
Kenneth Haugland21-May-15 21:12
mvaKenneth Haugland21-May-15 21:12 
AnswerRe: My vote of 4 Pin
andrea contoli3-Jun-15 4:46
andrea contoli3-Jun-15 4:46 

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.