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