Working with Colors
In this section we will examine color representation in GDI+ and how to use color-related functionality in real-world applications.
In GDI+, a color is represented by a 32-bit structure made up of four components: alpha (A), red (R), green (G), and blue (B), referred to as ARGB mode. Components' values range from 0 to 255. The alpha component (the first 8 bits) of the color represents transparency, which determines how a color is blended with the background. An alpha value of 0 represents a fully transparent color, and a value of 255 represents a fully opaque color; intermediate values produce results between these extremes. Real-world examples of alpha use include drawing translucent graphics shapes and images. Chapter 9 discusses the alpha component in more detail (see Section 9.6).
5.2.1 Color Spaces
It's hard for human beingsas perceptual entitiesto describe and represent colors. Color spaces provide a common frame of reference that helps represent colors. A color space contains components called color channels. For example, RGB space is a three-dimensional space with red, green, and blue color channels. To limit our discussion, we will cover the RGB (red-green-blue), HSV (hue-saturation-value), and HLS (hue-lightness-saturation) color spaces.
The RGB color space is the most commonly used namespace in computer programming because it closely matches the structure of most display hardwarewhich commonly includes separate red, green, and blue subpixel structures. It can be thought of as a cube in which length indicates the intensity of red, width indicates the intensity of green, and height indicates the intensity of blue. The corner indicated by (0, 0, 0) is black, and the opposite corner (255, 255, 255) is white. Every other color available is represented somewhere between those corners.
The HSV, sometimes called HSB (hue-saturation-brightness), and HLS color spaces can be thought of as single and double cones. The hue component represents the position on the cone as an angular measurement. The 0-, 120-, and 240-degree values of hue represent the colors red, green, and blue, respectively.
The saturation component describes the color intensity. A saturation value of 0 means gray (colorless), and the maximum value of saturation indicates pure color and brightness for the values specified by the hue and value components.
The value, or brightness, component represents the brightness of the color. A value of 0 indicates the color black (no brightness), and a maximum value indicates that the color is brightest (closest to white).
The Color structure provided by the .NET Framework library is based on the RGB color space. In Section 5.2.2 we will discuss how to use it in our applications.
5.2.2 The Color Structure
The Color structure represents ARGB colors in GDI+. This class has a static member property for almost every possible color. For example, Color.Black and Color.Red represent the colors black and red, respectively. Besides these static properties, this structure includes read-only propertiesA, R, G, and Bthat represent the alpha, red, green, and blue components, respectively.
The IsEmpty property checks whether a Color structure has been initialized (if not, there is no color). The KnownColor enumeration contains more than 300 colors, and each color is represented by its name. For example, Blue and Black members represent the colors blue and black, respectively. KnownColor also defines color combinations, such as LimeGreen and LightBlue. You can also find system colors such as ActiveBorder, ActiveCaption, Control, ControlText, Highlight, and InactiveBorder, using the IsSystemColor enumeration. The Name property represents the name of the color, which is a read-only property. The Transparent property is a static property that represents a transparent color.
The Color structure also provides some methods. The FromArgb method creates a color from the four ARGB components. This method has different overloaded forms with which an application can create a Color object from an alpha value only; from an alpha value with a Color object only; from three values (red, green, and blue); and from all four values (alpha, red, green, and blue).
The FromKnownColor and FromName methods create a Color object from a predefined color or from the name of a predefined color, respectively. The FromKnownColor method takes only one argument, of KnownColor enumeration. The FromName method takes one argument of string type as the color name. All members defined in the KnownColor enumeration are valid names for this method.
Note
All three "from" methods (FromArgb, FromKnownColor, and FromName) are static.
The ToArgb and ToKnownColor methods convert an ARGB or KnownColor value, respectively, to a Color structure.
Listing 5.1 illustrates different ways to create Color objects and use them in an application to draw various graphics objects, including a filled ellipse with a red brush, a filled rectangle with a blue brush, and a line with a green pen. The application first creates four Color objects via the FromArgb, FromName, FromKnownColor, and Empty methods. The FromArgb method creates a translucent pure red Color object, using parameters 120, 255, 0, and 0. The FromName method creates a Color object from the string "Blue". The FromKnownColor method creates a color object from the known color Green.
Listing 5.1 Using the methods and properties of the Color structure
private void ColorStructMenu_Click(object sender, System.EventArgs e) { // Create Graphics object Graphics g = this.CreateGraphics(); // Create Color object from ARGB Color redColor = Color.FromArgb(120, 255, 0, 0); // Create Color object form color name Color blueColor = Color.FromName("Blue"); // Create Color object from known color Color greenColor = Color.FromKnownColor(KnownColor.Green); // Create empty color Color tstColor = Color.Empty; // See if a color is empty if(tstColor.IsEmpty) { tstColor = Color.DarkGoldenrod; } // Create brushes and pens from colors SolidBrush redBrush = new SolidBrush(redColor); SolidBrush blueBrush = new SolidBrush(blueColor); SolidBrush greenBrush = new SolidBrush(greenColor); Pen greenPen = new Pen(greenBrush, 4); // Draw GDI+ objects g.FillEllipse(redBrush, 10, 10, 50, 50); g.FillRectangle(blueBrush, 60, 10, 50, 50); g.DrawLine(greenPen, 20, 60, 200, 60); // Check property values MessageBox.Show("Color Name :"+ blueColor.Name + ", A:"+blueColor.A.ToString() + ", R:"+blueColor.R.ToString() + ", B:"+blueColor.B.ToString() + ", G:"+blueColor.G.ToString() ); // Dispose of GDI+ objects redBrush.Dispose(); blueBrush.Dispose(); greenBrush.Dispose(); greenPen.Dispose(); g.Dispose(); }
Figure 5.1 shows the output from Listing 5.1.
Figure 5.1. Creating colors using different methods
The GetBrightness, GetHue, and GetSaturation methods return a color's brightness, hue, and saturation component values, respectively. Listing 5.2 reads the hue, saturation, and brightness components of a color and displays their values on the form by using the DrawString method.
Listing 5.2 Getting brightness, hue, and saturation of a color
private void HSBMenu_Click(object sender, System.EventArgs e) { // Create a Graphics object Graphics g = this.CreateGraphics(); // Create a color Color clr = Color.FromArgb(255, 200, 0, 100); // Get hue, saturation, and brightness components float h = clr.GetHue(); float s = clr.GetSaturation(); float v = clr.GetBrightness(); string str = "Hue: "+ h.ToString() + " " + "Saturation: "+ s.ToString() + " " + "Brightness: "+ v.ToString(); // Display data g.DrawString(str, new Font("verdana", 12), Brushes.Blue, 50, 50); // Dispose of object g.Dispose(); }
Figure 5.2 shows the output from Listing 5.2. The values of hue, saturation, and brightness in this particular color are 330, 1, and 0.3921569, respectively.
Figure 5.2. Getting brightness, hue, and saturation components of a color
5.2.3 System Colors
The SystemColors class represents the Windows system colors; it provides 26 read-only properties, each of which returns a Color object. Table 5.1 lists the properties of the SystemColors class.
The following code snippet uses the SystemColors class to set colors of a few Windows controls. In this code we set the background colors of a text box, a radio button, and a button to inactive border, active caption, and control dark system colors, respectively.
textBox1.BackColor = SystemColors.InactiveBorder; radioButton1.BackColor = SystemColors.ActiveCaption; button1.BackColor = SystemColors.ControlDarkDark;
If you're wondering whether you can create a brush or a pen from the SystemColors class to fill and draw shapes, curves, and text, the answer is, absolutely. The following code snippet uses SystemColors to create SolidBrush and Pen objects. This code creates a solid brush and a pen from active caption system and highlight text system colors, respectively.
Property |
Description |
---|---|
ActiveBorder |
Active window border color |
ActiveCaption |
Active window title bar background color |
ActiveCaptionText |
Active window title bar text color |
AppWorkspace |
Multiple-document interface (MDI) workspace background color |
Control |
Control background color |
ControlDark |
3D control shadow color |
ControlDarkDark |
3D control dark shadow color |
ControlLight |
3D control highlight color |
ControlLightLight |
3D control light highlight color |
ControlText |
Text color of controls |
Desktop |
Windows desktop color |
GrayText |
Disabled text color |
Highlight |
Highlighted text background color |
HighlightText |
Highlighted text color |
HotTrack |
Hot track color |
InactiveBorder |
Inactive window border color |
InactiveCaption |
Inactive window caption bar color |
InactiveCaptionText |
Inactive window caption bar text color |
Info |
ToolTip background color |
InfoText |
ToolTip text color |
Menu |
Menu background color |
MenuText |
Menu text color |
ScrollBar |
Background color of scroll bars |
Window |
Background color of window |
WindowFrame |
Thin window frame color |
WindowText |
Window text color |
SolidBrush brush = new SolidBrush(SystemColors.ActiveCaption); Pen pn = new Pen(SystemColors.HighlightText);
For performance reasons, GDI+ provides SystemPens and SystemBrushes classes, which should be used instead of creating a brush or pen from the SystemColors class. For example, the following method is advisable for creating system brushes and pens. This code snippet creates a solid brush and a pen from active caption and highlight text system colors, respectively.
SolidBrush brush1 = (SolidBrush)SystemBrushes.FromSystemColor (SystemColors.ActiveCaption); Pen pn1 = SystemPens.FromSystemColor (SystemColors.HighlightText);
Listing 5.3 uses the SystemBrushes and SystemPens classes to create a SolidBrush object and three Pen objects, which are used later to draw and fill graphics objects. The solid brush is created from the active caption system color, and the three pens are created from highlight text, control light light, and control dark system colors, respectively. Later the brush and pens are used to draw two lines, a rectangle, and an ellipse.
Listing 5.3 Using SystemPens and SystemBrushes
private void SystemColorsMenu_Click(object sender, System.EventArgs e) { // Create a Graphics object Graphics g = this.CreateGraphics(); // Create brushes and pens SolidBrush brush1 = (SolidBrush)SystemBrushes.FromSystemColor (SystemColors.ActiveCaption); Pen pn1 = SystemPens.FromSystemColor (SystemColors.HighlightText); Pen pn2 = SystemPens.FromSystemColor (SystemColors.ControlLightLight); Pen pn3 = SystemPens.FromSystemColor (SystemColors.ControlDarkDark); // Draw and fill graphics objects g.DrawLine(pn1, 10, 10, 10, 200); g.FillRectangle(brush1, 60, 60, 100, 100); g.DrawEllipse(pn3, 20, 20, 170, 170); g.DrawLine(pn2, 10, 10, 200, 10); // Dispose of object g.Dispose(); }
Figure 5.3 shows the output from Listing 5.3. System colors were used to draw two lines, an ellipse, and a rectangle.
Figure 5.3. Using system colors to draw graphics objects
Note
When you create pens using SystemPens, you cannot modify the width or other properties of the pen. The code will compile but will throw an unhandled exception when executed. If you create a pen using SystemColors, however, you can modify its width like this:
Pen pn = new Pen(SystemColors.HighlightText);
Pn.Width = 4;
5.2.4 The ColorConverter and ColorTranslator Classes
The ColorConverter class is used to convert colors from one data type to another. This class is inherited from the TypeConverter class, which defines the functionality for conversion of types and accessing values and properties of types. The TypeConverter class serves as a base class for many conversion classes, and ColorConverter and FontConverter are two of them. We will discuss FontConverter in more detail later in this chapter. Some of the common methods of the TypeConverter class (which are available in the ColorConverter class) are described in Table 5.2.
Method |
Description |
---|---|
CanConvertFrom |
Takes a type as a parameter and returns true if the converter can convert an object to the type of the converter; otherwise returns false. |
CanConvertTo |
Takes a type as a parameter and returns true if the converter can convert an object to a given type; otherwise returns false. |
ConvertFrom |
Converts an object to the type of the converter and returns the converted object. |
ConvertTo |
Converts a specified object to a new type and returns the object. |
GetStandardValues |
Returns a collection of standard values (collection type) for the data type for which this type converter is designed. |
GetStandardValuesSupported |
Identifies whether this object supports a standard set of values. |
Listing 5.4 uses the ColorConverter class methods to convert colors. We store a color in a string and call the ConvertFromString method, which returns the Color object. Later we will use the Color objects to create two brushes that we will use to fill a rectangle and an ellipse.
Listing 5.4 Using the ColorConverter class to convert colors
private void ColorConvert_Click(object sender, System.EventArgs e) { Graphics g = this.CreateGraphics(); g.Clear(this.BackColor); string str = "#FF00FF"; ColorConverter clrConverter = new ColorConverter(); Color clr1 = (Color)clrConverter.ConvertFromString(str); // Use colors SolidBrush clr2 = new SolidBrush(clr1); SolidBrush clr3 = new SolidBrush(clr1); // Draw GDI+ objects g.FillEllipse(clr2, 10, 10, 50, 50); g.FillRectangle(clr3, 60, 10, 50, 50); // Dispose of objects clr2.Dispose(); clr3.Dispose(); g.Dispose(); }
Figure 5.4 shows the output from Listing 5.4.
Figure 5.4. Converting colors
The ColorTranslator class provides methods to translate colors to and from HTML, OLE, and Win32 color values. These methods are useful when you're using legacy color structures that pre-date the .NET Framework. For example, you may have legacy code that gives the HTML color representation of a color. Table 5.3 describes the methods of the ColorTranslator class. All of the methods are static.
Listing 5.5 uses the ColorTranslator class to translate colors from Win32 and HTML colors. Later these colors will be used to create brushes.
Listing 5.5 Translating colors
private void ColorTranslator_Click(object sender, System.EventArgs e) { Graphics g = this.CreateGraphics(); // Translate colors Color win32Color = ColorTranslator.FromWin32(0xFF0033); Color htmlColor = ColorTranslator.FromHtml("#00AAFF"); // Use colors SolidBrush clr1 = new SolidBrush(win32Color); SolidBrush clr2 = new SolidBrush(htmlColor); // Draw GDI+ objects g.FillEllipse(clr1, 10, 10, 50, 50); g.FillRectangle(clr2, 60, 10, 50, 50); // Dispose of objects clr1.Dispose(); clr2.Dispose(); g.Dispose(); }
Method |
Description |
---|---|
FromHtml |
Translates from an HTML color representation to a Color structure. |
FromOle |
Translates from an OLE color value to a Color structure. |
FromWin32 |
Translates from a Windows color value to a Color structure. |
ToHtml |
Translates from a Color structure to an HTML color representation. |
ToOle |
Translates from a Color structure to an OLE color. |
ToWin32 |
Translates from a Color structure to a Windows color. |
In a manner similar to the "from" methods just discussed, you can translate a Color structure into Win32, HTML, and OLE values using the ToWin32, ToHtml, and ToOle methods, respectively.
Note
You can also transform colors using transformation methods. Some of the transformation methods are for scaling, translating, rotating, and shearing. We cover this functionality in Chapter 10.