// RGB, each 0 to 255, to HSV.
// H = 0 to 359 degrees around color circle
// S = 0 (shade of gray) to 255 (pure color)
// V = 0 (black) to 255 {white)
//
// Based on C Code in "Computer Graphics -- Principles and Practice,"
// Foley et al, 1996, p. 592. Floating point fractions, 0..1, replaced with
// integer values, 0..255.
PROCEDURE RGBtoHSV (CONST r,g,b: INTEGER; {0..255}
VAR h,s,v: INTEGER); {h IN 0..359; s,v IN 0..255}
VAR
Delta : INTEGER;
MinValue: INTEGER;
BEGIN
MinMax3(R, G, B, MinValue, v);
Delta := v - MinValue;
// Calculate saturation: saturation is 0 if r, g and b are all 0
IF v = 0
THEN s := 0
ELSE s := (255 * Delta) DIV v;
IF s = 0
THEN h := 0 // Achromatic: When s = 0, h is undefined but assigned the value 0
ELSE BEGIN // Chromatic
IF r = v
THEN h := (60*(g-b)) DIV Delta // degrees -- between yellow and magenta
ELSE
IF g = v
THEN h := 120 + (60*(b-r)) DIV Delta // degrees -- between cyan and yellow
ELSE
IF b = v
THEN h := 240 + (60*(r-g)) DIV Delta; // degrees -- between magenta and cyan
IF h < 0
THEN h := h + 360;
END;
END {RGBtoHSV};
{PROCEDURE RGBToHLS (CONST R,G,B: TReal; VAR H,L,S: TReal);
VAR
Delta: TReal;
Max : TReal;
Min : TReal;
BEGIN
Max := MaxValue( [R, G, B] );
Min := MinValue( [R, G, B] );
L := (Max + Min) / 2.0; // Lightness
IF Max = Min // Achromatic case since r = g = b
THEN BEGIN
S := 0.0;
H := NAN; // Undefined
END
ELSE BEGIN
Delta := Max - Min;
IF L <= 0.5
THEN S := Delta / (Max + Min)
ELSE S := Delta / (2.0 - (Max + Min));
IF R = Max
THEN // degrees between yellow and magenta
H := (60.0*(G - B)) / Delta
ELSE
IF G = Max
THEN // degrees between cyan and yellow
H := 120.0 + (60.0*(B - R)) / Delta
ELSE
IF B = Max
THEN // degrees between magenta and cyan
H := 240.0 + (60.0*(R - G)) / Delta;
IF H < 0
THEN H := H + 360.0; // Keep in interval [0, 360)
END
END {RGBtoHLS}
// == HSV / RGB =======================================================
//
// Based on C Code in "Computer Graphics -- Principles and Practice,"
// Foley et al, 1996, p. 593.
//
// H = 0.0 to 360.0 (corresponding to 0..360 degrees around hexcone)
// NaN (undefined) for S = 0
// S = 0.0 (shade of gray) to 1.0 (pure color)
// V = 0.0 (black) to 1.0 (white)
{ PROCEDURE HSVtoRGB (CONST H,S,V: TReal; VAR R,G,B: TReal);
VAR
f : TReal;
i : INTEGER;
hTemp: TReal; // since H is CONST parameter
p,q,t: TReal;
BEGIN
IF S = 0.0 // color is on black-and-white center line
THEN BEGIN
IF IsNaN(H)
THEN BEGIN
R := V; // achromatic: shades of gray
G := V;
B := V
END
ELSE RAISE EColorError.Create('HSVtoRGB: S = 0 and H has a value');
END
ELSE BEGIN // chromatic color
IF H = 360.0 // 360 degrees same as 0 degrees
THEN hTemp := 0.0
ELSE hTemp := H;
hTemp := hTemp / 60; // h is now IN [0,6)
i := TRUNC(hTemp); // largest integer <= h
f := hTemp - i; // fractional part of h
p := V * (1.0 - S);
q := V * (1.0 - (S * f));
t := V * (1.0 - (S * (1.0 - f)));
CASE i OF
0: BEGIN R := V; G := t; B := p END;
1: BEGIN R := q; G := V; B := p END;
2: BEGIN R := p; G := V; B := t END;
3: BEGIN R := p; G := q; B := V END;
4: BEGIN R := t; G := p; B := V END;
5: BEGIN R := V; G := p; B := q END
END
END
END {HSVtoRGB}
// RGB, each 0 to 255, to HSV.
// H = 0.0 to 360.0 (corresponding to 0..360.0 degrees around hexcone)
// S = 0.0 (shade of gray) to 1.0 (pure color)
// V = 0.0 (black) to 1.0 {white)
// Based on C Code in "Computer Graphics -- Principles and Practice,"
// Foley et al, 1996, p. 592. Floating point fractions, 0..1, replaced with
// integer values, 0..255.
{ PROCEDURE RGBToHSV (CONST R,G,B: TReal; VAR H,S,V: TReal);
VAR
Delta: TReal;
Min : TReal;
BEGIN
Min := MinValue( [R, G, B] );
V := MaxValue( [R, G, B] );
Delta := V - Min;
// Calculate saturation: saturation is 0 if r, g and b are all 0
IF V = 0.0
THEN S := 0
ELSE S := Delta / V;
IF S = 0.0
THEN H := NAN // Achromatic: When s = 0, h is undefined
ELSE BEGIN // Chromatic
IF R = V
THEN // between yellow and magenta [degrees]
H := 60.0 * (G - B) / Delta
ELSE
IF G = V
THEN // between cyan and yellow
H := 120.0 + 60.0 * (B - R) / Delta
ELSE
IF B = V
THEN // between magenta and cyan
H := 240.0 + 60.0 * (R - G) / Delta;
IF H < 0.0
THEN H := H + 360.0
END
END {RGBtoHSV}