0

我有一个Delphi XE2项目。在我的项目中,我有MainForm, Label01, Label02, Label03, Label04, Label05, Label06, Edit01, Edit02, Edit03, Edit04, BitBtn01, BitBtn02,Timer01Timer02.

我正在尝试实现以下内容:

之后Button Click会不断增加或减少BrightnessLabel01.Font.Color就像“微软在Windows 7任务栏中完成任何工作后做了这件事”一样。

BitBtn01.Click所以我的逻辑是:Label01.Font.Color就将HSB Color Model按照程序命名为RGBToHSV. 如果Brightness小于 100%,那么它将增加Timer01。达到Brightness100% 后,将最多减少Timer0225%。每次都会根据称为保持不变的过程Brightness进行更新。这些程序根据. Label01.Font.ColorHSVToRGVHueSaturationColor Conversion Algorithm

根据我的要求,我编写了以下代码:

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.

所需链接如下:

  1. HSVToRGB 程序 - hxxp://www.delphipages.com/forum/showthread.php?t=133111

  2. RGBToHSV 程序 - hxxp://www.delphipages.com/forum/showthread.php?t=133111

  3. 颜色转换算法 - hxxp://www.cs.rit.edu/~ncs/color/t_convert.html

将“x”替换为“t”。

这是我的项目的下载链接

我的编码是正确的并且可以完美编译。

但问题是,在运行程序几次之后,HueandSaturation被改变了(但它不应该这样),尽管我已经使用了所有必需的变量 asReal

所以颜色从原来的颜色偏移了。

我无法找到它来应用更高的精度,以避免颜色偏移。

4

1 回答 1

3

您应该将原始颜色存储在某处,并始终根据该值进行计算。中间值只能用于显示,不能用于下一步的计算。转换错误往往会随着时间的推移而增加。

于 2013-07-26T19:23:05.463 回答