65.9K
CodeProject is changing. Read more.
Home

Create Custom Color Maps in C#

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.39/5 (12 votes)

Mar 26, 2007

7 min read

viewsIcon

114063

downloadIcon

2276

This article shows how to create various custom color maps

Introduction

In C#, there is a default ColorMap class, defined in the System.Drawing.Imaging namespace. This class defines a mapping between existing colors and the new colors to which they are to be converted. When the map is applied, any pixel of the old color is converted to the new color. This class is useful for image processing applications.

However, in some graphics and chart applications, you may need the custom color maps to achieve specific visual effects. These color maps are simply tables or lists of colors that are organized in some desired fashion. The surface, patch, and image objects can be associated with a custom color map. This article shows you how to create such custom color maps.

Background

To create a custome color map in C#, you need to construct a color map with an m x 4 color map matrix. Each row of this matrix represents ARGB values. The row index can represent the y data of a 2D chart or the height (the z data) of a 3D surface plot. For a given color map matrix with m rows, the color data values can be linearly scaled to the color map.

For example, if you want to use the color map to represent the y coordinates of a 2D graphics object, you can use the YMin and YMax to linearly transform the y data values to indices where each index identifies an ARGB row (i.e., a color) in the color map matrix. The mathematical transformation of the color index values is described by the formula:

<formulas /></formulas />

Here y is the individual value of Y data and m is the length of the color map matrix. This allows you to use the entire range of colors in the color map over the plotted data. For 3D graphics objects and 3D surface charts, the y data should be replaced with the z data.

Now we can implement the colormap matrix class. Let's use a custom colormap named "Spring" as an example to illustrate how easily it is to create a custom colormap.

using System;

using System.Drawing;

using System.Drawing.Drawing2D;

namespace Example1_8

{

public class ColorMap

{

private int colormapLength = 64;

private int alphaValue = 255;

public ColorMap()

{

}

public ColorMap(int colorLength)

{

colormapLength = colorLength;

}

public ColorMap(int colorLength, int alpha)

{

colormapLength = colorLength;

alphaValue = alpha;

}

public int[,] Spring()

{

int[,] cmap = new int[colormapLength, 4];

float[] spring = new float[colormapLength];

for (int i = 0; i < colormapLength; i++)

{

spring[i] = 1.0f * i / (colormapLength - 1);

cmap[i, 0] = alphaValue;

cmap[i, 1] = 255;

cmap[i, 2] = (int)(255 * spring[i]);

cmap[i, 3] = 255 - cmap[i, 1];

}

return cmap;

}

......

}

}

In this class, there are three constructors. If you use

ColorMap cm = new ColorMap();

to create a new ColorMap object, the default parameters colormapLength = 64 and alphaValue = 255 will be used. Here colormapLength is the length of the color map matrix and the alphaValue is the color transparency parameter. The default alphaValue of 255 represents an opaque color. The following constructor

ColorMap cm = new ColorMap(32);

overrides the colormapLength with the input parameter 32, and the alphaValue remains the default value of 255. You can override both parameters by calling the ColorMap class with the following code snippet:

COlorMap cm = new ColorMap(32, 100);

This sets colormapLength = 32 and alphaValue = 100.

I have add eight commonly used custom colormaps to the ColorMap class. You can easily add more custom colormaps following the procedure described here.

<h2>Using the code</h2>

The ColorMap class can be used in your C# applications. The follwoing Form1 class demonstrate how to draw various color bars using the ColorMap class. Here is the code snippet of the Form1 class:

using System;

using System.Drawing;

using System.Windows.Forms;

namespace Example1_8

{

public partial class Form1 : Form

{

public Form1()

{

InitializeComponent();

SetStyle(ControlStyles.ResizeRedraw, true);

This.BackColor = Color.White;

this.Width = 340;

this.Height = 340;

}

protected override void OnPaint(PaintEventArgs e)

{

Graphics g = e.Graphics;

int width = 30;

int height = 128;

int y = 10;

// Create opaque color maps with alpha = 255:

ColorMap cm = new ColorMap();

Font aFont = new Font("Arial", 20, FontStyle.Bold);

g.DrawString("OPAQUE COLOR", aFont, Brushes.Black, 10, 60);

DrawColorBar(g, 10, y, width, height, cm, "Spring");

DrawColorBar(g, 10 + 40, y, width, height, cm, "Summer");

DrawColorBar(g, 10 + 2 * 40, y, width, height, cm, "Autumn");

DrawColorBar(g, 10 + 3 * 40, y, width, height, cm, "Winter");

DrawColorBar(g, 10 + 4 * 40, y, width, height, cm, "Jet");

DrawColorBar(g, 10 + 5 * 40, y, width, height, cm, "Gray");

DrawColorBar(g, 10 + 6 * 40, y, width, height, cm, "Hot");

DrawColorBar(g, 10 + 7 * 40, y, width, height, cm, "Cool");

y = y + 150;

// Create transparent color maps with alpha = 150:

ColorMap cm1 = new ColorMap(64, 150);

g.DrawString("TRANSPARENT COLOR", aFont, Brushes.Black, 10, 210);

DrawColorBar(g, 10, y, width, height, cm1, "Spring");

DrawColorBar(g, 10 + 40, y, width, height, cm1, "Summer");

DrawColorBar(g, 10 + 2 * 40, y, width, height, cm1, "Autumn");

DrawColorBar(g, 10 + 3 * 40, y, width, height, cm1, "Winter");

DrawColorBar(g, 10 + 4 * 40, y, width, height, cm1, "Jet");

DrawColorBar(g, 10 + 5 * 40, y, width, height, cm1, "Gray");

DrawColorBar(g, 10 + 6 * 40, y, width, height, cm1, "Hot");

DrawColorBar(g, 10 + 7 * 40, y, width, height, cm1, "Cool");

}

private void DrawColorBar(Graphics g, int x, int y,

int width, int height, ColorMap map, string str)

{

int[,] cmap = new int[64, 4];

switch(str)

{

case "Jet":

cmap = map.Jet();

break;

case "Hot":

cmap = map.Hot();

break;

case "Gray":

cmap = map.Gray();

break;

case "Cool":

cmap = map.Cool();

break;

case "Summer":

cmap = map.Summer();

break;

case "Autumn":

cmap = map.Autumn();

break;

case "Spring":

cmap = map.Spring();

break;

case "Winter":

cmap = map.Winter();

break;

}

int ymin = 0;

int ymax = 32;

int dy = height / (ymax - ymin);

int m = 64;

for (int i = 0; i < 32; i++)

{

int colorIndex = (int)((i - ymin) *

m / (ymax - ymin));

SolidBrush aBrush = new SolidBrush(Color.FromArgb(

cmap[colorIndex, 0], cmap[colorIndex, 1],

cmap[colorIndex, 2], cmap[colorIndex, 3]));

g.FillRectangle(aBrush, x, y + i * dy, width, dy);

}

}

}

}

Inside the DrawColorBar method, we draw a color bar by dividing it into 32 sub-rectangles. We thenassign the y data from 0 to 31. The switch statement selects a specified color map matrix. The following code snippet

int colorIndex = (int)((i - ymin) * m / (ymax - ymin));

computes the index of the color map matrix using the Y data. Then we create a SolidBrush object using this color map matrix.

Inside the OnPaint method, we create two ColorMap objects, cm and cm1. cm uses the default parameters: colormapLength = 64 and alphaValue = 255; i.e. the opaque color. The parameters of cm1 are reassigned to colormapLength = 64 and alphaValue = 150, indicating that the color becomes transparent.

This project produces the output shown in the following screenshot, which shows eight different color maps defined in the ColorMap class.

This project is from the examples of the new book "Practical C# Charts and Graphics", where you can find more advanced chart and graphics programming for real-world .NET applications. For more information, please visit my website at www.authors.unicadpublish.com/~jack_xu

<h2>About the Author</h2>

Dr. Jack Xu has a Ph.D in theoretical physics. He has over 15 years programming experience in Basic, Fortran, C, C++, Matlab, and C#, specializing in numerical computation methods, algorithms, physical modeling, computer-aided design (CAD) development, graphics user interface, and 3D graphics. Currently, he is responsible for developing commercial CAD tools based on Microsoft .NET framework.

Please read my other articles:

"Draw US Flag using C# and GDI+"

"Create a Custom Color Shading in C#"

"Spherical Coordinates in C#"