Additions to the Palette Document

Copyright Dr. William T. Verts April 12, 1996

Converting RGB Color to VGA (16-Color)
Here is another way of converting a 24 bit RGB color into a 1-of-16 color compatible with the IBM VGA. This routine is more efficient than building a 16 entry palette then searching the palette for the closest match because it computes the closest VGA color directly.

VGA colors are 4-bit values, where the rightmost three bits are red, green, and blue, respectively (1 bit per color), and the leftmost bit is the overall instensity. The comparison values in the function below are what I believe to be the best possible thresholds, but they may certainly be tweaked if the response is not quite right. The terms that appear as Word(Red), Word(Green), and Word(Blue) are typecasts from byte to word (16 bit unsigned) so that the sum of the three color values can be greater than 255.

Function VGA_Color (C_In:Color_Type) : Byte ; Var C_Out : Byte ; Begin With C_In Do Begin C_Out := Zero ; If Red > 85 Then C_Out := C_Out + 4 ; (* Contains some Red *) If Green > 85 Then C_Out := C_Out + 2 ; (* Contains some Green *) If Blue > 85 Then C_Out := C_Out + 1 ; (* Contains some Blue *) If (Word(Red) + Word(Green) + Word(Blue)) >= 255 Then C_Out := C_Out + 8 ; (* Is Bright rather than Dim *) VGA_Color := C_Out ; End ; End ;
Another 256 Color Palette Builder (Untested)
In this routine we are building a 256 color palette, but instead of evenly distributing the colors across the entire 24 bit color space, we are randomly generating colors around the diagonal (gray) axis of the color cube. This will approximate the palettes that I have seen in use by most .GIF images.

Procedure Palette_256_Random (Var P:Palette ; Diameter:Byte) ; Var R, G, B: Integer ; Radius : Integer ; Offset : Integer ; Begin (************************************************************) (* Clear P, then load in the first 16 colors in the *) (* first 16 locations of the palette (keeps Windows happy!) *) (************************************************************) VGA_16 (P) ; (************************************************************) (* Generate random colors around the gray center line until *) (* the table is filled. Use "Diameter" to determine how *) (* far from the center line (Manhattan distance) a color *) (* is allowed to be. *) (************************************************************) Radius := Integer(Diameter) Div 2 ; (* Type cast *) Repeat (*------------------------------------------------------*) (* Generate a random position along the gray diagonal. *) (*------------------------------------------------------*) R := Random(256) ; (* Generates number in [0..255] *) G := R ; B := R ; (*------------------------------------------------------*) (* Perturb the colors by a small random amount. *) (*------------------------------------------------------*) R := R + (Integer(Random(Diameter)) - Radius) ; G := G + (Integer(Random(Diameter)) - Radius) ; B := B + (Integer(Random(Diameter)) - Radius) ; (*------------------------------------------------------*) (* Clip the resulting R,G,B back to byte values. *) (*------------------------------------------------------*) If R < 0 Then R := 0 Else If R > 255 Then R := 255 ; If G < 0 Then G := 0 Else If G > 255 Then G := 255 ; If B < 0 Then B := 0 Else If B > 255 Then B := 255 ; (*------------------------------------------------------*) (* Attempt to add the new color to the table. If the *) (* color already exists, the new item will not be added,*) (* and the table will remain the same length. Only *) (* when unique colors are added will the table length *) (* increase. Stop when the table is full. *) (*------------------------------------------------------*) Add_Color (P, R, G, B) ; Until P.Top = 255 ; End ;
Back to the CS 32 Page

Back to Dr. Bill's Page