Color Range  Lab Report
Create Image by Including/Excluding Range of R, G, B, H, S, V values
Shown above are the pixels from a tulip image that have 10 <= Hue <= 60 and 128 <= Value <= 255

The purpose of this program is to show how to include (or exclude) a color cube of RGB values, or a range of HSV values, from an image.

When working with a picture of a real-world object, changing one color to another might seem like a trivial bitmap manipulation.  But a single image can have thousands of colors (unique RGB triples).  For example, the original tulip picture above has over 42,000 colors in it, with the "yellow" part (shown above) of the tulip containing over 26,000 colors!

Instead of selecting a single R-G-B triple, often a small color cube with a range of R-G-B values must be selected for change.  In addition to working with RGB color space, other color spaces, such as HSV (Hue-Saturation-Value), are useful.

With HSV color space, a Hue of 0 degrees is red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue and 300 degrees is magenta.  Saturation and Value range from 0 to 255.  The "dark yellow" pixels are rejected above by only selecting "Values" above 128.

Materials and Equipment

Software Requirements
Windows 95/98/NT
Delphi 3/4  (to recompile)
Test Images:  Tulip1, Mandrill or Parrots BMPs

Hardware Requirements
1024-by-768 display in High Color or True Color Mode


  1. Double click on the ColorRange.Exe icon to start the program.
  2. Press the Load button and select a sample bitmap such as Tulip1.BMP.   (BMPs or JPGs can be used.)
  3. If the image is smaller than, or larger than, the 640-by-480 area on the screen, select the Stretch Checkbox so the image fills the area.
  4. Move the cursor over the image to observe the R, G, B or H, S, V values.
  5. Select ranges of R, G, B, H, S, V by first selecting the corresponding Checkbox and then using the SpinEdit boxes to specify minimum and maximum values.   (Note:  Hue minimum values can be negative.  For example a Hue range from -20 to +20 can be specified for a broader range of "red" colors.)
  6. Select the Exclude Color by clicking on the  TShape area and selecting a color from the TColorDialog
  7. Select the Include or Exclude radio button, if desired.
  8. After the R, G, B, H, S and V ranges and the Exclude Color have been specified, click on the Update button to see the resulting image. 
  9. If desired, save the resulting image by pressing the Save Button.

Compare the Tulip image shown above with the one from specifying only a range of Red from 125-255.  The two images are very similar.  Since Yellow = Red + Green, a high value of red alone is fairly useful here.

Experiment with the "famous" Mandrill monkey picture.  In particular, the "red" nose can be extracted with Hue from -20 - +20 and Value from 200-255.  The "blue" cheeks can be extracted with Hue from 190-280 and Value from 128-255.

ScreenColorRangeMandrillNose.jpg (16087 bytes) ScreenColorRangeMandrillCheeks.jpg (22781 bytes)

At present ColorRange only loads BMP or JPG files. With some minor changes, WMF and EMF files could also be loaded.  For GIF support you will need a GIF component such as TGIFImage from Anders Melander.  Change the conditional compilation value to GIF and extend the file types allowed by OpenPictureDialog's filter.

A ColorRange.INI file "remembers" the last directory used by this program.

Instead of using a TImage, FormCreate creates a TSensitiveImage object using Bevel1 to define its size and position.  The main feature of TSensitiveImage is that it "knows" when a cursor is over it (based on cm_MouseEnter and   cm_MouseLeave events) so the spatial coordinates and RGB and HSV values can be displayed.  TSensitiveImage can also blank these values automatically when a cm_MouseLeave event occurs.

The use of TSensitiveImage was an experiment to avoid the use of a slightly modified VCL component that required being installed on the component palette.   Adding countless components to the component palette, and keeping them configured the same way on multiple machines, seems to be a poor design and practice from a software engineering standpoint.  However, as this experiment with TSensitiveImage showed, modifying an existing VCL component programmatically doesn't seem to be a good practice either.  Extending an existing VCL object for a one-time special purpose shouldn't clutter the component palette, yet there doesn't seem to be good alternatives at present.

Changing a "single color" in an image of a real-world object usually doesn't make any sense.  A range of values must be changed, which can be represented by a small color "cube" (or box) in RGB space, or a range of HSV values.

RGB, HSV, TSensitiveImage (modified TImage), cm_MouseEnter, cm_MouseLeave, LoadGraphicsFile (loads BMP, JPG, WMF, EMF, or GIF), TColorDialog, TOpenPictureDialog, TSavePictureDialog, TIniFile, RGBTripleToHSV, TBevel

Delphi 3/4 Source and EXE (219 KB): ColorRange.ZIP
(D3 EXE is 368 KB, D4 EXE is 466 KB)

24-bit color BMP test images:
Mandrill.ZIP (737 KB)
Parrots.ZIP (200 KB)

Updated 26 Feb 2005

since 8 Nov 1998