ユーザーが選択した 2 つの色の間の虹色のグラデーションを表示するグラデーション ビットマップを生成する必要があります。虹を生成するのは簡単です。以下のコードは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 //
このアルゴリズムの問題点は、2 つの色の間の部分的な虹を表示できないことです。もちろん、それは可能ですが、各色の割合に近づく必要があり、私はその解決策が好きではありません. 色を r、g、b チャンネルに分解しようとしましたが、うまくいきませんでした。その理由は後から考えれば明らかです。FF0000 と 0000FF の間のグラデーションが必要だとします。FF->00 から赤色に変換し、00->FF から青色に変換します。ただし、虹のグラデーションにはっきりと存在する緑 (00FF00) はありません。
私が必要としているのは、2 つの色と分数を与えることができ、色を生成するグラデーション関数です。誰か記事、アルゴリズム、さらにはコードを教えてもらえますか?
アップデート
NGLN の回答は、この質問に対する正解です。彼とウォーレンはどちらも、色が明るい色 (0、$FF、および値を含む色)ではない場合にどうすればよいか疑問に思いました。アップ/ダウンスケーリングとHSL補間など、いくつかの角度を試しました。私は最終的に、最も単純なものとして最後のものに落ち着きました。
基本的に、 と の 2 つの色が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
て、補間されたアルファ チャネルを色に「いじる」ことができます。