How to change the color of a TRectangle, ie., using HSV? The samples I found wont apply with Firemonkey. Basically I would like to slide a trackbar and change its brightness or set the bright percent...
type TColorVar = record case Integer of 0: (B: Byte; G: Byte; R: Byte; Alpha: Byte); 1: (Color: TAlphaColor ); end;
procedure HSL2RGB(H, SL, L: Double; var Color: TAlphaColor; const Alpha: Double = 1.0); overload; var v: Double; R, G, B: Double; m: Double; sv: Double; sextant: Integer; fract, vsf, mid1, mid2: Double; begin R := L; // default to gray G := L; B := L; if (L <= 0.5) then v := L * (1.0 + SL) else v := L + SL - L * SL; if (v > 0) then begin m := L + L - v; sv := (v - m) / v; H := H * 6.0; sextant := Trunc(H); fract := H - sextant; vsf := v * sv * fract; mid1 := m + vsf; mid2 := v - vsf; case sextant of 0: begin R := v; G := mid1; B := m; end; 1: begin R := mid2; G := v; B := m; end; 2: begin R := m; G := v; B := mid1; end; 3: begin R := m; G := mid2; B := v; end; 4: begin R := mid1; G := m; B := v; end; 5: begin R := v; G := m; B := mid2; end; end; end; TColorVar(Color).Alpha := Trunc(Alpha * 255.0); TColorVar(Color).R := Trunc(R * 255.0); TColorVar(Color).G := Trunc(G * 255.0); TColorVar(Color).B := Trunc(B * 255.0); end;
function HSL2RGB(H, SL, L: Double; const Alpha: Double = 1.0): TAlphaColor; overload; begin HSL2RGB(H, SL, L, Result, Alpha); end;
procedure RGB2HSL(Color: TAlphaColor; var H, S, L, Alpha: Double); var R, G, B: Double; v: Double; m: Double; vm: Double; r2, g2, b2: Double; begin Alpha := TColorVar(Color).Alpha / 255.0; R := TColorVar(Color).R / 255.0; G := TColorVar(Color).G / 255.0; B := TColorVar(Color).B / 255.0; H := 0; // default to black S := 0; L := 0; v := System.Math.Max(R, G); v := System.Math.Max(v, B); m := System.Math.Min(R, G); m := System.Math.Min(m, B); L := (m + v) / 2.0; if (L <= 0.0) then Exit; vm := v - m; S := vm; if (S > 0.0) then begin if (L <= 0.5) then S := S / (v + m) else S := S / (2.0 - v - m); end else Exit; r2 := (v - R) / vm; g2 := (v - G) / vm; b2 := (v - B) / vm; if (R = v) then begin if G = m then H := 5.0 + b2 else H := 1.0 - g2; end else begin if SameValue(G, v, Epsilon) then begin if SameValue(B, m, Epsilon) then H := 1.0 + r2 else H := 3.0 - b2; end else begin if SameValue(R, m, Epsilon) then H := 3.0 + g2 else H := 5.0 - r2; end; end; H := H / 6.0; end;
uses
ReplyDeleteSystem.Math;
type
TColorVar = record
case Integer of
0:
(B: Byte;
G: Byte;
R: Byte;
Alpha: Byte);
1:
(Color: TAlphaColor
);
end;
procedure HSL2RGB(H, SL, L: Double; var Color: TAlphaColor; const Alpha: Double = 1.0); overload;
var
v: Double;
R, G, B: Double;
m: Double;
sv: Double;
sextant: Integer;
fract, vsf, mid1, mid2: Double;
begin
R := L; // default to gray
G := L;
B := L;
if (L <= 0.5) then
v := L * (1.0 + SL)
else
v := L + SL - L * SL;
if (v > 0) then
begin
m := L + L - v;
sv := (v - m) / v;
H := H * 6.0;
sextant := Trunc(H);
fract := H - sextant;
vsf := v * sv * fract;
mid1 := m + vsf;
mid2 := v - vsf;
case sextant of
0:
begin
R := v;
G := mid1;
B := m;
end;
1:
begin
R := mid2;
G := v;
B := m;
end;
2:
begin
R := m;
G := v;
B := mid1;
end;
3:
begin
R := m;
G := mid2;
B := v;
end;
4:
begin
R := mid1;
G := m;
B := v;
end;
5:
begin
R := v;
G := m;
B := mid2;
end;
end;
end;
TColorVar(Color).Alpha := Trunc(Alpha * 255.0);
TColorVar(Color).R := Trunc(R * 255.0);
TColorVar(Color).G := Trunc(G * 255.0);
TColorVar(Color).B := Trunc(B * 255.0);
end;
function HSL2RGB(H, SL, L: Double; const Alpha: Double = 1.0): TAlphaColor; overload;
begin
HSL2RGB(H, SL, L, Result, Alpha);
end;
procedure RGB2HSL(Color: TAlphaColor; var H, S, L, Alpha: Double);
var
R, G, B: Double;
v: Double;
m: Double;
vm: Double;
r2, g2, b2: Double;
begin
Alpha := TColorVar(Color).Alpha / 255.0;
R := TColorVar(Color).R / 255.0;
G := TColorVar(Color).G / 255.0;
B := TColorVar(Color).B / 255.0;
H := 0; // default to black
S := 0;
L := 0;
v := System.Math.Max(R, G);
v := System.Math.Max(v, B);
m := System.Math.Min(R, G);
m := System.Math.Min(m, B);
L := (m + v) / 2.0;
if (L <= 0.0) then
Exit;
vm := v - m;
S := vm;
if (S > 0.0) then
begin
if (L <= 0.5) then
S := S / (v + m)
else
S := S / (2.0 - v - m);
end
else
Exit;
r2 := (v - R) / vm;
g2 := (v - G) / vm;
b2 := (v - B) / vm;
if (R = v) then
begin
if G = m then
H := 5.0 + b2
else
H := 1.0 - g2;
end
else
begin
if SameValue(G, v, Epsilon) then
begin
if SameValue(B, m, Epsilon) then
H := 1.0 + r2
else
H := 3.0 - b2;
end
else
begin
if SameValue(R, m, Epsilon) then
H := 3.0 + g2
else
H := 5.0 - r2;
end;
end;
H := H / 6.0;
end;
Example:
procedure TForm1.FormCreate(Sender: TObject);
begin
//private
// Hue, Saturation, Luminance, Alpha: Double;
RGB2HSL(Rectangle1.Fill.Color, Hue, Saturation, Luminance, Alpha);
TrackBar1.Max := 1.0;
TrackBar1.Value := Luminance;
TrackBar1.OnChange := TrackBar1Change;
end;
procedure TForm1.TrackBar1Change(Sender: TObject);
ReplyDeletebegin
Luminance := TrackBar1.Value;
Rectangle1.Fill.Color := HSL2RGB(Hue, Saturation, Luminance, Alpha);
end;
Original code: http://www.geekymonkey.com/Programming/CSharp/RGB2HSL_HSL2RGB.htm
Thank you man!! I will try that. I see that the code is very similar to mine, but my code don't work... Thanks a lot.
ReplyDeleteMagno Lima Delphi already has this implementations:
ReplyDeleteSystem.UIConsts.HSLtoRGB
System.UIConsts.RGBtoHSL
Yaroslav Brovin Humm... I will verify it, thank you.
ReplyDelete