
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@5596 8e941d3f-bd1b-0410-a28a-d453659cc2b4
317 lines
6.5 KiB
ObjectPascal
317 lines
6.5 KiB
ObjectPascal
unit mbColorConv;
|
|
|
|
{$mode objfpc}{$H+}
|
|
|
|
interface
|
|
|
|
uses
|
|
Classes, SysUtils, Graphics;
|
|
|
|
type
|
|
TBrightnessMode = (bmLuminance, bmValue);
|
|
|
|
{ HSL color model }
|
|
|
|
function HSLtoColor(H, S, L: double): TColor;
|
|
procedure HSLtoRGB(H, S, L: Double; out R, G, B: Integer);
|
|
|
|
procedure ColortoHSL(c: TColor; out H, S, L: Double);
|
|
procedure RGBtoHSL(R, G, B: Integer; out H, S, L: Double);
|
|
|
|
{ HSV color model }
|
|
|
|
procedure ColorToHSV(c: TColor; out H, S, V: Double);
|
|
procedure RGBtoHSV(R, G, B: Integer; out H, S, V: Double);
|
|
|
|
function HSVtoColor(H, S, V: Double): TColor;
|
|
procedure HSVtoRGB(H, S, V: Double; out R, G, B: Integer);
|
|
|
|
|
|
implementation
|
|
|
|
uses
|
|
Math, LclIntf;
|
|
|
|
function modulo(x, y: Double): Double;
|
|
begin
|
|
Result := x - floor(x / y) * y;
|
|
end;
|
|
|
|
//==============================================================================
|
|
// HSL color model
|
|
//==============================================================================
|
|
|
|
function HSLToColor(H, S, L: Double): TColor;
|
|
var
|
|
R, G, B: Integer;
|
|
begin
|
|
HSLtoRGB(H, S, L, R, G, B);
|
|
Result := RGBtoColor(R, G, B);
|
|
end;
|
|
(*
|
|
procedure HSLtoRGB(H, S, L: double; out R, G, B: Integer);
|
|
var
|
|
C, X, m: Double;
|
|
rr, gg, bb: Double;
|
|
begin
|
|
H := H * 360;
|
|
C := (1 - abs(2*L - 1)) * S;
|
|
X := C * (1 - abs(modulo(H / 60, 2) - 1));
|
|
m := L - C/2;
|
|
if H < 60 then
|
|
begin
|
|
R := round((C + m) * 255);
|
|
G := round((X + m) * 255);
|
|
B := round(m * 255);
|
|
end else
|
|
if H < 120 then
|
|
begin
|
|
R := round((X + m) * 255);
|
|
G := round((C + m) * 255);
|
|
B := round(m * 255);
|
|
end else
|
|
if H < 180 then
|
|
begin
|
|
R := round(m * 255);
|
|
G := round((C + m) * 255);
|
|
B := round((X + m) * 255);
|
|
end else
|
|
if H < 240 then
|
|
begin
|
|
R := round(m * 255);
|
|
G := round((X + m) * 255);
|
|
B := round((C + m) * 255);
|
|
end else
|
|
if H < 300 then
|
|
begin
|
|
R := round((X + m) * 255);
|
|
G := round(m * 255);
|
|
B := round((C + m) * 255);
|
|
end else
|
|
begin
|
|
R := round((C + m) * 255);
|
|
G := round(m * 255);
|
|
B := round((X + m) * 255);
|
|
end;
|
|
end; *)
|
|
|
|
|
|
procedure HSLtoRGB(H, S, L: double; out R, G, B: Integer);
|
|
var
|
|
M1, M2: double;
|
|
|
|
function HueToColorValue(Hue: double): byte;
|
|
var
|
|
V : double;
|
|
begin
|
|
if Hue > 10 then
|
|
Hue := Hue + 1;
|
|
if Hue < 0 then
|
|
Hue := Hue + 1
|
|
else if Hue > 1 then
|
|
Hue := Hue - 1;
|
|
if 6 * Hue < 1 then
|
|
V := M1 + (M2 - M1) * Hue * 6
|
|
else if 2 * Hue < 1 then
|
|
V := M2
|
|
else if 3 * Hue < 2 then
|
|
V := M1 + (M2 - M1) * (2/3 - Hue) * 6
|
|
else
|
|
V := M1;
|
|
Result := round(255 * V)
|
|
end;
|
|
|
|
begin
|
|
if S = 0 then
|
|
begin
|
|
R := round(255 * L);
|
|
G := R;
|
|
B := R
|
|
end
|
|
else
|
|
begin
|
|
if L <= 0.5 then
|
|
M2 := L * (1 + S)
|
|
else
|
|
M2 := L + S - L * S;
|
|
M1 := 2 * L - M2;
|
|
R := HueToColorValue(H + 1/3);
|
|
G := HueToColorValue(H);
|
|
B := HueToColorValue(H - 1/3)
|
|
end;
|
|
end;
|
|
|
|
procedure ColorToHSL(c: TColor; out H, S, L: Double);
|
|
begin
|
|
RGBtoHSL(GetRValue(c), GetGValue(c), GetBValue(c), H, S, L);
|
|
end;
|
|
|
|
// From: http://www.rapidtables.com/convert/color/rgb-to-hsl.htm
|
|
procedure RGBtoHSL(R, G, B: Integer; out H, S, L: Double);
|
|
var
|
|
rr, gg, bb, Cmax, Cmin, delta: double;
|
|
begin
|
|
rr := R / 255;
|
|
gg := G / 255;
|
|
bb := B / 255;
|
|
Cmax := MaxValue([rr, gg, bb]);
|
|
Cmin := MinValue([rr, gg, bb]);
|
|
delta := (Cmax - Cmin);
|
|
if delta = 0 then
|
|
begin
|
|
H := 0;
|
|
S := 0;
|
|
end else
|
|
begin
|
|
// Calculate L
|
|
L := (Cmax + Cmin) / 2;
|
|
|
|
// Calculate H
|
|
if Cmax = rr then
|
|
begin
|
|
H := modulo((gg - bb) / delta, 6);
|
|
{
|
|
H := ((gg - bb) / delta);
|
|
H := H - floor(H / 6);
|
|
}
|
|
H := H * 60;
|
|
end else
|
|
if Cmax = gg then
|
|
H := 60 * ((bb - rr) / delta + 2)
|
|
else
|
|
if Cmax = bb then
|
|
H := 60 * ((rr - gg) / delta + 4)
|
|
else
|
|
H := 0;
|
|
H := H / 360;
|
|
|
|
// Calculate S
|
|
S := delta / (1 - abs(2 * L - 1));
|
|
end;
|
|
end;
|
|
|
|
|
|
(*
|
|
procedure RGBtoHSL(R, G, B: Integer; out H, S, L: Double);
|
|
var
|
|
rr, gg, bb, D, Cmax, Cmin: double;
|
|
begin
|
|
rr := R / 255;
|
|
gg := G / 255;
|
|
bb := B / 255;
|
|
Cmax := MaxValue([rr, gg, bb]);
|
|
Cmin := MinValue([rr, gg, bb]);
|
|
L := (Cmax + Cmin) / 2;
|
|
if Cmax = Cmin then
|
|
begin
|
|
H := 0;
|
|
S := 0;
|
|
end
|
|
else
|
|
begin
|
|
D := Cmax - Cmin;
|
|
//calc S
|
|
if L < 0.5 then
|
|
S := D / (Cmax + Cmin)
|
|
else
|
|
S := D / (2 - Cmax - Cmin);
|
|
//calc H
|
|
if R = Cmax then
|
|
H := (gg - bb) / D
|
|
else if G = Cmax then
|
|
H := 2 + (bb - rr) /D
|
|
else
|
|
H := 4 + (rr - gg) / D;
|
|
H := H / 6;
|
|
if H < 0 then
|
|
H := H + 1;
|
|
end;
|
|
end;
|
|
*)
|
|
|
|
//==============================================================================
|
|
// HSV color model
|
|
//==============================================================================
|
|
|
|
{ Assumes H, S, V in the range 0..1 and calculates the R, G, B values which are
|
|
returned to be in the range 0..255.
|
|
From: http://axonflux.com/handy-rgb-to-hsl-and-rgb-to-hsv-color-model-c
|
|
}
|
|
procedure HSVtoRGB(H, S, V: Double; out R, G, B: Integer);
|
|
var
|
|
i: Integer;
|
|
f: Double;
|
|
p, q, t: Double;
|
|
|
|
procedure MakeRgb(rr, gg, bb: Double);
|
|
begin
|
|
R := Round(rr * 255);
|
|
G := Round(gg * 255);
|
|
B := Round(bb * 255);
|
|
end;
|
|
|
|
begin
|
|
i := floor(H * 6);
|
|
f := H * 6 - i;
|
|
p := V * (1 - S);
|
|
q := V * (1 - f*S);
|
|
t := V * (1 - (1 - f) * S);
|
|
case i mod 6 of
|
|
0: MakeRGB(V, t, p);
|
|
1: MakeRGB(q, V, p);
|
|
2: MakeRGB(p, V, t);
|
|
3: MakeRGB(p, q, V);
|
|
4: MakeRGB(t, p, V);
|
|
5: MakeRGB(V, p, q);
|
|
else MakeRGB(0, 0, 0);
|
|
end;
|
|
end;
|
|
|
|
function HSVToColor(H, S, V: Double): TColor;
|
|
var
|
|
r, g, b: Integer;
|
|
begin
|
|
HSVtoRGB(H, S, V, r, g, b);
|
|
Result := RgbToColor(r, g, b);
|
|
end;
|
|
|
|
{ Assumes R, G, B to be in range 0..255. Calculates H, S, V in range 0..1
|
|
From: http://axonflux.com/handy-rgb-to-hsl-and-rgb-to-hsv-color-model-c }
|
|
|
|
procedure ColorToHSV(c: TColor; out H, S, V: Double);
|
|
begin
|
|
RGBToHSV(GetRValue(c), GetGValue(c), GetBValue(c), H, S, V);
|
|
end;
|
|
|
|
procedure RGBToHSV(R, G, B: Integer; out H, S, V: Double);
|
|
var
|
|
rr, gg, bb: Double;
|
|
cmax, cmin, delta: Double;
|
|
begin
|
|
rr := R / 255;
|
|
gg := G / 255;
|
|
bb := B / 255;
|
|
cmax := MaxValue([rr, gg, bb]);
|
|
cmin := MinValue([rr, gg, bb]);
|
|
delta := cmax - cmin;
|
|
if delta = 0 then
|
|
begin
|
|
H := 0;
|
|
S := 0;
|
|
end else
|
|
begin
|
|
if cmax = rr then
|
|
H := (gg - bb) / delta + IfThen(gg < bb, 6, 0)
|
|
else if cmax = gg then
|
|
H := (bb - rr) / delta + 2
|
|
else if (cmax = bb) then
|
|
H := (rr -gg) / delta + 4;
|
|
H := H / 6;
|
|
S := delta / cmax;
|
|
end;
|
|
V := cmax;
|
|
end;
|
|
|
|
end.
|
|
|