Delphi Graphics: Algorithms
A. General Graphics B. Color C. Image Processing D. Mathematics/Geometry

Summary of Delphi Color Resources in article Delphi Coloring Pages.
Also see Color Reference Library.


AmazonTechnical.gif (2495 bytes)  in   look for 

Delphi Graphics
Delphi
Graphics
Color
Image Processing


1-bit color g.gif (983 bytes)  efg's Single-Bit Bitmaps Lab Report
Achromatic and Colored Light [Foley96, Chapter 13, pp. 563-604]
Additive/Subtractive Colors ColorMix.gif (1372 bytes) efg's Color Mix Lab Report
Alpha Blending

Alpha Blending
www.optimalcode.com/exalpha.zip 

IA graphics library, optimized for very fast 32-bit bitmap handling, including alpha blending and antialiasing.
http://delphi.icm.edu.pl/ftp/d50free/g32_09.zip

BMP to TXT Example of how to convert BMP file to a TXT file of RGB values, and how to convert such a TXT file to RGB values in a TBitmap for display.
Brush Styles See Brush Styles on Delphi Graphics VCL/RTL page

CIE Chromaticity Diagram [Foley96, pp. 579-584, Plate II.1-II.2]

Chromaticity.gif (2862 bytes)  efg's Chromaticity Lab Report

Changing Brightness of Pixel D6/D7 GraphUtil:
function ColorAdjustLuma(clrRGB: TColor; n: Integer; fScale: BOOL): TColor;

Also see Brightness on Image Processing page

Changing Color in Image Pablo Pedrocca's UseNet Post about how to make an image more blue

Bob Villiers' UseNet Post about how to change a single color in a pallete

Dean Verhoeven's E-mail about using SetDIBColorTable to alter palette of pf8bit bitmap

Ed Harmon's UseNet Post:
MyBitmap.Handle := CreateMappedBitmap(MyBitmap.Handle, [clLime], [NewColor]);

Damon Chandler's (TeamB) UseNet Post about changing palette entry in pf8bit bmp

ColorRange.gif (1115 bytes) efg's Color Range Lab Report:
Select or exclude range of colors in an image and replace with specified color.

// Change one color to another
// Use this only for small bitmaps, or to avoid working with palettes
procedure TForm1.Button1Click(Sender: TObject);
  VAR
  Bitmap: TBitmap;
  i,j   : INTEGER;
begin 
  Bitmap := TBitmap.Create;
  TRY
    Bitmap.LoadFromFile('C:\Program Files\Borland\Delphi 3\Images\Buttons\Alarm.BMP');
    // Change "red" part of alarm to "blue"
    FOR j := 0 TO Bitmap.Height-1 DO
    BEGIN
      FOR i := 0 TO Bitmap.Width-1 DO
      BEGIN
        IF   Bitmap.Canvas.Pixels[i,j] = clRed
        THEN Bitmap.Canvas.Pixels[i,j] := clBlue
      END
    END;
    Bitmap.SaveToFile('C:\Temp\BlueAlarm.BMP');
    Image2.Picture.Graphic := Bitmap
  FINALLY
    Bitmap.Free
  END;
end;
Changing Color of Tab in PageControl Peter Below's UseNet Post:  "You have to draw the tab yourself in this case, using the OnDrawtab event.
Set the controls OwnerDraw property to true to get the event to fire."
CMYK see CMYK on VCL/RTL page
Color Charts ColorChart.gif (1060 bytes) efg's Color Charts Lab Report
Color Depth When converting each 5-bit color component in a pf15bit bitmap to an 8-bit color component in a pf24bit bitmap, what happens with the "extra" 3 bits?  See efg's UseNet Post about this.
Color Gradients Yaron Gur's E-mail with procedures to fill a vertical and horizontal gradient within a TBitmap

cworn's UseNet Post with TGradient class and assembly code in the GetColorBetween function

Jean-Yves QuÚinec's demo program showing gradient examples  (TBitmap, TImage, TPaintBox)
degrad.zip

Peter S÷derman's UseNet Post with example of using GradientFill API call

256-Color Mode:  Since in 256-color video mode many video adapters use 18 bits/pixel, there are only 6 bits of red, green, and blue.  (See COLORRES under GetDeviceCaps for the actual value).  With only 6-bits of R, G, and B, only 64 distinct shades are possible.  That is, 64 shades of gray are possible.  Likewise, 64 shades of red are possible, etc.

Gradient Fill
www.openinfo.se/martin/texterdelphi/gradientfillex.htm

Ray Lischner's "Palettes Made Plain:  Demystifying Microsoft Windows Palettes" shows gradient palette and palette animation demo, Delphi Informant, July 1998.

GradBtn.  Button that can have a gradient fill.
www.users.uswest.net/~sharman1/gradbutt.zip

HarmGradient.  A TGraphicControl descendent.
www.users.uswest.net/~sharman1/HarmGradient.zip

"Creating a gradient fill background," pp. 329-333
Delphi Programming Problem Solver, Neil Rubenking

Gradient Panel
www.geocities.com/SiliconValley/Grid/3989/gradientpnl.htm

Create any combination of R, G, B color gradients in efg's Palette Lab or Scanline Tech Note

See gradients used in Lyapunov and Fractals Show2 Lab Reports

Also see "Spectrum/Rainbow".

Color Inverse See Invert Colors
Color Management

lcms implements fast transforms between ICC profiles.
For win95/98/2000/NT.   A wide subset of the ICC International color consortium profile format is supported. The use of ICC profiles enables developers to access the inmense quantity of existing profiles. lcms is free and source code is also provided. This package contains source code, documentation, testbed and profile checking utility.  www.littlecms.com 

Sample lcms application by Armindo Da Silva

Color Picker VCL Component TColorDialog on Dialogs palette

Here's how to use the MouseDown event of a TShape to define the TColorPicker brush color:

procedure TFormFractalsShow2.ShapeColorMouseDown(Sender: TObject;
  Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
  IF   ColorDialog.Execute
  THEN (Sender AS TShape).Brush.Color := ColorDialog.Color;
  UpdateColorScheme
end;

Mike Lischke's TColorPickerButton is a special speed button which can be used  to let the user select a specific color. The control does not  use the standard Windows color dialog, but uses a popup window   very similar to the one in Office97, which has been improved a  lot to support the task of picking one color out of millions.  
http://delphi.icm.edu.pl/ftp/d40free/colorpb.zip
www.lischke-online.de/Controls.html 

Color Cop v4.0 converts RGB decimal values to RGB Hexadecimal Triplets. It has a built in color picker, color preview, auto copy to clipboard, and an eyedropper to choose colors anywhere on the screen. Color Cop can make text and background colors very easy to manipulate in HTML documents. It now has support for Delphi Hex codes.  
www.datastic.com/tools/colorcop.html 

HueSaturationByValue.gif (5695 bytes)  HSV (see Alexei Puzikov's HSV/RGB Color Chooser Project)

Color Property Fingerpainting -- Building a Custom Color Property Editor, Robert Vivrette, Delphi Informant, Nov 1996, pp. 26-35
Color Reduction, Color Quantization

Color reduction techniques for graphics (FAQ972D)

Demonstrate the different color reduction options that can be used when converting images with more than 256 colors to GIFs, www.melander.dk/delphi/gifimage;
Anders Melander's UseNet Post about 24-bit bitmap to 256-color GIF;

Displaying a 24 bit True Color bitmap image on a 256 color display (FAQ 996D) by Joe Hecht

Harm's UseNet Post with ConvertAndSave8BitBitmap

Create8bitFrom 24bitBitmap in Robert Ro▀mair's UseNet Post

Phil McRevis' UseNet Post with suggestion on best approach to reduce 24-bit pixels to 15-/16-bit pixels using Floyd-Steinberg dithering

parrots.gif (3545 bytes)See the Gervautz-Purgathofer Octree Color Quantization algorithm adapted from October 1997 Microsoft Systems Journal in efg's ShowDemoOne and ShowDemoMany Lab Reports.   (These projects only display pf24bit bitmaps in 256 color mode -- they do not convert a bitmap to pf8bit PixelFormat.)

efg's UseNet Post about converting 256-color bitmap to pf1bit 

Color Spaces, Conversions RGB and HSL Colour Models by Grahame Marsh
www.undu.com/DN971201/00000019.htm

Collection of color utility routines

  • RGB/HLS-conversion, both integer and floating-point unctions (RGB = red, green, blue; HLS = hue, luminance, saturation);
  • Windows controls: compute 3D-color shades (highlight, shadow) for a given face color;
  • get / set DIB color table of a TBitmap object, map specified bitmap colors to other colors (Delphi 3 and above only);
  • Gamma correction; you need the Math unit

http://home.t-online.de/home/Robert.Rossmair/#rrColors

[Foley96, pp. 585-587, Plate II.4]

Gernot Hoffmann Color Order Systems RGB, HLS, HSB
www.fho-emden.de/~hoffmann/hlscone03052001.pdf 

HLS:
- [Foley96, pp. 592-595, Plate II.9]
- Colors (HLS), http://digilander.iol.it/gensavas/francosava/grafica/docs/c_grafica3/i_coloriHLS_English.htm 

HSL
Colin Wilson's UseNet Post with RGB/HSL conversion routines


HSL/RGB:  Michael Tihon's Spectroscope Project

HSL, HSV/ HSB and RGB components
http://web.tiscalinet.it/encomps 

HSV:
- Using a background thread to compute and display a Mandelbrot set using HSVcolor scheme, Delphi in a Nutshell, pp. 148-151

RGB/HLS (D6/D7)

The following routines mimic the like named routines from Shlwapi.dll except these routines do not rely on any specific version of IE being installed. 

//  Calculates Hue, Luminance and Saturation for the clrRGB value
procedure ColorRGBToHLS(clrRGB: COLORREF; var Hue, Luminance, Saturation: Word);

// Calculates a color given Hue, Luminance and Saturation values
function ColorHLSToRGB(Hue, Luminance, Saturation: Word): TColorRef; 

efg's Lab Reports:

ViewerRGB.gif (1080 bytes) Show Image HueSaturationByValue.gif (5695 bytes) HSV yvu.gif (989 bytes) YUV RGBColorsIcon.gif (992 bytes) RGB
Colors
ColorMix.gif (1372 bytes) Color Mix

[Foley96, pp. 590-592, Plate II.7-II.8]

GraphicEx:  various color space conversions
http://www.lischke-online.de/Graphics.html#GraphicEx
 

CMY, CMYK (subtractive color):
- Converting a RGB color to a CMYK color, Borland  (FAQ 2948D)
- Steve Schafer's UseNet Post showing conversions both ways
- efg's Show Image Lab Report
- [Foley96, pp. 587-588, Plate II.6]

L*a*b*
- Steve Schafer's UseNet Post

L*u*v*:
- [Foley96, pp. 584]

RGB Konvertierungen (RGB Conversions)
- http://home.t-online.de/home/PeterJHaas/bitmap.htm#RGB

XYZ:
- [Foley96, pp. 580-581, 586-587]
- Steve Schafer's UseNet Post

yvu.gif (989 bytes)  YUV
- efg's YUV Lab Reports
- efg's YUVRGB code in UseNet post

YIQ: [Foley96, pp. 589-590]

"Putting Colors in Order."  A new method of looking at RGB color space as Hue, Value and Chroma (HVC) Dr. Dobb's Journal, Issue 202, July 1993, page 40.
http://pw1.netcom.com/~hjsmith/ColorOrd/ColorDoc.html
Pascal Code:  http://pw1.netcom.com/~hjsmith/ColorOrd/Listings.html

efg's Color Reference Library

Color Usage

Hitting the Highlights:  Center Stage for Data-entry Controls, Delphi Informant, Jan 1998

ColorAdjustLuma D6 GraphUtil Unit:

function ColorAdjustLuma(clrRGB: TColorRef; n: Integer; fScale: BOOL): TColorRef; 

Given a color and a luminance change "n" this routine returns a color whose luminance has been changed accordingly.

ColoHLStoRGB D6 GraphUtil Unit:

procedure ColorRGBToHLS(clrRGB: COLORREF; var Hue, Luminance, Saturation: Word); 

Calculates a color given Hue, Luminance and Saturation values

ColorRef see ColorRef on VCL/RTL page
ColorRGBToHLS D6 GraphUtil Unit: 

procedure ColorRGBToHLS(clrRGB: COLORREF; var Hue, Luminance, Saturation: Word); 

Calculates Hue, Luminance and Saturation for the clrRGB value

ColorToHTMLColor Ralf Mimoun's UseNet Post
ColorToIdent see ColorToIdent on VCL/RTL page
ColorToRGB see ColorToRGB on VCL/RTL page
ColorToRGBTriple
FUNCTION  ColorToRGBTriple(CONST Color:  TColor):  TRGBTriple;
BEGIN
  WITH RESULT DO
  BEGIN
    rgbtRed   := GetRValue(Color);
    rgbtGreen := GetGValue(Color);
    rgbtBlue  := GetBValue(Color)
  END
END {ColorToRGBTriple};
ColorToString see ColorToString on VCL/RTL page
Console Application Colors Generating a Windows Console Application (FAQ 747D)
ComboBox Two examples of color comboboxes
www.ecnet.net/users/gsmpati/delphi
Contrast Andreas Filsinger's VisibleContrast function for creating text with good contrast with the background.

Also see GetHighLightColor and GetShadowColor.

Counting Colors Count the number of unique RGB triples in an image
BOMB.gif (1109 bytes) efg's Very Large Bitmap Lab Report
ColorRange.gif (1115 bytes) efg's Color Range Lab Report:
Select or exclude range of colors in an image and replace with specified color.
ViewerRGB.gif (1080 bytes) efg's ShowImage Lab Report
Cursors Neil Rubenking's PC Magazine (1 Nov 1999) Delphi utility, CursorDance, shows animated and color cursors and includes complete Delphi source code. 

Download the whole project from PC Mag in the cdance.zip file.  Unzip cdance.zip and you'll see a curd_src.zip.  Unzip curd_src.zip and you'll see an Images.zip.  Unzip Images.zip and you'll see the Resmake.bat file.  This is a clever trick by Neil to define a .RC file and a "make" file all inside a single .BAT file.  This creates the .RES file used by the Cursor Dance project.

Also see Cursors on the Graphics Algorithms page.

Cycle Colors SPECTRUM.gif (1072 bytes)   efg's Cycle Colors Lab Report
Differences See Nearest Color below
Display Mode Colors How many colors will my display mode support? (FAQ 741D)
Finding the color depth of a canvas (TI 1507D)

Can your video handle 16, 256, 32768, 16777216, or more colors?
www.chami.com/tips/delphi/121896D.html

Determine the RGB Bits-Per-Pixel for the Display
http://support.microsoft.com/support/kb/articles/q195/8/29.asp

Charles Hacker's UseNet Post calculating ColorDepth

Displaying a 24 bit True Color bitmap image on a 256 color display (FAQ 996D). See efg's ShowDemoOne Lab Report for an alternative in displaying 24-bit BMPs in 256-color display mode.

Dithering

Gordy's Usenet Post about dithered grayscale

Non-Delphi:
Video for Windows DrawDIBDraw example (near bottom of True-Color Tyranny section).  DrawDib apparently uses some kind of pattern dither (Bayer?) to display images, but it does a surprisingly good job.
www.geocities.com/SiliconValley/2151/dibs.html 

[Foley96, pp. 568-573]

Fade Eddie Shipman's UseNet Post about making a rainbow background on a form (with palettes)
fade.gif (1035 bytes) efg's Fade: Fade to/from black. See also Tween.  (no palettes)
Font Colors Different Font Colors Print As Same Color
http://support.microsoft.com/support/kb/articles/Q209/8/79.ASP
Gamma Correction Steve Schafer's Usenet Post about gamma correction including routines to linearize and unlinearize RGB values.

Philipp Pammler's Usenet Post with example of using GetDeviceGammaRamp and SetDeviceGammaRamp API calls. Michael Warner's reply that API gamma functions work with few video cards.

TGammaPanel is a True Color Select Panel like a Paint Shop Pro 5 Color Panel. www.abcnet.de/TRSOFT/Download/Gamma.zip

[Foley96, pp. 564-568]
See Gamma section on efg's Color Reference Library Page

GetBValue See VCL/RTL page
GetColorDepth
USES Math;  // MinIntValue

// Adapted from Tommy Andersen's ColorDepth post to
// comp.lang.pascal.delphi.components.misc, 5 Oct 1997.
//
// According to Tim Robert's post "Bitmaps with > 256 Colors" to
// compl.lang.pascal.delphi.misc, 17 Apr 1997, "in a windows bitmap,
// one of either the bits-per-plane or the number of planes must be 1. In
// fact, the planar form is only supported at 4 bits per pixel. A 24-bit
// true color bitmap must have bits-per-pixel set to 24 and planes set to 1.
//
// 16-bit color = 65536 colors may really be 15-bit color = 32767 colors
// 32-bit color only has 24 bits of color. The remaining 8-bit "alpha"
// channel does not result in additional colors, so MinIntValue is used
// below to make sure Bits/Pixel <= 24.
FUNCTION GetColorDepth: INTEGER;
  VAR
    DeviceContext: hDC;
BEGIN
  DeviceContext := GetDC(hWnd_DeskTop);

  TRY
  RESULT := 1 SHL (GetDeviceCaps(DeviceContext, PLANES) *
                  MinIntValue( [24, GetDeviceCaps(DeviceContext, BITSPIXEL)]))
  FINALLY
    // Give back the screen DC
    ReleaseDC(0, DeviceContext)
  END
END {GetColorDepth};
 

Ray Lischner's "Palettes Made Plain:  Demystifying Microsoft Windows Palettes" shows this approach:

VAR
  BitsPerPixel:  INTEGER;
...
IF   (GetDeviceCaps(Form1.Canvas.Handle, RASTERCAPS) AND RC_PALETTE) <> 0
THEN BitsPerPixel := GetDeviceCaps(Form1.Canvas.Handle, COLORRES)
ELSE BitsPerPixel := GetDeviceCaps(Form1.Canvas.Handle, PLANES) *
                     GetDeviceCaps(Form1.Canvas.Handle, BITSPIXEL);
GetColorValues see GetColorValues on VCL/RTL page
GetDeviceCaps Windows API call that returns device-specific information.  For the display monitor, use
VAR  value;
... 
DeviceContext := GetDC(hWnd_DeskTop);
TRY
  value := GetDeviceCaps(DeviceContext, <constant>)
FINALLY   
  ReleaseDC(0, DeviceContext)
END;

Color specific "caps" include:

<constant> Description
BITSPIXEL Bits per pixel.  See GetColorDepth.
COLORES Identifies actual color resolution of device.  On 256-color devices this value is often 18 with 6 bits of R, G and B possible.  Observed to be 0 in high color and true color display modes.
NUMRESERVED 20 (see System Colors)
PLANES Color planes.  See GetColorDepth.
RASTERCAPS The RC_PALETTE bit is set to indicate a palette device.
See IsPaletteDevice function below in Palettes section.
SIZEPALETTE 256
GetGValue See VCL/RTL page
GetHighLightColor D6 GraphUtil Unit: 
function GetHighLightColor(const Color: TColor): TColor; 

GetHighLightColor and GetShadowColor take a Color and calculate an "appropriate" highlight/shadow color for that value. If the color's saturation is beyond 220 then it's lumination is decreased rather than
increased. 

GetPixelDepth
FUNCTION GetPixelDepth: INTEGER;
  VAR
    DeviceContext: hDC;
BEGIN
  DeviceContext := GetDC(hWnd_DeskTop);
  TRY
    RESULT := GetDeviceCaps(DeviceContext, BITSPIXEL)
  FINALLY
    // Give back the screen DC
    ReleaseDC(0, DeviceContext)
  END;
END {GetPixelDepth};
GetRValue See VCL/RTL page
GetShadowColor D6 GraphUtil Unit: 
function GetShadownColor(const Color: TColor): TColor; 

GetHighLightColor and GetShadowColor take a Color and calculate an "appropriate" highlight/shadow color for that value. If the color's saturation is beyond 220 then it's lumination is decreased rather than
increased. 

GradientFill GradientFill API call
Gray Scale There are various ways to convert (R,G,B) to shades of gray.  One way is to create an "Intensity" image:
     I = (R + G + B)/3.
Take this value of I and assign it to the R, G and B components of the pixel.
 
Another way is to compute the "Y" value (from YIQ or YUV -- the grayscale from B/W TV). 
     Y = 0.212671R + 0.715160G + 0.072169B
After computing Y, assign it to the R, G, B components.

See Usenet Post with "common formula" by Steve Schafer and Harm's reply with integer math suggested optimzation.

Charles Hacker's UseNet Post with GrayScale procedure

Steve Schafer's Usenet Post about gamma correction including routines to linearize and unlinearize RGB values.

Create a gray-scale palette, Delphi in a Nutshell, p. 19
efg's UseNet Post about how to create TBitmap with 256 shades of gray.

Davie Reed's UseNet Post  about "How to set gray-scale bitmap"
Gordy's Usenet Post about dithered grayscale

grays.gif (1078 bytes) Y8 Gray Scale Lab Report

   
How to create a Bitmap from numeric data? (D5)  Shows gray scale vs. spectrum.

Also see Monochrome checkbox in each of the following:
efg's ShowImage Lab Report or Slide Show Tech Note

Michael Christopher's C++ Builder component  for simple image processing with 8 bit-images (invert and contrast enhancement).  MichaelChristopher_IP_Image.zip

Histograms See Histograms on  Image Processing page
Hue/Saturation Change Hue/Saturation of screen shot image.  Change the TrackBar below from 0 to 360 to assign the hue to the gray image.  (Thanks to Haris I. Volos for asking how to do this.)

Before reassigning the hue of each pixel from the TrackBar, the saturation must be boosted (by the value in the SpinEditBox) in a gray image, or there isn't "enough" color (otherwise the color still appears as a "gray hue"). 

ScreenChangeHueSaturation.jpg (20293 bytes)

In the above image, each "Original" RGB pixel is converted to HSV.  S is boosted by the "Delta Saturation" amount to give S'.  H is assigned a new value, H', from the TrackBar.  The resulting H'S'V values are converted back to the RGB values in the "New Hue" image.

Complete D3 example with source code:  ChangeHueSaturation.ZIP

IdentToColor see IdentToColor on VCL/RTL page
Invert Colors in Bitmap ScreenInvertBitmap.jpg (27774 bytes)

D3-D5 example of inverting pf24bit bitmap:  InvertBitmap.ZIP

C  = 255 - R
M = 255 - G
Y  = 255 - B


// Based on 1 June 2000 post to borland.public.delphi.multimedia
// by Robert Ro▀mair
...
  VAR
    R:  TRect;
...
  WITH Image1.Picture.Bitmap DO
  BEGIN
    R := Rect(0, 0, Width, Height);
    InvertRect(Canvas.Handle, R);
  END;
  Image1.Invalidate

// Show bitmap (BMP file) and its color inverse in two TImages.
// Based on 1 June 2000 post to borland.public.delphi.multimedia
// by Robert Ro▀mair.
procedure TFormInvertBitmap.ButtonLoadBMPClick(Sender: TObject);
  VAR
    Bitmap:  TBitmap;
begin
  IF   OpenPictureDialog.Execute
  THEN BEGIN
    Bitmap := TBitmap.Create;
    TRY
      Bitmap.LoadFromFile(OpenPictureDialog.Filename);
      Bitmap.PixelFormat := pf24bit;  // avoid using palettes
      Image1.Picture.Graphic := Bitmap;
      InvertRect(Bitmap.Canvas.Handle, Bitmap.Canvas.ClipRect);
      Image2.Picture.Graphic := Bitmap
    FINALLY
      Bitmap.Free
    END
  END
end;

Also see ColorMix.gif (1372 bytes)   Color Mix

IsPaletteDevice See Palette Section
Lines Example of how to draw Gradient and Rainbow lines using TBresenham class in BresenhamLibrary unit.
D4/D5 Complete Example Source Code:  ColorLines.ZIP
ScreenColorLinesGradient.jpg (20853 bytes) Gradient Lines
ScreenColorLinesRainbow.jpg (21818 bytes) Rainbow Lines
Map Coloring A Look at Four- and Five-Color Algorithms, Delphi Informant, May 1999, pp. 40-47
Maxwell Triangle MaxwellTriangleSmall.gif (1250 bytes) efg's Maxwell Triangle Lab Report
Monochrome bitmaps Problem generating Monochrome bitmap
http://support.microsoft.com/support/kb/articles/q149/5/85.asp
Nearest Color See NearestColor.TXT, which shows how to find the "nearest" color in RGB space.  This approach minimizes the Pythagorean distance in RGB space, but this won't be linear in color perception space.  For much more information on this topic, see Differences in efg's Color Science Reference Library.
Owner-Draw Examples A Menu Bar
A Colorful Popup Menu
A Colorful ComboBox
A Color Selector

http://www.govst.edu/users/gsmpati/delphi 

PaletteIndex see PaletteIndex on VCL/RTL page
PaletteRGB see PaletteRGB on VCL/RTL page
Palettes Palette Functions, Tomes Graphical, pp. 403-454

For palette problems when loading DIBs from a resource file, see 
TI1081D, "Loading Bitmaps and Cursors from RES files"
http://community.borland.com/article/0,1410,16081,00.html
 

Palettes, Background Information

Joe Hecht's UseNet Post that there is no "standard" Windows palette

The Microsoft Windows Palette Manager
www.compuphase.com/palette.htm

The Palette Manager:  How and Why It Does What It Does
http://support.microsoft.com/support/kb/articles/q137/3/72.asp
(download Palman.EXE and review the file PalMan.WRI.)

GetPalette and PaletteChanged, pp. 211-212.
Delphi Component Design by Danny Thorpe

Ray Lischner's "Palettes Made Plain:  Demystifying Microsoft Windows Palettes" shows gradient palette and palette animation demo, Delphi Informant, July 1998.

Processing WM_PALETTECHANGED and WM_QUERYNEWPALETTE
Microsoft's Knowledge Base:  http://support.microsoft.com/support/kb/articles/Q77/7/02.ASP

Safety Palette
http://msdn.microsoft.com/workshop/design/color/safety.asp

The Hardware Palette is the color lookup table found in the hardware.

A System Palette is the copy of the hardware palette maintained in software by the Palette Manager.  (But actually, the hardware often does not use a palette.  Windows maintains a system palette for compatibility with 256-color mode.)

A Logical Palette is a Windows palette object created using the CreatePalette API call.

A Foreground Palette (a logical palette) may overwrite all entries of the sysetm palette, except the static system colors.

A Background Palette (a logical palette) can only set "free" entries in the system palette or map colors in the logical palette to entries in the system palette.

SelectPalette:  Win32 API call to mark palette as either "background" or "possibly-foreground."  Reselecting a palette that is already selected causes no harm.

RealizePalette:  Win 32 API call that creates a mapping table -- each color in the logical palette is color-matched to every color in the system palette. "Realization" is the process of mapping a logical palette to the system palette.   This process is quite involved since the Windows Palette Manager must deal with multiple applications. The foreground palette only has priority, not exclusivity.   Drawing will be relative to the logical palette only after realization of the palette.  Re-realizing a palette that is already realized causes no harm.

Normally SelectPalette/RealizePalette occur as a pair of calls, but RealizePalette is only needed for "display" device contexts.  RealizePalette is not needed for "memory" device contexts.  In summary, SelectPalette is needed for all device contexts and RealizePalette is needed only for a device that really supports palette operations in hardware.

"More Fun with MFC: DIBs, Palettes, Subclassing, and a Gamut of Reusable Goodies", Part I (Jan 97), www.microsoft.com/MSJ/0197/mfcp1/mfcp1.htm 
www.microsoft.com/msj/code1993to1997/MSJJAN97.EXE

More Fun With MFC: DIBs, Palettes, Subclassing and a Gamut of Goodies, Part II (Mar 97)
www.microsoft.com/msj/0397/mfcp2/mfcp2.htm
www.microsoft.com/msj/code1993to1997/MSJMAR97.EXE

More Fun with MFC: DIBs, Palettes, Subclassing, and a Gamut of Goodies, Part III (Jun 97)
www.microsoft.com/msj/0697/mfc3/mfc3.htm 

An 8-bit image that does not contain all the static colors in its original color table loses whatever colors could not be set directly in the system palette (but only in palette mode, i.e., 256-color display mode).

IsPaletteDevice
// Adapted from Joe C. Hecht's UseNet Post
FUNCTION IsPaletteDevice: BOOLEAN;
  VAR
    DeviceContext: hDC;
BEGIN
  DeviceContext := GetDC(hWnd_DeskTop);
  TRY
    RESULT := GetDeviceCaps(DeviceContext, RASTERCAPS) AND RC_PALETTE = RC_PALETTE
  FINALLY
    // Give back the screen DC
    ReleaseDC(0, DeviceContext)
  END
END {IsPaletteDevice};

In The Microsoft Windows Palette Manager there is a "Does the video card support a palette?" section.  The IsPaletteDevice code there checks RC_PALETTE as shown above, but further restricts the test for when the number of bits per pixel is 8.  The comments there:  "The only hardware modes that use a pallete are modes with 2, 4, 16 and 256 colours.  Microsoft Windows supports palette operations only on displays with 256 colours.  That is, in 16-colour mode, you cannot use the palette.  So you only need to check for the RC_PALETTE bit if the number of bits per pixel is 8."  Here's the equivalent code:

FUNCTION IsPaletteDevice:  BOOLEAN;
  VAR
    Bits         :  INTEGER;
    DeviceContext:  hDC;
    ReturnCode   :  INTEGER;
BEGIN
  DeviceContext := GetDC(hWnd_DeskTop);
  TRY
    bits := GetDeviceCaps(DeviceContext, BITSPIXEL) *
            GetDeviceCaps(DeviceContext, PLANES);
    ReturnCode := GetDeviceCaps(DeviceContext, RASTERCAPS);
  FINALLY
    ReleaseDC(0, DeviceContext)
  END;
  RESULT := ((ReturnCode AND RC_PALETTE) <> 0) AND (Bits = 8)
END {IsPaletteDevice};                         

efg's Lab Reports

CombinePf4bit.gif (1266 bytes) Combine pf4Bit Bitmaps
Palet2.gif (1124 bytes) Palette Lab
(WM_PALETTECHANGED and WM_QUERY
NEWPALETTE messages)
grays.gif (1078 bytes) Y8 Gray Scale
(pf8bit vs pf24bit approach in displaying grayscale data)
Palettes, Caveats Microsoft's Palettes Self-Study Module:
"... many, if not most, devices are not palette capable.  Low-end devices such as VGA just can't display enough colors at one time to be palette "aware."  High-end devices can display so many colors that they don't need to be palette aware.  These factors severely limit the market for applications reliant on palette manipulation."  (Microsoft moved this link -- I'm still looking for it)

Danny Thorpe's UseNet Post about why transparency often fails on paletted devices

Palettes, Creation Joe Hecht's UseNet Post about Bug in D4 (fixed in D5)

see
- CreatePalette API call and AnimatePalette on Delphi Graphics Win32API page

Create a gray-scale palette, Delphi in a Nutshell, p. 19

efg's UseNet Post about how to create TBitmap with 256 shades of gray.

Gradient Palettes, Halftone Palette, 22 FracInt .PAL files ,
Palet2.gif (1124 bytes)  efg's Palette Lab Report

See Scanline Tech Note for pf8bit bitmaps with palettes

  efg's pf1bit  Lab Report

efg's UseNet Post about converting 256-color bitmap to pf1bit 

David Ullrich's UseNet Post about Gray and Black/White Palettes
Eddie Shipman's UseNet Post about making a rainbow background on a form
Ignacio Alvarez's UseNet Post about Palette Created for pf24bit bitmap when using 256 color display mode.

Palettes, Examples Scramble Palette Example
\Program Files\Borland\Delphi n\HELP\Examples\Bitmap\BMPFormU.PAS

Creating a palette with more than one entry (FAQ 890D)

Damon Chandler's (Team B) UseNet Post about modifying a palette.  
Damon Chandler's (TeamB) UseNet Post about changing palette entry in pf8bit bmp
Also discusses GetDIBColorTable and SetDIBColorTable.
Bob Villiers' UseNet Post about how to change a single color in a pallete

Dean Verhoeven's E-mail about using SetDIBColorTable to alter palette of pf8bit bitmap

Ray Lischner's Palette Animation Demo, pal10.zip at www.tempest-sw.com/freeware or via ftp at ftp://ftp.tempest-sw.com/pub/delphi/pal10.zip, Delphi 1.

Ray Lischner's "Palettes Made Plain:  Demystifying Microsoft Windows Palettes" shows gradient palette and palette animation demo, Delphi Informant, July 1998.

Palette Management in VCL Components, Visual Developer, pp. 110-113, Builder C++ example, www.visual-developer.com/code/vdm/vdmv9n2.zip

Wandlung in Graustufen und ─ndern der Palette
(Transformation in gray tones and modifying of the pallet)
http://home.t-online.de/home/PeterJHaas/bitmap.htm#Graustufen

How to respond to QueryNewPalette and PaletteChanged messages
www.lmc-mediaagentur.de/dpool/tips04/0358.htm 

Screen Capture
www.xploiter.com/programming/delphi/tips3.shtml#tip25

Laurie's UseNet Post with Change256ColorBitmapPalette procedure

Sean Dockery's UseNet Post asking how to reliably get windowed controls to abide by changes to the system palette.  (Sean's examples are very good, but his question went unanswered.)

PALDEMO1. A tutorial program by Eric Engler that shows you how to handle Windows palette messages in a 256 color screen mode. Delphi 1.
www.geocities.com/SiliconValley/Network/2114/paldemo1.zip

Palette Experiments, pp. 296-311, Delphi 2 Multimedia. (out of print)

"Working with Color Palettes," pp. 209-211, How to Program Delphi 3 (out of print)
Suggests using Image.BringToFront to control precedence in z-order when multiple images with palettes are displayed.

Palettes, Multiple Images Several options should be considered if an application needs more than one palette-based image at at time:
  1. Use a rainbow palette.  A rainbow of colors allows all images to be displayed with approximae colors.  See Color Gradients and Spectrum/Rainbow.
  2. Use a conglomerate palette.  Combine all palettes into a combined, conglomerate palette.
  3. Use prioritized palettes.  Force all but one of the palettes to be realized in the background.  (The third parameter to SelectPalette is FALSE on the first and highest priority bitmap and TRUE on all subsequent, priortized SelectPalette calls.  Only the dominant image is displayed optimally.

    For example:
    // Select the chosen dominant palette
    SelectPalette(hDC, hDominantPalette, FALSE);
    RealizePalette(hDC);

    // Select a lower priority palette
    SelectPalette(hDc, hLowlyPalette, TRUE);
    RealizedPaletted(hDC);

    When an application realizes its dominant palette in response to the WM_QUERYNEWPALETTE message, the application needs to realized its secondary palettes in response to the resulting WM_PALETTECHANGED message.  Otherwise, all of the applications have a chance to realize their palettes first, and the foreground application loses out.  For a complete example see
    The Palette Manager:  How and Why It Does What It Does
    http://support.microsoft.com/support/kb/articles/q137/3/72.asp
  4. Use color analysis (see "Palettes, Optimized" below)
Palettes, Optimized Optimized Palettes, Color Reduction, Color Quantization:
Color problems in 256 color mode (FAQ 2780D) (Pen and text don't match brush)
Color reduction techniques for graphics (FAQ 972D) [weak answer]
Compressing 256 Colour Bitmaps by Grahame Marsh, www.undu.com/Articles/980311b.htm

Gervautz-Purgathofer Octree Color Quantization algorithm adapted from October 1997 Microsoft Systems Journal (www.microsoft.com/MSJ/1097/MSJoct97.zip). See efg's ShowDemoOne Lab Report or www.geocities.com/Athens/Delphi/9072/download.htm#genpal

ReduceColors function.  See Anders Melander's UseNet Post about using TGIFImage to reduce colors.

efg's Lab Reports

parrots.gif (3545 bytes) Display Single 24-bit color image in 256-color mode
Display Several 24-bit color images in 256-color mode

efg's Color Reference Library

Palettes, VGA While VGA hardware does have a palette-based design, the number of available colors (64) and the number of hardware palette entries (16) are too limiting for use by the Palette Manager.  So the Windows VGA driver does not support palettes and uses a fixed color table of 16 colors.
PixelProfile RGB or HSV Pixel Profile in Image
PixelProfile.gif (1269 bytes)  efg's PixelProfile Lab Report
Print Image How can I Print a Bitmap?  Item 1 on Delphi Printing Info and Links page 
efg's
Printer Demo #1

Print In Color (FAQ 1650D)

RGB see RGB on VCL/RTL page
RGBTripleToColor
FUNCTION  RGBTripleToColor(CONST Triple:  TRGBTriple):  TColor;
BEGIN
  RESULT := RGB(Triple.rgbtRed, Triple.rgbtGreen, Triple.rgbtBlue)
END {RGBTripleToColor};
Saturate Color Jean-Yves QuÚinec's Estampe Demo program
SetDIBColorTable efg's Graphics WinAPI page
SetSysColors efg's Graphics WinAPI page
SetSystemPaletteUse see Palettes
Spectrum/Rainbow Painting a rainbow color spectrum onto a form (FAQ 1247D)

Eddie Shipman's UseNet Post about making a rainbow background on a form

   How to create a Bitmap from numeric data? (D5)

VisibleLight.jpg (1178 bytes)  efg's Spectra Lab Report

Also, see "Color Gradients".

StringToColor see StringToColor on VCL/RTL page
System Colors Microsoft Windows reserves 20 "static" colors in the system palette.  The system colors cannot be changed (but can be reduced from 20 to 2 using the SetSystemPaletteUse API call -- this should be avoided since some video drivers behave strangely when the 20 static colors are no longer fixed).

System Palette and Static Colors
http://msdn.microsoft.com/library/psdk/gdi/colors_1r3n.htm

According to the Microsoft Systems Journal, Sept. 91, p. 119, the table below is the Windows 3.0 Default Palette.  These colors should never dither in 256-color mode.

The placement of the static colors is at the beginning and end of the palette table so that common raster operations such as XOR will behave correctly.  With the static colors in slots 0..9 and 246..255, the inverse index of one of the static colors results in another static color.

The colors marked with an asterisk (*) below are part of Windows 95 "theme" colors.  So these specific theme colors may not be defined in all configurations of Windows.

The "Static" Colors
(Find info about the "dynamic" static colors at www.compuphase.com/palette.htm)
Index Red Green Blue RGB Name Delphi Definition
0 0 0 0 $000000 black clBlack
1 128 0 0 $000080 dark red (maroon) clMaroon
2 0 128 0 $008000 dark green clGreen
3 128 128 0 $008080 dark yellow (olive) clOlive
4 0 0 128 $800000 dark blue (navy) clNavy
5 128 0 128 $800080 dark magenta (purple) clPurple
6 0 128 128 $808000 dark cyan (teal) clTeal
7 192 192 192 $C0C0C0 light grey clSilver
8 192 220 192 $C0DCC0 *"money" green TColor($C0DCC0)
clMoneyGreen  (D6)
9 166 202 240 $F0CAA6 *sky blue
Sometimes RGB(164,200,240)
TColor($F0CAA6)
clSkyBlue (D6)
RxLib:  TColor($FFFBF0)
246 255 251 240 $F0FBFF *cream TColor($F0FBFF)
clCream (D6)
RxLib:  TColor($A6CAF0)
247 160 160 164 $A4A0A0 *light grey clMedGray (D6)
TColor($A4A0A0)
248 128 128 128 $808080 medium grey clGray, cl DkGray
249 255 0 0 $0000FF red clRed
250 0 255 0 $00FF00 green (bright) clLime
251 255 255 0 $00FFFF yellow clYellow
252 0 0 255 $FF0000 blue clBlue
253 255 0 255 $FF00FF magenta clFuchsia
254 0 255 255 $FFFF00 cyan clAqua
255 255 255 255 $FFFFFF white clWhite

I am not sure why RxLib uses different definitions for clSkyBlue and clCream than the values given by  Microsoft.

Printing System Colors using various brush styles:  efg's Printer Demo #2

TColor see efg's Delphi Graphics VCLRTL page
TColorSpeedBtn Robert Rossmair's UseNet Post with ClrSpBtn unit 
(a TSpeedButton descendant that has a Color property)
TDBGrid Colorizing a TDBGrid
http://community.borland.com/article/0,1410,20845,00.html
TRGBQuad, TRGBTriple see VCL/RTL page
Vectorscope efg's Vectorscope Delphi 6 project dynamically draws the vectorscope diagram below:

From www.seanet.com/Users/bradford/ntscvideo.html:
A vectorscope is a specialized oscilloscope that measures color information in the subcarrier of the main signal. Instead of measuring brightness,  a vectorscope indicates saturation and hue. Positions closer to the center are less saturated, while positions closer to the outer edge are more saturated colors. All shades of gray (white to black) are be a dot at the center.

Also see:  www.tektronix.com/Measurement/App_Notes/NTSC_Video_Msmt/vectorscope.html

Check the Show Color Chart box to see the following  diagram overlaid on the above.

Thanks to Richard Jungert for coaching me through this project.

WM_SYSCOLOR
CHANGE
see Messages on  efg's Delphi Graphics Win32 API page

Color Messages
http://msdn.microsoft.com/library/psdk/gdi/colors_8alv.htm

 

WM_PALETTE
CHANGED
WM_QUERY
NEWPALETTE
XORing Colors Howard Moon's UseNet Post about XOR for TColor

See alternative to XORing,
LineStretch.gif (928 bytes)   efg's   Line Stretch Lab Report


Note:
   Foley96 (referenced above in several places) is not a Delphi book,
but is an excellent source for computer graphics algorithms.


Links Verified 6 Feb 2000
Updated 26 Feb 2005


since 6 Feb 2000