(******************************************************************************************** )
( )
( THSVRec (Hue, Saturation, Value) and THSBRec (Hue, Saturation, Brightness): )
( *************************************************************************** )
( )
( THSVRec/THSBRec = Record Case Byte of )
( 0: (Org: THSV); )
( 1: (Hue: Word; Saturation, Brightness: Byte); )
( ... )
( End; )
( )
( Hue = 0..65520 > X * ~180 > 0..360° )
( Saturation = 0..256 > X * 2.56 > 0..100% )
( Brightness\Value = 0..256 > X * 2.56 > 0..100% )
( )
( Hue: 0° = Red 60° = Yellow )
( 120° = Green 180° = Cyan )
( 240° = Blue 300° = Magenta )
( )
( )
( Known also still as HLS (Hue, Luminance, Saturation) => Luminance = Brightness\Value )
( )
(*********************************************************************************************)
Type THSB =
Type LongWord;
THSV = THSB;
PHSB = ^THSB;
PHSV = PHSB;
THSBRec =
packed Record Case Byte
of
0: (Org: THSB);
1: (Hue: Word; Saturation, Brightness: Byte);
4: (Bin: LongWord);
6: (Bits: TLongWordSet);
7: (Bytes: TByteArray4);
8: (Words: TWordArray2);
End;
THSVRec = THSBRec;
Function RGBtoHSV(
RGB: TColor): THSV;
Function HSVtoRGB(
HSV: THSV): TColor;
Function RGBtoHSV(
RGB: TColor): THSV;
Var _RGB: TColorRec
Absolute RGB;
_HSV: THSVRec
Absolute Result;
Darkness: Byte;
H: LongInt;
Begin
RGB := ColorToRGB(
RGB);
If _RGB.Red > _RGB.Green
Then _HSV.Brightness := _RGB.Red
Else _HSV.Brightness := _RGB.Green;
If _RGB.Blue > _HSV.Brightness
Then _HSV.Brightness := _RGB.Blue;
If _RGB.Red < _RGB.Green
Then Darkness := _RGB.Red
Else Darkness := _RGB.Green;
If _RGB.Blue < Darkness
Then Darkness := _RGB.Blue;
If _HSV.Brightness = 0
Then _HSV.Saturation := 0
Else _HSV.Saturation := MulDiv(_HSV.Brightness - Darkness, 255, _HSV.Brightness);
If _HSV.Saturation <> 0
Then Begin
If _RGB.Red = _HSV.Brightness
Then H := Round((_RGB.Green - _RGB.Blue) / (_HSV.Brightness - Darkness) * 10920)
Else If _RGB.Green = _HSV.Brightness
Then H := Round(21840 + (_RGB.Blue - _RGB.Red) / (_HSV.Brightness - Darkness) * 10920)
Else H := Round(43680 + (_RGB.Red - _RGB.Green) / (_HSV.Brightness - Darkness) * 10920);
If H >= 0
Then _HSV.Hue := H
Else _HSV.Hue := H + 65520;
End Else _HSV.Hue := 0;
End;
Function BGRtoHSV(
RGB: TBGRRec): THSVRec;
Var Darkness: Byte;
H: LongInt;
Begin
If RGB.Red >
RGB.Green
Then Result.Brightness :=
RGB.Red
Else Result.Brightness :=
RGB.Green;
If RGB.Blue > Result.Brightness
Then Result.Brightness :=
RGB.Blue;
If RGB.Red <
RGB.Green
Then Darkness :=
RGB.Red
Else Darkness :=
RGB.Green;
If RGB.Blue < Darkness
Then Darkness :=
RGB.Blue;
If Result.Brightness = 0
Then Result.Saturation := 0
Else Result.Saturation := MulDiv(Result.Brightness - Darkness, 255, Result.Brightness);
If Result.Saturation <> 0
Then Begin
If RGB.Red = Result.Brightness
Then H := Round((
RGB.Green -
RGB.Blue) / (Result.Brightness - Darkness) * 10920)
Else If RGB.Green = Result.Brightness
Then H := Round(21840 + (
RGB.Blue -
RGB.Red) / (Result.Brightness - Darkness) * 10920)
Else H := Round(43680 + (
RGB.Red -
RGB.Green) / (Result.Brightness - Darkness) * 10920);
If H >= 0
Then Result.Hue := H
Else Result.Hue := H + 65520;
End Else Result.Hue := 0;
End;
Function HSVtoRGB(
HSV: THSV): TColor;
Var _RGB: TColorRec
Absolute Result;
_HSV: THSVRec
Absolute HSV;
Begin
_RGB.Palette := cpSystemPalette;
If _HSV.Saturation <> 0
Then Begin
If _HSV.Hue >= 54600
Then Begin
_RGB.Red := _HSV.Brightness;
_RGB.Green := MulDiv(_HSV.Brightness,
not _HSV.Saturation, 255);
_RGB.Blue := Round(_HSV.Brightness * (255 - _HSV.Saturation * (_HSV.Hue
mod 10920) / 10920) / 255);
End Else If _HSV.Hue >= 43680
Then Begin
_RGB.Red := Round(_HSV.Brightness * (255 - _HSV.Saturation * (10920 - (_HSV.Hue
mod 10920)) / 10920) / 255);
_RGB.Green := MulDiv(_HSV.Brightness,
not _HSV.Saturation, 255);
_RGB.Blue := _HSV.Brightness;
End Else If _HSV.Hue >= 32760
Then Begin
_RGB.Red := MulDiv(_HSV.Brightness,
not _HSV.Saturation, 255);
_RGB.Green := Round(_HSV.Brightness * (255 - _HSV.Saturation * (_HSV.Hue
mod 10920) / 10920) / 255);
_RGB.Blue := _HSV.Brightness;
End Else If _HSV.Hue >= 21840
Then Begin
_RGB.Red := MulDiv(_HSV.Brightness,
not _HSV.Saturation, 255);
_RGB.Green := _HSV.Brightness;
_RGB.Blue := Round(_HSV.Brightness * (255 - _HSV.Saturation * (10920 - (_HSV.Hue
mod 10920)) / 10920) / 255);
End Else If _HSV.Hue >= 10920
Then Begin
_RGB.Red := Round(_HSV.Brightness * (255 - _HSV.Saturation * (_HSV.Hue
mod 10920) / 10920) / 255);
_RGB.Green := _HSV.Brightness;
_RGB.Blue := MulDiv(_HSV.Brightness,
not _HSV.Saturation, 255);
End Else Begin
_RGB.Red := _HSV.Brightness;
_RGB.Green := Round(_HSV.Brightness * (255 - _HSV.Saturation * (10920 - (_HSV.Hue
mod 10920)) / 10920) / 255);
_RGB.Blue := MulDiv(_HSV.Brightness,
not _HSV.Saturation, 255);
End;
End Else Begin
_RGB.Red := _HSV.Brightness;
_RGB.Green := _HSV.Brightness;
_RGB.Blue := _HSV.Brightness;
End;
End;