[Back to GRAPHICS SWAG index] [Back to Main SWAG index] [Original]
{
============================================================
PROGRAM : CLOSECOL.PAS
AUTHOR : SCOTT TUNSTALL B.Sc
PURPOSE : Get the colour which has specified RGB values from
the VGA palette.
If no colour with specified values exists, return
the nearest colour.
NOTES :
I seem to recall AGES ago that someone wanted a routine
that would find the colour CLOSEST to a specified RGB
value.
This might help, although I've not tested it extensively.
Tests seem to show it works OK tho'.
Oh yeah. It needs KOJAKVGA (preferably V3) to work as is,
but it won't be too difficult for smart cookies to work out
whats going on, if they want to convert the code to their
units.
DISCLAIMER:
The standard stuff follows:
Unless you're a proud CGA/EGA card user ;), this unit
shouldn't break your PC.
However, the rule is: use this code AT YOUR OWN RISK.
If you use this code in any programs, please mention my name
in the credits. An ad for KOJAKVGA 3.3 would be nice too ;)
Have fun folks!
------------------------------------------------------------
}
program CloseCol;
uses kojakvga, crt;
{
As the function name implies, this gets the palette entry which
contains RGB values closest to those specified.
(C) 1997 Crap explanations ;)
Expects: R,G,B component values to look for;
Red component must be in range 0-63
Same applies for Green and Blue.
Values above 63 are reset to (Value MOD 64) !
This is due to the limitations of the VGA DAC I'm afraid.
Returns: index (0-255) of closest or matching colour.
}
function GetClosestVGAColour(SearchRed,SearchGreen,SearchBlue:byte) : byte;
var bestindex, currRed, currGreen, currBlue, colourcount: byte;
distred, distgreen, distblue,
bestdistred, bestdistgreen, bestdistblue: integer;
RGBTotal, BestRGBTotal: word;
begin
bestindex:=0;
distred:=255; { Distance of red from SearchRed value }
distgreen:=255;
distblue:=255;
bestdistred:=255;
bestdistgreen:=255;
bestdistblue:=255;
BestRGBTotal:=255+255+255; { R,G,B summed }
{ Iterate (love that word!) through all palette entries }
for colourcount:=0 to 255 do
begin
{ Read colour from VGA adaptor directly. }
GetRGB(colourcount,currRed,currGreen,currBlue);
{ Compute Red/Green and Blue distances }
distred:=abs(CurrRed-SearchRed);
distgreen:=abs(CurrGreen-SearchGreen);
distblue:=abs(CurrBlue-SearchBlue);
{ The lower the sum of RGB distances, the closer
the colour is to what was required }
RGBTotal:=distred+distgreen+distblue;
If RGBTotal <= BestRGBTotal Then
Begin
BestIndex:=ColourCount;
{ If we've got a perfect match, i.e. the
total colour distance is 0, then
break the loop }
If RGBTotal = 0 Then
break
else
BestRGBTotal:=RGBTotal;
End;
end;
{ And return the closest colour's palette index }
getClosestVGAColour:=BestIndex;
end;
{ Support function to display red, green, blue values at X,Y in
colour printcolour }
procedure PrintRGB(x:word; y, printcolour, r,g,b: byte);
var NumStr: string[3];
Builtstr:string[30];
begin
str(r, BuiltStr);
str(g, NumStr);
BuiltStr:=BuiltStr+','+NumStr;
str(b, NumStr);
BuiltStr:=BuiltStr+','+NumStr;
UseColour(printcolour);
PrintAt(x,y,BuiltStr);
end;
{ Test. You input your required RGB values and the system shows
two blocks which should be nearly - or even better,
** exactly ** - the same colour shade.
}
var MyRed, MyGreen, MyBlue, { RGB of colour to look for }
FoundRed, FoundGreen, FoundBlue, { RGB of closest colour }
OurColour, FillColour: byte; { Indexes for drawing }
begin
Writeln('What [VGA] R,G,B values are you looking for ? ');
Write('Red (0-63) '); Readln(MyRed);
Write('Green (0-63) '); Readln(MyGreen);
Write('Blue (0-63) '); Readln(MyBlue);
InitVGAMode;
OurColour:=GetClosestVGAColour(MyRed, MyGreen, MyBlue);
If OurColour = 0 Then
FillColour:= 1
Else
FillColour:= OurColour -1;
SetRGB(FillColour,MyRed,MyGreen,MyBlue);
{ Display colour looked for }
PrintRGB(0,0,FillColour, MyRed, MyGreen, MyBlue);
FillArea(0,16,158,199, FillColour);
{ Display closest colour }
GetRGB(OurColour, FoundRed, FoundGreen, FoundBlue);
PrintRGB(160,0, OurColour, FoundRed, FoundGreen, FoundBlue);
FillArea(161,16,319,199,OurColour);
{ And do I have to explain what this does? }
repeat until keypressed;
End.
[Back to GRAPHICS SWAG index] [Back to Main SWAG index] [Original]