我需要生成一个梯度位图,显示彩虹渐变之间的两种颜色,这是由用户选择的。生成彩虹很容易。下面的代码是我从Wiki获得的,并对其进行了稍微的修改。它具有快速、简单的优点。
function TColor_Dialog.GiveRainbowColor (fraction: double): TAlphaColor;
var
m: Double;
r, g, b, mt: Byte;
begin
if fraction <= 0 then m := 0 else
if fraction >= 1 then m := 6
else m := fraction * 6;
mt := (round (frac (m) * $FF));
case Trunc (m) of
0: begin
R := $FF;
G := mt;
B := 0;
end;
1: begin
R := $FF - mt;
G := $FF;
B := 0;
end;
2: begin
R := 0;
G := $FF;
B := mt;
end;
3: begin
R := 0;
G := $FF - mt;
B := $FF;
end;
4: begin
R := mt;
G := 0;
B := $FF;
end;
5: begin
R := $FF;
G := 0;
B := $FF - mt;
end;
end; // case
Result := ColorToQuad (r, g, b);
end; // GiveRainbowColor //
这个算法的问题是它不能在两种颜色之间显示部分彩虹。嗯,当然可以,但你必须接近每种颜色的分数,我不喜欢这样的解决方案。我试着把颜色分解成r、g、b通道,但这不起作用。事后看来,原因相当明显。假设您需要在FF0000和0000ff之间的梯度。您将从ff->00转换为红色,从00->ff转换为蓝色。然而,没有绿色(00ff00),这是清楚地出现在彩虹梯度。
我需要的是一个梯度函数,我可以给出两种颜色和一个分数,它生成一种颜色。有人能给我指一篇文章、算法甚至代码吗?
更新
NGLN的答案是这个问题的正确答案。他和沃伦都想知道当a颜色不是明亮的颜色(包含0,a$FF和a值的颜色)时该怎么办。我尝试了几个角度:向上/向下缩放和HSL插值。我终于把最后一个作为最简单的。
基本上有两种颜色:从
和到
。使用RGBtoHSL从每种颜色提取HSL参数:RGBtoHSL(col_from,hf,sf,lf)
。然后计算两种颜色之间的色调,饱和度和亮度,并重建一个新的颜色。这是NGLN在他关于色调的更新中提到的,但如果你概括这个原则,你在任何颜色之间都有彩虹。
function TColor_Dialog.interpolate_hsl (col_from, col_to: TAlphaColor; fraction: double): TAlphaColor;
var af, at, ad: uInt8;
hf, ht, hd: single;
sf, st, sd: single;
lf, lt, ld: single;
begin
// Get each rgb color channel
af := GetAValue (col_from);
at := GetAValue (col_to);
RGBtoHSL (col_from, hf, sf, lf);
RGBtoHSL (col_to, ht, st, lt);
// Compute differences
ad := af + Round (fraction * (at - af));
hd := hf + fraction * (ht - hf);
sd := sf + fraction * (st - sf);
ld := lf + fraction * (lt - lf);
Result := MakeColor (HSLtoRGB (hd, sd, ld), ad);
end; // interpolate_hsl //
这为所有可能的颜色提供了彩虹。我对不透明度应用相同的插值,因此使用MakeColor
将插值的alpha通道“摸索”到颜色中。
然后你需要计算彩虹中一种颜色的位置;GiveRainBowColor
的反面:
function RainbowIndex(BrightColor: TColor): Double;
var
R: Byte;
G: Byte;
B: Byte;
begin
R := GetRValue(ColorToRGB(BrightColor));
G := GetGValue(ColorToRGB(BrightColor));
B := GetBValue(ColorToRGB(BrightColor));
if (R * G * B <> 0) or ((R <> 255) and (G <> 255) and (B <> 255)) then
Result := -1
else if B = 0 then
if R = 255 then
Result := 0 + G / 255
else
Result := 1 + (255 - R) / 255
else if R = 0 then
if G = 255 then
Result := 2 + B / 255
else
Result := 3 + (255 - G) / 255
else { G = 0 }
if B = 255 then
Result := 4 + R / 255
else
Result := 5 + (255 - B) / 255;
Result := Result / 6;
end;
(但是,对于不同时具有0和255部分的颜色来说,这会出现一个问题。换句话说:您还需要从阴影、着色或灰色中计算亮色。请参阅下面的更新。)
从clred
到clblue
获取彩虹切片的用法示例:
procedure TForm1.FormPaint(Sender: TObject);
var
Start: Double;
Finish: Double;
X: Integer;
begin
Start := RainbowIndex(clRed);
Finish := RainbowIndex(clBlue);
for X := 0 to ClientWidth - 1 do
begin
Canvas.Brush.Color := GiveRainbowColor(0, ClientWidth - 1, X);
Canvas.FillRect(Bounds(X, 0, 1, 50));
Canvas.Brush.Color :=
GiveRainbowColor(0, ClientWidth - 1, Round(Start + (Finish - Start) * X));
Canvas.FillRect(Bounds(X, 50, 1, 50));
end;
end;
uses
GraphUtil;
const
HLSMAX = 240;
function Hue(AColor: TColor): Double;
var
Hue: Word;
Luminance: Word;
Saturation: Word;
begin
ColorRGBToHLS(ColorToRGB(AColor), Hue, Luminance, Saturation);
Result := Hue / HLSMAX;
end;
function RainbowColor(Hue: Double): TColor; overload;
begin
Hue := EnsureRange(Hue, 0, 1) * 6;
case Trunc(Hue) of
0: Result := RGB(255, Round(Frac(Hue) * 255), 0);
1: Result := RGB(255 - Round(Frac(Hue) * 255), 255, 0);
2: Result := RGB(0, 255, Round(Frac(Hue) * 255));
3: Result := RGB(0, 255 - Round(Frac(Hue) * 255), 255);
4: Result := RGB(Round(Frac(Hue) * 255), 0, 255);
else
Result := RGB(255, 0, 255 - Round(Frac(Hue) * 255));
end;
end;
function RainbowColor(MinHue, MaxHue, Hue: Integer): TColor; overload;
begin
Result := RainbowColor((Hue - MinHue) / (MaxHue - MinHue + 1));
end;
procedure TForm1.FormPaint(Sender: TObject);
var
X: Integer;
Start: Double;
Finish: Double;
begin
Start := Hue(clMoneyGreen);
Finish := Hue(clPurple);
for X := 0 to ClientWidth - 1 do
begin
Canvas.Brush.Color := RainbowColor(0, ClientWidth - 1, X);
Canvas.FillRect(Bounds(X, 0, 1, 50));
Canvas.Brush.Color :=
RainbowColor(Start + (Finish - Start) * X / ClientWidth);
Canvas.FillRect(Bounds(X, 50, 1, 50));
end;
end;
此外,RainbowColor例程可以缩短为:
function RainbowColor(Hue: Double): TColor; overload;
begin
Result := ColorHLStoRGB(Round(Hue * HLSMAX), HLSMAX div 2, HLSMAX);
end;
很难描述我在做什么。我基本上想要创建一个离散的彩虹渐变,这样对于I个JButtons的任何一行,它们上的颜色渐变都将看起来是彩虹的。 我做了以下操作,但它只创建了一个红色渐变,然后是绿色渐变,然后是蓝色渐变: 你知道我怎样才能得到某种彩虹效果吗? 谢谢 编辑: 我使用了一个正弦函数,它似乎工作的稍微好一点,但不知道如何定义它,所以我得到了一个“彩虹波”在我想要的区域:
我需要设置一个最小的Gradle 不提供任何Android选项。 我应该如何为Android创建一个最小的可编译项目? 这里的答案已经过时,对我没有任何帮助。
对于最新的布料(4.1),我似乎找不到一个很好的例子,在整个画布上或在一个对象(如矩形)上设置径向渐变。 我对线性渐变没有问题,但是让径向定位正确(我只想在中心)却让我捉摸不透。这是我尝试过的代码。 JS:
HTML5画布允许我们使用以下方法使用线性和径向渐变填充和描边形状 - Sr.No. 方法和描述 1 addColorStop(offset, color) 此方法将给定颜色的颜色停止添加到给定偏移处的渐变。 这里0.0是梯度一端的偏移量,1.0是另一端的偏移量。 2 createLinearGradient(x0, y0, x1, y1) 此方法返回CanvasGradient对象,该对象表示沿
按下按钮,灯环显示如下效果,行如彩虹。 1. 添加事件类积木 当按钮被按下时。 2. 添加灯光类积木 显示(),让灯环亮起彩虹图案。 3. 按下光环板的按钮看看吧! 下载代码
了解如何在 Illustrator 中创建不同类型的渐变。 渐变是两种或多种颜色之间或同一颜色的不同色调之间的逐渐混和。您可以利用渐变来形成颜色混合,增大矢量对象的体积,以及为图稿添加光亮或阴影的效果。在 Illustrator 中,您可以使用“渐变”面板、渐变工具或“控制”面板来创建、应用和修改渐变。 渐变类型 在 Illustrator 中,您可以创建以下三种类型的渐变: 线性渐变 利用此渐变