- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我需要生成一个渐变位图,显示用户选择的两种颜色之间的彩虹渐变。生成彩虹很容易。下面的代码是我从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 channel ,但这不起作用。事后看来,原因非常明显。假设您需要 FF0000 和 0000FF 之间的渐变。您将看到从 FF->00 转变为红色,从 00->FF 转变为蓝色。但是,彩虹渐变中没有明显存在的绿色 (00FF00)。
我需要的是一个渐变函数,我可以给出两种颜色和一个分数,然后它生成一种颜色。谁能给我指出一篇文章、算法甚至代码?
更新
NGLN 的答案是这个问题的正确答案。他和 Warren 都想知道当颜色不是明亮颜色(包含 0、$FF 和值的颜色)时该怎么办。我尝试了几个角度:放大/缩小和 HSL 插值。最后我决定选择最后一个,因为它是最简单的。
基本上有两种颜色:from
和 to
。使用 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 channel “摸索”到颜色中。
最佳答案
然后你需要计算彩虹中某种颜色的位置; 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;
上面的RainbowIndex
例程除了计算hue之外什么也没做。颜色的属性。 GraphUtil
单元提供 HSL color model 的转换例程这使得这个 RainbowIndex
例程有点过时,并提供了能够提供任何 TColor
值的优势:
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;
将彩虹切片从 clMoneyGreen
转换为 clPurple
的示例用法:
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;
关于delphi - 如何创建彩虹渐变的一部分,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19715600/
我有以下问题:写一个网页,上面有一个使用渐变颜色构建的彩虹。彩虹应倾斜一定 Angular (不应完全水平),左侧彩虹的宽度应小于右侧彩虹的宽度。 我不知道如何做宽度的部分。谁能帮帮我? #grad1
我只想使用 CSS 来创建彩虹。以下是所需内容的图片。 这是我的代码(到目前为止): * { margin: 0; padding: 0; } #r { height: 80vw; w
伴随每年 LGBT 骄傲月的到来,各大品牌都会纷纷站出来为他们推出 “Pride” 系列产品,以此表示支持。 IT之家昨日报道,苹果watchOS 6.2.5 Beta5新增4款彩虹表盘。而就
与这个问题相关 css rainbow built using gradient colors 有没有办法通过使用多个 div 而不是一个来做到这一点? 您可能会问,为什么只用一个就可以做到这一点,出
有没有一种方法可以在 rainbows/unicorn 中同时启动 faye 和 rails 应用程序。 现在我正在使用 rainbows 启动 faye/private_pub 应用程序,但也想用它
我尝试使用 matplotlib 库绘制梁的应力。 我已经使用公式计算并绘制了它作为示例: 如图 1 所示,您会看到绿色光束在元素 3 和元素 8 处具有更大的应力,因此如果我用彩虹渐变填充颜色,蓝色
我是一名优秀的程序员,十分优秀!