unit BlendUnit;

interface

Uses
 Graphics,
 Classes,
 SysUtils;

type
  TRGB = record
   Red: Byte;
   Green: Byte;
   Blue: Byte;
  End;
  TColorList = Array of TColor;

Function BlendColors(StartColor, EndColor: TColor; BlendOver: Integer): TColorList;

implementation

Function SingleHexToInt(S: Char): Integer;
Var
 X: Integer;
begin
 X := 0;
 If S = '0' Then X := 0;
 If S = '1' Then X := 1;
 If S = '2' Then X := 2;
 If S = '3' Then X := 3;
 If S = '4' Then X := 4;
 If S = '5' Then X := 5;
 If S = '6' Then X := 6;
 If S = '7' Then X := 7;
 If S = '8' Then X := 8;
 If S = '9' Then X := 9;
 If S = 'A' Then X := 10;
 If S = 'B' Then X := 11;
 If S = 'C' Then X := 12;
 If S = 'D' Then X := 13;
 If S = 'E' Then X := 14;
 If S = 'F' Then X := 15;
 Result := X;
End;

Function HexToInt(HexValue: String): Int64;
Var
 Counter, Multiplier: Integer;
 Res: Int64;
Begin
 Multiplier := -1;
 Res := 0;
 For Counter := length(HexValue) downto 1 do begin
  Inc(Multiplier);
  If Multiplier = 0 Then Begin
   Res := Res + SingleHexToInt(HexValue[counter]);
  End
   else
  Begin
   Res := Res + SingleHexToInt(HexValue[Counter]) * (Multiplier * 16);
  End;
 End;
 Result := Res;
End;

Procedure ValiddateColor(Var S: String);
Var
 I: Integer;
Begin
 For I := 1 to 6 - length(S) do begin
  S := '0' + S;
 End;
End;

Function RGBToColor(RGB: TRGB): TColor;
Var
 R, G, B: String;
Begin
 R := IntToHex(RGB.Red, 2);
 G := IntToHex(RGB.Green, 2);
 B := IntToHex(RGB.Blue, 2);
 Result := StringToColor('$00' + R + G + B);
End;

Function BlendColors(StartColor, EndColor: TColor; BlendOver: Integer): TColorList;
Var
 StartRGB, EndRGB: TRGB;
 Long: LongInt;
 S: String;
 R, G, B: Real;
 I: Integer;
 Colors: Array of TRGB;
Begin
 SetLength(result, BlendOver);
 Setlength(colors, Blendover);
 // StartColor := StringToColor('$00FFFFFF');
 // EndColor := StringToColor('$00000000');
 // Extract Start RGB Value into StartRGB
 S := ColorToString(StartColor); // if this is a "clWhite" like color convert it to longint else convert raw
 If Not IdentToColor(S, Long) then Long := ColorToRGB(StartColor);
 S := IntToHex(Long, 3);
 ValiddateColor(S);
 StartRGB.Red := HexToInt(Copy(S, 1, 2));
 StartRGB.Green := HexToInt(Copy(S, 3, 2));
 StartRGB.Blue := HexToInt(Copy(S, 5, 2));
 // Extract Start RGB Value into StartRGB
 S := ColorToString(EndColor); // if this is a "clWhite" like color convert it to longint else convert raw
 If Not IdentToColor(S, Long) then Long := ColorToRGB(EndColor);
 S := IntToHex(Long, 3);
 ValiddateColor(S);
 EndRGB.Red := HexToInt(Copy(S, 1, 2));
 EndRGB.Green := HexToInt(Copy(S, 3, 2));
 EndRGB.Blue := HexToInt(Copy(S, 5, 2));
 // Calculate difference
 R := StartRGB.Red - EndRGB.Red;
 G := StartRGB.Green - EndRGB.Green;
 B := StartRGB.Blue - EndRGB.Blue;
 R := (R / BlendOver);
 G := (G / BlendOver);
 B := (B / BlendOver);
 Colors[0] := EndRGB;

 // Calculate Colors
 For I := 1 to BlendOver-1 do begin
// - Works most the time but have glitches
  Colors[I].Red := EndRGB.Red + Round((I+1) * R);
  Colors[I].Green := EndRGB.Green + Round((I+1) * G);
  Colors[I].Blue := EndRGB.Blue + Round((I+1) * B);

{  Colors[I].Red := Colors[I-1].Red + Round(R);
  Colors[I].Green := Colors[I-1].Green + Round(G);
  Colors[I].Blue := Colors[I-1].Blue + Round(B);
 }
 End;
 Colors[BlendOver-1] := StartRGB;
 For I := BlendOver-1 downto 0 do begin
  Result[I] := RGBToColor(Colors[I]);
 End;
End;

end.
