Digital representation of the color using the RGB color system

Understanding color and the RGB system

Copyright © 2002 Ernesto De Spirito

Help & Manual authoring tool

Contents

LMD-Tools 6.1 - 300+ components for various development tasks!

Primary colors of the light

The light has three primary colors: red, green and blue. By combining these primary colors in different intensities we can get all visible colors.

If we represent the intensity of each primary color with a number, then we can represent colors with three numbers (one for red, one for green and one for blue). This way of representing colors with numbers for the intensity of the red, green and blue components of the light is known as the RGB color system.

The RGB color system

Assuming that we use integer numbers in the range 0..255 (one byte), i.e. 256 possible values for each primary color, then with three bytes we can represent 256 x 256 x 256 different combinations of the primary colors, i.e. more than 16 million colors (often referred as "true color"). In particular, this RGB color system is known as RGB-256.

Some programs use a system known as RGB-100, which uses numbers in the range 0..100 to indicate a percentage of intensity (0%=off; 100%=max). In the examples we are going to use RGB-256 because it's the most popular.

Shades of gray

Black is the absence of color (or the absence of light) and it is represented as RGB(0,0,0) (Red=0, Green=0, Blue=0). White is the presence of all colors (in their maximum intensity) and it is represented as RGB(255,255,255) (Red=255, Green=255, Blue=255). All shades of gray from black to white are represented with three equal values for the red, green and blue components (no color predominates), i.e. they have the form RGB(x,x,x). For example, the color defined in the jargon as "light gray" is represented as RGB(192,192,192), and "dark gray" is RGB(128,128,128).

RGB(0,0,0) = Black
RGB(128,128,128) = Dark gray
RGB(192,192,192) = Light gray
RGB(255,255,255) = White

Primary colors

Now let's get to the colors. To begin with, the primary colors are represented this way:

RBG(255,0,0) = Light red (or bright red)
RBG(0,255,0) = Light green (or bright green)
RBG(0,0,255) = Light blue (or bright blue)

Their dark versions would be:

RBG(128,0,0) = Dark red
RBG(0,128,0) = Dark green
RBG(0,0,128) = Dark blue

As you might be guessing, the different intensities of red have the form RBG(x,0,0), the ones of green have the form RGB(0,x,0) and the ones of blue are of the form RGB(0,0,x).

Secondary colors

The secondary colors of the light are cyan, magenta and yellow, and they result from the combination of different pairs of the primary colors in equal intensities. For example, their bright versions would be:

RBG(0,255,255) = Light cyan = light green + light blue
RBG(255,0,255) = Light magenta = light red + light blue
RBG(255,255,0) = Light yellow = light red + light green

The dark versions of the secondary colors would be:

RBG(0,128,128) = Dark cyan = dark green + dark blue
RBG(128,0,128) = Dark magenta = dark red + dark blue
RBG(128,128,0) = Dark yellow = dark red + dark green

As you can see, the different intensities of cyan are of the form RBG(0,x,x), the ones of magenta have the form RGB(x,0,x) and the ones of yellow are of the form RGB(x,x,0).

Other colors

How can we make other colors? Let's take orange for example. As you probably know, light orange is a color between light red and light yellow, i.e., between RGB(255,0,0) and RGB(255,255,0), and this means light orange is RGB(255,128,0). How did I get this value? Simply by taking the average of the color components of light red and light yellow:

           Light red   Light yellow
  Red   = (   255    +     255     ) / 2 = 255
  Green = (    0     +     255     ) / 2 = 128
  Blue  = (    0     +      0      ) / 2 = 0
RGB(255,0,0) = Light red
RBG(255,128,0) = Light orange
RBG(255,255,0) = Light yellow

Different intensities of orange have the form RGB(x,x/2,0).

Pure colors

Pure colors combine only two primary colors and have the form RGB(x,y,0), RGB(y,x,0), RGB(0,x,y), RGB(0,y,x), RGB(x,y,0) or RGB(y,x,0) where x <> 0 and x >= y:

  • When y = 0, we have a primary color.
  • When x = y, we have a secondary color.
  • When y = x/2 we have a color exactly between a primary color and a secondary color. For example RGB(255,128,0) is an orange exactly between red and yellow.
  • When y < x/2 we have a color closer to a primary color than a secondary color. For example RGB(255,116,0) is an orange closer to to red than to yellow.
  • When y > x/2 we have a color closer to a secondary color than a secondary color. For example, RGB(255,140,0) is an orange closer to yellow than to red.

Hue and luminosity

Colors of the same form that have the same relationship x/y are said to have the same "hue". For example RBG(255,128,0) and RGB(192,96,0) are of the same form (RGB(x,y,0)) and they have the same relationship x/y (255/128 = 192/96), so they have the same hue. The "hue" is what we incorrectly often refer as "color". For example, in this case the hue of both colors is "orange", but one is a light orange, and the other is a darker orange, i.e., they have the same "hue", but they differ on the "luminosity". The luminosity measures how near a color is from white, and is usually represented as a percentage. For example, RGB(192,96,0) is an orange with a luminosity of 75% and RBG(128,64,0) is an orange with a 50% luminosity.

RBG(255,128,0) = Orange 100% luminosity
RGB(192,96,0) = Orange 75% luminosity
RBG(128,64,0) = Orange 50% luminosity

The hue of RBG(0,0,128) and RGB(0,0,64) is blue, but the second color has 50% of the luminosity of the first one (they have a luminosity of 50% and 25% respectively).

Saturation

Apart from hue and luminosity, colors are defined by a third parameter that is known as "saturation", which measures the purity of the color. So far we've dealt with 100% pure colors. Impure colors are pure colors mixed with gray. The less mixed with gray, the more saturated. For example, RGB(192,128,64) has the same hue and luminosity of light orange RGB(255,128,0), but 50% saturation, and results from mixing light orange with medium gray RGB(128,128,128):

           orange   gray
  Red   = (  255  + 128 ) / 2 = 192
  Green = (  128  + 128 ) / 2 = 128
  Blue  = (   0   + 128 ) / 2 = 64

If we mix the result with medium gray again, we would have an orange with 25% saturation RGB(160,128,96), even closer to medium gray. If we mix it with gray again, we get an orange with just 12,5% saturation RGB(144,128,112), almost a medium gray.

RBG(255,128,0) = Light Orange 100% saturation
RGB(192,128,64) = Light Orange 50% saturation
RGB(160,128,96) = Light Orange 25% saturation
RGB(144,128,112) = Light Orange 12,5% saturation
RGB(128,128,128) = Medium Gray

Notice that a color is more saturated when the difference between the RGB values is bigger. When the RGB values are close from each other, the color is less saturated (i.e., it's more "grayish", or we can say it's less "live", "vivid" or "pure").

The saturation can be calculated with the following formula:

  Saturation = ((maximum-medium) + (medium-minimum)) / 255 * 100%

For example:

  Saturation(160,128,96) = ((160-128) + (128-96)) / 255 * 100%
                         = (32 + 32) / 255 * 100%
                         = 64 / 255 * 100%
  Saturation(160,128,96) = 25%

Integer representation

The three bytes that represent a color can be combined in a 32-bit integer constant, normally represented in hexadecimal notation. For example, RGB(160,128,96) is 6080A0:

  Red   (RR) = 160 dec = A0 hex
  Green (GG) = 128 dec = 80 hex
  Blue  (BB) =  96 dec = 60 hex

Notice that color constants have the form BBGGRR (not RRGGBB), where BB is the byte (two hexadecimal digits) for blue, GG is the byte for green and RR is the byte for red. The reason is that integers are internally stored with the least significant byte first, so BBGGRR gets stored as RRGGBB, the order in which the RGB values are expected (for example 6080A0 is internally stored as A08060).

In Visual Basic, RGB(160,128,96) is represented as &H6080A0&, in C/C++ it's 0x6080A0 and in Delphi it's $6080A0.

Adding color to your applications

Using Windows system colors guarantees the user can adjust the colors of your application to those he/she can see (your application will simply use the colors set in the Control Panel). Consider this fact before thinking of using your own colors. By the way, you can find some useful guidelines about the use of colors in the MSDN Library:

 http://msdn.microsoft.com/library/en-us/dnwue/html/ch14b.asp

Okay, sometimes we want our application to have a little touch of color, but on the other hand we don't want it to look like a circus. The secret is limiting to just a bunch of colors, being consistent, and choosing very impure colors with little contrast between adjacent backgrounds (and high contrasts between the letters and the backgrounds).

For example, for the background of your buttons you can use a color like RGB(192,192,200), which is like the original light gray, but with a little blue. Remember that when you don't use a system color for the background of an element, you should not use a system color for the foreground. For example, you probably see that the caption is black, which contrasts very well against the light blue-gray background you set, but this might not be the case in the user's PC. What if the user has set in the Control Panel light letters over a dark background for the colors of the buttons? In your application, the result would be light letters (user setting) over a light background (your setting). For this reason, you should explicitly set the caption color to ensure the caption will contrast fine against the background. In this case, RGB(0,0,0) -black- would be the best choice.

You can group different elements of your form in panels, and set the background color of these panels, for example to RGB(192,200,200), a light gray with a little cyan. If you want it a little more green, you can set it for example to RGB(192,202,199), and if you want it a little more blue, you can set it to RGB(192,199,202). Remember to explicitly set the color of the captions of the labels that you have over these panels to a color that highly contrasts with the background (typically black).

If you want more color, you can set the background color of textboxes to a luminous color like RGB(255,255,239), an unsaturated light yellow, and set the color of the text to a very dark color (usually black).

RGB(192,192,200) = light gray with a little blue
RGB(192,200,200) = light gray with a little cyan
RGB(192,203,198) = idem, more greenish
RGB(192,198,203) = idem, more bluish
RGB(255,255,239) = an unsaturated light yellow

If you want something radically different, instead of the standard light gray RGB(192,192,192) for the background of your form, you can set a much brighter color, like RGB(245,245,255), a very luminous and unsaturated light blue, almost white. This would allow you to use not-so-dark colors for some labels (typically in bold face), like for example dark cyan RGB(0,80,80), etc., while keeping a good contrast. Instead of a color like RGB(192,200,200) for a panel, you should now use a color like RGB(248,242,255) so the background of of the panel doesn't contrast very much with the background of the form, and for the buttons you can use a color like RGB(232,242,255) for the same reason.

RGB(192,192,192) = Light gray
RGB(245,245,255) = Brighter gray with a little blue
RGB(248,242,255)
RGB(232,242,255)

With these little touches of color and some graphics as decorations, your application will have a different look.

Safety palette

The safety palette is used to ensure colors are "solid" (not "dithered") in video cards and monitors capable of just 256 colors. If you want your application to look well on these devices, you should use the safety palette.

The safety palette is made up of 216 colors that result from all the possible combinations of the values 0, 51, 102, 153, 204, and 255 (or $00, $33, $66, $99, $CC, and $FF in hex notation) for the red, green and blue components. For example, the color RGB(204,153,102) or $6699CC is one of the safe colors.

                                         
                                         
                                         
                                         
                                         
                                         

The safety palette leaves 40 colors unused (256 - 216 = 40). Windows reserves 20 system colors, leaving you other 20 colors that you could use in your application, but you should be aware that these 20 colors might change when the user switches to another application, so it's recommended that you don't use them.
 

JfControls Library - for Delphi and C++ Builder

This article was first published in our Developers Newsletter, now discontinued.