[英]Convert HTML hex colour to TColor in Inno Setup Pascal Script
[英]How to Lighten or Darken a specified TColor in Inno Setup Pascal Script?
我需要根據我的wpInfoBefore
向導頁面中顯示的用戶當前系統規范自動更改狀態欄的顏色(它是TPanel
)(變亮或變暗)。
我喜歡有兩個函數可以通過輸入TColor
作為值來正確執行此操作。 但是,我多次嘗試通過閱讀這樣的帖子來編寫這些函數,甚至使用RGB
函數,但沒有成功。
例如,如果我需要使給定的TColor
變暗或變亮,我可能需要使用如下所示的函數:
var
RecommendedStatusColor: TColor;
function LightenColor(Colour: TColor, Percentage: Integer): TColor;
begin
...
end;
function DarkenColor(Colour: TColor, Percentage: Integer): TColor;
begin
...
end;
RecommendedStatusColor := $00D000;
if ... then
StatusBar.Color := LightenColor(RecommendedStatusColor, 75);
//Lighten given color by 75%
if ... then
StatusBar.Color := DarkenColor(RecommendedStatusColor, 50);
//Darken given color by 50%
輸出應該是修改后的(變亮或變暗) TColor.
提前致謝。
您必須將顏色轉換為HSL 或 HSV並更改亮度 (L) 或值 (V) 並轉換回 RGB。
以下代碼使用 HSL(L = 亮度)。
function GetRValue(RGB: Cardinal): Byte;
begin
Result := Byte(rgb);
end;
function GetGValue(RGB: Cardinal): Byte;
begin
Result := Byte(rgb shr 8);
end;
function GetBValue(RGB: Cardinal): Byte;
begin
Result := Byte(rgb shr 16);
end;
function Max(A, B: Integer): Integer;
begin
if A > B then
Result := A
else
Result := B;
end;
function Min(A, B: Integer): Integer;
begin
if A < B then
Result := A
else
Result := B;
end;
const
HLSMAX = 240;
RGBMAX = 255;
HLSUndefined = (HLSMAX*2/3);
procedure ColorRGBToHLS(RGB: Cardinal; var Hue, Luminance, Saturation: Word);
var
H, L, S: Double;
R, G, B: Word;
cMax, cMin: Double;
Rdelta, Gdelta, Bdelta: Word; { intermediate value: % of spread from max }
begin
R := GetRValue(RGB);
G := GetGValue(RGB);
B := GetBValue(RGB);
{ calculate lightness }
cMax := Max(Max(R, G), B);
cMin := Min(Min(R, G), B);
L := ( ((cMax + cMin) * HLSMAX) + RGBMAX ) / ( 2 * RGBMAX);
Luminance := Trunc(L);
if cMax = cMin then { r=g=b --> achromatic case }
begin
Hue := Trunc(HLSUndefined);
Saturation := 0;
end
else { chromatic case }
begin
{ saturation }
if Luminance <= HLSMAX/2 then
begin
S := ( ((cMax-cMin)*HLSMAX) + ((cMax+cMin)/2) ) / (cMax+cMin);
end
else
begin
S := ( ((cMax-cMin)*HLSMAX) + ((2*RGBMAX-cMax-cMin)/2) ) /
(2*RGBMAX-cMax-cMin);
end;
{ hue }
Rdelta := Trunc(( ((cMax-R)*(HLSMAX/6)) + ((cMax-cMin)/2) ) / (cMax-cMin));
Gdelta := Trunc(( ((cMax-G)*(HLSMAX/6)) + ((cMax-cMin)/2) ) / (cMax-cMin));
Bdelta := Trunc(( ((cMax-B)*(HLSMAX/6)) + ((cMax-cMin)/2) ) / (cMax-cMin));
if (Double(R) = cMax) then
begin
H := Bdelta - Gdelta
end
else if (Double(G) = cMax) then
begin
H := (HLSMAX/3) + Rdelta - Bdelta
end
else // B == cMax
begin
H := ((2 * HLSMAX) / 3) + Gdelta - Rdelta;
end;
if (H < 0) then
H := H + HLSMAX;
if (H > HLSMAX) then
H := H - HLSMAX;
Hue := Round(H);
Saturation := Trunc(S);
end;
end;
function HueToRGB(Lum, Sat, Hue: Double): Integer;
var
ResultEx: Double;
begin
{ range check: note values passed add/subtract thirds of range }
if (hue < 0) then
hue := hue + HLSMAX;
if (hue > HLSMAX) then
hue := hue - HLSMAX;
{ return r,g, or b value from this tridrant }
if (hue < (HLSMAX/6)) then
ResultEx := Lum + (((Sat-Lum)*hue+(HLSMAX/12))/(HLSMAX/6))
else if (hue < (HLSMAX/2)) then
ResultEx := Sat
else if (hue < ((HLSMAX*2)/3)) then
ResultEx := Lum + (((Sat-Lum)*(((HLSMAX*2)/3)-hue)+(HLSMAX/12))/(HLSMAX/6))
else
ResultEx := Lum;
Result := Round(ResultEx);
end;
function RoundColor(Value: Double): Integer;
begin
if Value > 255 then
Result := 255
else
Result := Round(Value);
end;
function RGB(R, G, B: Byte): Cardinal;
begin
Result := (Cardinal(R) or (Cardinal(G) shl 8) or (Cardinal(B) shl 16));
end;
function ColorHLSToRGB(Hue, Luminance, Saturation: Word): Cardinal;
var
R,G,B: Double; { RGB component values }
Magic1,Magic2: Double; { calculated magic numbers (really!) }
begin
if (Saturation = 0) then
begin { achromatic case }
R := (Luminance * RGBMAX)/HLSMAX;
G := R;
B := R;
if (Hue <> HLSUndefined) then
;{ ERROR }
end
else
begin { chromatic case }
{ set up magic numbers }
if (Luminance <= (HLSMAX/2)) then
begin
Magic2 := (Luminance * (HLSMAX + Saturation) + (HLSMAX/2)) / HLSMAX;
end
else
begin
Magic2 :=
Luminance + Saturation - ((Luminance * Saturation) +
(HLSMAX/2)) / HLSMAX;
end;
Magic1 := 2 * Luminance - Magic2;
{ get RGB, change units from HLSMAX to RGBMAX }
R := (HueToRGB(Magic1,Magic2,Hue+(HLSMAX/3))*RGBMAX + (HLSMAX/2))/HLSMAX;
G := (HueToRGB(Magic1,Magic2,Hue)*RGBMAX + (HLSMAX/2)) / HLSMAX;
B := (HueToRGB(Magic1,Magic2,Hue-(HLSMAX/3))*RGBMAX + (HLSMAX/2))/HLSMAX;
end;
Result := RGB(RoundColor(R), RoundColor(G), RoundColor(B));
end;
function LightenColor(RGB: Cardinal; Percentage: Integer): Cardinal;
var
H, S, L: Word;
begin
ColorRGBToHLS(RGB, H, L, S);
L := (Cardinal(L) * Percentage) div 100;
Result := ColorHLSToRGB(H, L, S);
end;
function GetSysColor(nIndex: Integer): DWORD;
external 'GetSysColor@User32.dll stdcall';
function ColorToRGB(Color: TColor): Cardinal;
begin
if Color < 0 then
Result := GetSysColor(Color and $000000FF) else
Result := Color;
end;
用法:
LighterColor := TColor(LightenColor(ColorToRGB(Color), 150));
DarkerColor := TColor(LightenColor(ColorToRGB(Color), 75));
參考:
ColorRGBToHLS
+ ColorHLSToRGB
– VCL 源代碼Min
+ Max
– Inno Setup 在 Pascal 腳本中獲取 Min 和 Max Integer 值ColorToRGB
–將 Inno Setup WizardForm.Color 轉換為 RGBLightenColor
– 使用 Delphi 以編程方式淡化顏色
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.