我正在制作与渐变相关的一小部分类型/功能,以备将来使用。我想确保至少有两个过程:ColorBetween和ColorsBetween。我可能想要在任意两种颜色(ColorsBetween)之间获得一个TColor数组,我可能只需要知道一种颜色值,两种颜色之间的百分比(ColorBetween)。
我已经在下面完成了它。除此之外,我有两个核心问题:
[???]
)以下是代码:
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
StrUtils, StdCtrls, Math;
type
TColorArray = array of TColor;
implementation
function ColorsBetween(const ColorA, ColorB: TColor; const Count: Integer): TColorArray;
var
X: Integer; //Loop counter
begin
SetLength(Result, Count);
for X:= 0 to Count - 1 do
Result[X]:= ColorBetween(ColorA, ColorB, Round((X / Count) * 100)); //Correct?
end;
function ColorBetween(const ColorA, ColorB: TColor; const Percent: Single): TColor;
var
R1, G1, B1: Byte;
R2, G2, B2: Byte;
begin
R1:= GetRValue(ColorA);
G1:= GetGValue(ColorA);
B1:= GetBValue(ColorA);
R2:= GetRValue(ColorB);
G2:= GetGValue(ColorB);
B2:= GetBValue(ColorB);
Result:= RGB(
EnsureRange(([???]), 0, 255),
EnsureRange(([???]), 0, 255),
EnsureRange(([???]), 0, 255)
);
end;
编辑:将Percent: Integer
更改为Percent: Single
以获得更流畅的效果 - 不限于100个可能的值。
答案 0 :(得分:7)
听起来你想要更换你的???与
Round((R1*Percent + R2*(100-Percent))/100.0)
代码中的EnsureRange
不是必需的,因为如果Percent
在0到100的范围内,此函数必须返回0到255范围内的值。我想我会应用{{ 1}}到EnsureRange
(强制它进入范围0.0到100.0)然后使用以下代码:
Percent
您的第一个函数返回第一个颜色为Result := RGB(
Round((R1*Percent + R2*(100-Percent))/100.0),
Round((G1*Percent + G2*(100-Percent))/100.0),
Round((B1*Percent + B2*(100-Percent))/100.0),
);
的数组。也许你会更好:
ColorA
这在数组的两端给出了相同的行为。或者您可能希望同时包含for X:= 0 to Count - 1 do
Result[X]:= ColorBetween(ColorA, ColorB, (X+1) / (Count+1) * 100.0);
和ColorA
。然后你会使用:
ColorB
但是如果你这样做,请记住Count必须大于1,否则你将除以零。那个蠢货就行了!!
不要担心性能。毫无疑问,代码可以稍快一点,但它肯定不会成为瓶颈。您将采用这些颜色并与它们一起绘制。与这些简单的例程相比,这将消耗更多的资源。
最后一点。 RGB空间中的插值对于人眼来说看起来不是特别平滑或线性的。使用浮点百分比无法回避这一事实。为了在查看时获得最佳效果,您需要在不同的色彩空间中进行插值。
答案 1 :(得分:4)
我不知道这是否是最快的方式,但它有效:
function ColorBetween(const ColorA, ColorB: TColor; const Percent: Integer): TColor;
var
R1, G1, B1: Byte;
R2, G2, B2: Byte;
begin
R1:= GetRValue(ColorA);
G1:= GetGValue(ColorA);
B1:= GetBValue(ColorA);
R2:= GetRValue(ColorB);
G2:= GetGValue(ColorB);
B2:= GetBValue(ColorB);
Result:= RGB(
Percent * (R2-R1) div 100 + R1,
Percent * (G2-G1) div 100 + G1,
Percent * (B2-B1) div 100 + B1
);
end;
function ColorsBetween(const ColorA, ColorB: TColor; const Count: Integer): TColorArray;
var
X : integer;
begin
SetLength(Result, Count);
for X := 0 to Count - 1 do
Result[X] := ColorBetween(ColorA, ColorB, Round((X / (Count-1)) * 100)); //Note: Divide by count-1
end;