我有一个Delphi XE2
项目。在我的项目中,我有MainForm
,Label01
,Label02
,Label03
,Label04
,Label05
,Label06
,{ {1}},Edit01
,Edit02
,Edit03
,Edit04
,BitBtn01
,BitBtn02
和Timer01
。
我正在尝试实施以下内容:
在Timer02
Button Click
之后,Brightness
的{{1}}将会持续增加或减少,就像'微软已完成在任务栏中的Windows 7中的任何工作后完成此操作'一样。
所以我的逻辑是:在Label01.Font.Color
上,根据名为BitBtn01.Click
的程序,Label01.Font.Color
将被转换为HSB Color Model
。如果RGBToHSV
小于100%,则会增加Brightness
。达到Timer01
达到100%后,它将递减Brightness
达25%。每当Timer02
根据名为Brightness
的程序更新Label01.Font.Color
,HSVToRGV
和Hue
保持不变。这些程序根据Saturation
工作。
根据我的要求,我写了以下代码:
Color Conversion Algorithm
所需的链接如下:
HSVToRGB程序 - hxxp://www.delphipages.com/forum/showthread.php?t = 133111
RGBToHSV程序 - hxxp://www.delphipages.com/forum/showthread.php?t = 133111
颜色转换算法 - hxxp://www.cs.rit.edu/~ncs/color/t_convert.html
将'x'替换为't'。
Here is the download link of my project
我的编码是正确的,编译得很完美。
但问题是,在运行程序几次后,unit ApplicationWizard01;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ExtCtrls, Vcl.StdCtrls, Vcl.Buttons, Math;
type
TMainForm = class(TForm)
BitBtn01: TBitBtn;
BitBtn02: TBitBtn;
Edit01: TEdit;
Edit02: TEdit;
Edit03: TEdit;
Edit04: TEdit;
Label01: TLabel;
Label02: TLabel;
Label03: TLabel;
Label04: TLabel;
Label05: TLabel;
Label06: TLabel;
Timer01: TTimer;
Timer02: TTimer;
procedure BitBtn01Click(Sender: TObject);
procedure Timer01Timer(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure BitBtn02Click(Sender: TObject);
procedure Timer02Timer(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
MainForm: TMainForm;
implementation
{$R *.dfm}
procedure HSVToRGB(Const H, S, V: Real; { 'H' In '000' To '001', 'S' In '000' To '001', 'V' In '000' To '255' }
Out R, G, B: Real); { 'R' In '000' To '255', 'G' In '000' To '255', 'B' In '000' To '255' }
const
SectionSize = 60/360;
var
F: real;
P, Q, T: real;
Section: real;
SectionIndex: integer;
begin
if H < 0 then
begin
R:= V;
G:= R;
B:= R;
end
else
begin
Section:= H/SectionSize;
SectionIndex:= Floor(Section);
F:= Section - SectionIndex;
P:= V * ( 1 - S );
Q:= V * ( 1 - S * F );
T:= V * ( 1 - S * ( 1 - F ) );
case SectionIndex 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;
else
begin
R:= V;
G:= P;
B:= Q;
end;
end;
end;
end;
procedure RGBToHSV(Const R, G, B: Real; { 'R' In '000' To '255', 'G' In '000' To '255', 'B' In '000' To '255' }
Out H, S, V: Real); { 'H' In '000' To '001', 'S' In '000' To '001', 'V' In '000' To '255' }
var
Range: real;
RGB: array[0..2] of real;
MinIndex, MaxIndex: integer;
begin
RGB[0]:= R;
RGB[1]:= G;
RGB[2]:= B;
MinIndex:= 0;
if G < R then MinIndex:= 1;
if B < RGB[MinIndex] then MinIndex:= 2;
MaxIndex:= 0;
if G > R then MaxIndex:= 1;
if B > RGB[MaxIndex] then MaxIndex:= 2;
Range:= RGB[MaxIndex] - RGB[MinIndex];
if Range = 0 then
begin
H:= 0;
S:= 0;
V:= R;
end
else
begin
case MaxIndex of
0:
begin
H:= (G-B)/Range;
end;
1:
begin
H:= 2 + (B-R)/Range;
end;
2:
begin
H:= 4 + (R-G)/Range;
end;
end;
S:= Range/RGB[MaxIndex];
V:= RGB[MaxIndex];
H:= H * (1/6);
if H < 0 then H:= 1 + H;
end;
end;
procedure TMainForm.BitBtn01Click(Sender: TObject);
begin
Timer01.Enabled := true;
end;
procedure TMainForm.BitBtn02Click(Sender: TObject);
begin
Timer01.Enabled := false;
Timer02.Enabled := false;
end;
procedure TMainForm.FormCreate(Sender: TObject);
const
HueStandardisationFactor = 360;
SaturationStandardisationFactor = 100;
BrightnessStandardisationFactor = 100/255;
var
H, S, V, R, G, B: Real;
begin
R := 98;
G := 128;
B := 33;
Label01.Font.Color := RGB(Round(R), Round(G), Round(B));
Edit01.Text := FloatToStr(Round(R)) + ' ' + FloatToStr(Round(G)) + ' ' + FloatToStr(Round(B));
RGBToHSV(R, G, B, H, S, V);
Edit02.Text := FloatToStr(Round(H*HueStandardisationFactor)) + ' ' + FloatToStr(Round(S*SaturationStandardisationFactor)) + ' ' + FloatToStr(Round(V*BrightnessStandardisationFactor));
Label02.Caption := 'Starting RGB Value : ' + '(' + FloatToStr(R) + ' ' + FloatToStr(G) + ' ' + FloatToStr(V) + ')';
Label03.Caption := 'Starting HSV Value : ' + '(' + FloatToStr(Round(H*HueStandardisationFactor)) + ' ' + FloatToStr(Round(S*SaturationStandardisationFactor)) + ' ' + FloatToStr(Round(V*BrightnessStandardisationFactor)) + ')';
end;
procedure TMainForm.Timer01Timer(Sender: TObject);
const
HueStandardisationFactor = 360;
SaturationStandardisationFactor = 100;
BrightnessStandardisationFactor = 100/255;
var
Brightness : Integer;
H1, S1, V1, R1, G1, B1: Real;
H2, S2, V2, R2, G2, B2: Real;
begin
R1 := GetRValue(Label01.Font.Color);
G1 := GetGValue(Label01.Font.Color);
B1 := GetBValue(Label01.Font.Color);
RGBToHSV(R1, G1, B1, H1, S1, V1);
Brightness := Round(V1);
Brightness := Brightness + 1;
if Brightness >= 255 then
begin
Timer01.Enabled := false;
Timer02.Enabled := true;
end;
H2 := H1;
S2 := S1;
V2 := Brightness;
Edit03.Text := FloatToStr(Round(H2*HueStandardisationFactor)) + ' ' + FloatToStr(Round(S2*SaturationStandardisationFactor)) + ' ' + FloatToStr(Round(V2*BrightnessStandardisationFactor));
HSVToRGB(H2, S2, V2, R2, G2, B2);
Label01.Font.Color := RGB(Round(R2), Round(G2), Round(B2));
Edit04.Font.Color := RGB(95, 25, 255);
Edit04.Text := FloatToStr(Round(R2)) + ' ' + FloatToStr(Round(G2)) + ' ' + FloatToStr(Round(B2));
end;
procedure TMainForm.Timer02Timer(Sender: TObject);
const
HueStandardisationFactor = 360;
SaturationStandardisationFactor = 100;
BrightnessStandardisationFactor = 100/255;
var
Brightness : Integer;
H1, S1, V1, R1, G1, B1: Real;
H2, S2, V2, R2, G2, B2: Real;
begin
R1 := GetRValue(Label01.Font.Color);
G1 := GetGValue(Label01.Font.Color);
B1 := GetBValue(Label01.Font.Color);
RGBToHSV(R1, G1, B1, H1, S1, V1);
Brightness := Round(V1);
Brightness := Brightness - 1;
if Brightness <= 25 then
begin
Timer01.Enabled := true;
Timer02.Enabled := false;
end;
H2 := H1;
S2 := S1;
V2 := Brightness;
Edit03.Text := FloatToStr(Round(H2*HueStandardisationFactor)) + ' ' + FloatToStr(Round(S2*SaturationStandardisationFactor)) + ' ' + FloatToStr(Round(V2*BrightnessStandardisationFactor));
HSVToRGB(H2, S2, V2, R2, G2, B2);
Label01.Font.Color := RGB(Round(R2), Round(G2), Round(B2));
Edit04.Font.Color := RGB(15, 135, 255);
Edit04.Text := FloatToStr(Round(R2)) + ' ' + FloatToStr(Round(G2)) + ' ' + FloatToStr(Round(B2));
end;
end.
和Hue
会发生变化(但不应该发生这种情况),尽管我已将所有必需的变量用作{ {1}}
因此颜色偏离原始颜色。
我无法找到它来应用更高的精度,以避免色移。
答案 0 :(得分:3)
您应该将原始颜色存储在某个位置并使计算始终保持该值。中间值应仅用于显示,而不用于计算下一步。转换错误往往会随着时间的推移而增加。