The purpose of this program is to select and display colors either by specifying Red-Green-Blue or Hue-Saturation-Value quantities.
Materials and Equipment
Delphi 3 or 4 (to recompile)
Best when run on 800 x 600 pixel (or higher) monitor in high color or true color display mode.
There are a number of color spaces in addition to the Red-Green-Blue (RGB) color space. One non-RGB color space that is often used in computer graphics is the Hue-Saturation-Value (HSV) color space. [For information about other color spaces, look for "Color Conversion" and "Color Spaces, Color Models" on efg's Color page.]
Here's a diagram of HSV color space:
In HSV color space, Hue is measured by an angle with Red starting at 0 degrees, Green at 120 degrees and Blue at 240 degrees. Complementary colors are in-between: Yellow is at 60 degrees, Cyan is at 180 degrees, and Magenta is at 300 degrees. The black line in the diagram at the lower left on the screen shows the hue angle.
Saturation, S, is a ratio that ranges from 0.0 along the center line of the cone (the V axis) to 1 on the edge of the cone. The gray circle above in the diagram at the lower left of the screen shows the position of the saturation value. The colors along this saturation circle are shown in the color box above the hue trackbar. The colors along the saturation radius are shown in the color box above the saturation trackbar.
Value, V, ranges from 0.0 (dark) to 1.0 (bright).
Pure Red is at H= 0, S=1, V=1.
Shades of gray all have S=0, with various values of V from 0.0 (black) to 1.0 (white). For S = 0, Hue is undefined.
When R, G, and B as well as S and V are defined over the range 0.0 to 1.0, these values are often represented in 8 bits with an integer value ranging from 0 to 255.
Foley, et al, in Computer Graphics Principles and Practice (Amazon link) [pages 590-593] describe the HSV color model as a single hexcone (versus the double-hexcone of the Hue-Lightness-Saturation color model). While the text describes the space as a hexcone, the color plates (II.7 and II.8) show a circular cone.
The RGB/HSV conversions are in the HSVLibrary unit. There are two sets of conversion routines. When only a one-way conversion is needed from HSV to RGB, and the result is to be a TRGBTriple, the function HSVtoRGBTriple can be used. For a one-way conversion from a RGBTriple back to HSV quantities, use the RGBTripletoHSV. These are "one-way" routines since the converted values are treated as integers. See the actual code for implementation of these routines.
The RGBtoHSV and HSVtoRGB routines can be used when "reversible" conversions are needed. Sometimes conversion from RGB to HSV is needed for some sort of HSV manipulation. When complete, the HSV values must be converted back to RGB. If floating-point values are not used to represent the converted values, integer truncation is not always desirable.
The "general" conversion routines are shown below (see the actual code for complete details):
Math, // MaxValue
IEEE754, // NaN, IsNaN
SysUtils; // Exception
EColorError = CLASS(Exception);
TReal = DOUBLE;
// RGB, each 0 to 255, to HSV.
|// Based on C Code in "Computer Graphics -- Principles
// Foley et al, 1996, p. 593.
// H = 0.0 to 360.0 (corresponding to 0..360 degrees around hexcone)
// NaN (undefined) for S = 0
// S = 0.0 (shade of gray) to 1.0 (pure color)
// V = 0.0 (black) to 1.0 (white)
PROCEDURE HSVtoRGB (CONST H,S,V: TReal; VAR R,G,B: TReal);
f : TReal;
i : INTEGER;
hTemp: TReal; // since H is CONST parameter
IF S = 0.0 // color is on black-and-white center line
R := V; // achromatic: shades of gray
G := V;
B := V
ELSE RAISE EColorError.Create('HSVtoRGB: S = 0 and H has a value');
ELSE BEGIN // chromatic color
IF H = 360.0 // 360 degrees same as 0 degrees
THEN hTemp := 0.0
ELSE hTemp := H;
hTemp := hTemp / 60; // h is now IN [0,6)
i := TRUNC(hTemp); // largest integer <= h
f := hTemp - i; // fractional part of h
p := V * (1.0 - S);
q := V * (1.0 - (S * f));
t := V * (1.0 - (S * (1.0 - f)));
CASE i OF
0: BEGIN R := V; G := t; B := p END;
1: BEGIN R := q; G := V; B := p END;
2: BEGIN R := p; G := V; B := t END;
3: BEGIN R := p; G := q; B := V END;
4: BEGIN R := t; G := p; B := V END;
5: BEGIN R := V; G := p; B := q END
The behavior of TTrackbars changed in a subtle way between Delphi 3 and Delphi 4. In the original Delphi 3 version of this program, the position of trackbars was changed in code. For example, any change in R,G,B values often required changes in all three of the H, S, V TTrackbars. This was done in a straightforward way in Delphi 3. Setting the TTrackBar.Position did not trigger an OnChange event. BUT in Delphi 4, OnChange events are triggered and without the existing "kludge" in the code, setting the position of one of the RGB TTrackBars triggered the OnChange in the HSV TTrackBars, which triggered an OnChange in the RGB TTrackBars, and so on. I am not sure whether this is a Delphi 4 bug or feature -- I'll wait and see what happens in Delphi 5.
The CreateHueSaturationCircle in the HSVLibrary unit can be used to create a TBitmap that contains a Hue-Saturation circle of any size.
The UpdateHueSaturationfromMouse routine is used to respond to mouse click (or
mouse down followed by mouse move) events.
The Range radio box can be used to change the format of how values are displayed. This can either be the range 0 to 255, or the range 0.0 to 1.0 -- except for Hue values that are always 0 to 360 degrees.
HSV is an interesting alternative color space that is very useful in a variety of problems.
For example, see efg's Color Range Lab Report for how to extract the "yellow" part of a tulip image using Hue and Value.
RGB, HSV, Color Space, ArcTan2, TTrackBar, CreateHSVGradient, CreateRGBGradient, CreateHueSaturationCircle, IsPaletteDevice, High Color, True Color, NaN, IsNan, IEEE754, MouseDown, MouseMove, ShellExecute, pRGBTripleArray, Scanline, EColorError, RGBtoHSV, HSVtoRGB, RGBtoRGBTriple, HSVtoRGBTriple, RGBTripleToHSV
Delphi 3 Source Only (136 KB): HSV.ZIP
Thanks, Alexei, for contributing your Color Chooser
Using a background thread to compute and display a Mandelbrot set using HSVcolor scheme, Delphi in a Nutshell, pp. 148-151
Adventures in HSV Space - July, 2001 - A detailed paper on when and how to use the Hue, Saturation, and Value color space. It includes C code for converting RGB values to and from HSV Space. It is in PDF format.
Updated 26 Feb 2005
since 5 Jul 1999