web-dev-qa-db-ja.com

アルゴリズム:RGB値を使用して、黄色から赤色を経て緑色にフェードインするにはどうすればよいですか?

0〜100の値に基づいて色を表示します。一方の端(100)で純粋な赤、もう一方の端(0)で純粋な緑です。中央(50)では、黄色にしたいです。

そして、75で色が半分赤と半分黄色になるように、色が次第にフェードするようにします。

このフェージングを反映するようにRGB値をプログラムするにはどうすればよいですか?ありがとう。

51
user776676

色のRGB値:

  • 赤255、0、0
  • 黄色255、255、0
  • 緑0、255、0

赤と黄色の間で、緑チャンネルへの追加を255に達するまで均等に配置します。黄色と緑の間で、赤チャンネルからの減算を均等に配置します。

41
jterrace

同じニーズがあり、これで解決しました:

myColor = new Color(2.0f * x, 2.0f * (1 - x), 0);

説明:[0-255]範囲の代わりに、色成分の[0.0-1.0]範囲に注目しましょう。

  • 緑= 0.0、1.0、0.0
  • 黄色= 1.0、1.0、0.0
  • 赤= 1.0、0.0、0.0

緑のコンポーネントを0.0(一方の端)から1.0(もう一方の端)にスケーリングし、赤のコンポーネントで同じことを行う(ただし逆方向に移動する)と、い不均一な色分布になります。

見た目を良くするために、たくさんのコードを書くか、もっと賢くすることができます。

単一のコンポーネントを注意深く見ると、範囲を2つの等しい部分に分割できることがわかります。最初の部分では、赤のコンポーネントを0.0から1.0に増やし、緑を1.0、青を0.0のままにします。 2番目では、緑のコンポーネントを減らし、残りの2つをそのままにします。コードを簡素化するために値を最大化することにより、1.0を超える値は1.0として読み取られるという事実を利用できます。 x値が0.00(0%)から1.00(100%)になると仮定すると、2を掛けて、色成分の1.0制限を超えることができます。これで、コンポーネントが0.0から2.0(赤のコンポーネント)および2.0から0.0(赤のコンポーネント)になりました。それらを[0.0-1.0]の範囲にクリップし、そこに行きます。

Xが別の範囲([0-100]など)で移動する場合、2ではなく適切な係数を選択する必要があります

72
Giorgio Aresu

これは、色成分の非常に単純な線形補間です。それはあなたのニーズを満たすかもしれません。

public Color GetBlendedColor(int percentage)
{
    if (percentage < 50)
        return Interpolate(Color.Red, Color.Yellow, percentage / 50.0);
    return Interpolate(Color.Yellow, Color.Lime, (percentage - 50) / 50.0);
}

private Color Interpolate(Color color1, Color color2, double fraction)
{
    double r = Interpolate(color1.R, color2.R, fraction);
    double g = Interpolate(color1.G, color2.G, fraction);
    double b = Interpolate(color1.B, color2.B, fraction);
    return Color.FromArgb((int)Math.Round(r), (int)Math.Round(g), (int)Math.Round(b));
}

private double Interpolate(double d1, double d2, double fraction)
{
    return d1 + (d2 - d1) * fraction;
}
19
Rick Sladkey

簡易拡張メソッド。

public static Color Interpolate(this Color source, Color target, double percent)
{
    var r = (byte)(source.R + (target.R - source.R) * percent);
    var g = (byte)(source.G + (target.G - source.G) * percent);
    var b = (byte)(source.B + (target.B - source.B) * percent);

    return Color.FromArgb(255, r, g, b);
}

使用法;

var low = 33.0;
var high = 100.0;
var color = Color.Red.Interpolate(Color.Green, low / high);
7
Vorspire

より現実的な色でしばらく実験した後、ここに私の式があります:

public Color GetColorOf(double value, double minValue, double maxValue)
{
    if (value == 0 || minValue == maxValue) return Color.White;

    var g = (int)(240 * value / maxValue);
    var r = (int)(240 * value / minValue);

    return (value > 0
        ? Color.FromArgb(240 - g, 255 - (int)(g * ((255 - 155) / 240.0)), 240 - g)
        : Color.FromArgb(255 - (int)(r * ((255 - 230) / 240.0)), 240 - r, 240 - r));
}
  • 0(またはNULL)の場合、またはmin = maxの場合、背景(つまり、Color.White)はありません。
  • すべての正の値について、RGB(240、255、240)とRGB(0、155、0)の間で均等に分散された緑色を取得します。
  • すべての負の値について、RGB(255、240、240)とRGB(230、0、0)の間で均等に分布した赤色を取得します。

heat map

4
Cristi S.

代わりに HSBまたはHSVカラー表現 を使用し、H( "Hue")値で遊ぶ必要があります。この他のSO RGBとHSB/HSV間の変換に関する質問: RGBカラーをHSVに変更する方法?

4
Simon Mourier

LinearGradientBrush を見てください。探しているものを完全に実装する必要があります。

1
PedroC88

Swift 4 UIColorの拡張機能を作成しました。これは、パーセンテージ(0-100)を赤から緑にUIColorに変換します。

現在、分析アプリの進行状況バーに使用しています。以下に例を示します。

let myNewColor = UIColor().greenRedProgress(percent: Int))

拡張機能は次のとおりです。

extension UIColor{

func greenRedProgress(percent: Int) -> UIColor{
    let modVal = CGFloat((Double(percent).truncatingRemainder(dividingBy: 50) / 50) * 255)
    if percent <= 0{
        return UIColor(red: 1.0, green: 0, blue: 0, alpha: 1)
    }else if percent >= 100{
        return UIColor(red: 0, green: 1.0, blue: 0, alpha: 1)
    }else{
        switch percent{
            case 1..<50: return UIColor(red: 1.0, green: (modVal/255), blue: 0, alpha: 1)
            case 51..<100: return UIColor(red: (255 - modVal)/255, green: 1.0, blue: 0, alpha: 1)
            case 50: return UIColor(red: 1.0, green: 1.0, blue: 0, alpha: 1)
            default: return UIColor(red: 0, green: 1.0, blue: 0, alpha: 1)
        }
    }
}}
0
Jordan

この機能を使用して、緑->黄->赤から取得するために、1400 MHz〜3500 MHzのCPU速度の値をrgb()値にマッピングしました。

function green_yellow_red(core_MHz, core_id){
  var core_color = ~~core_MHz.map(1400, 3500, 0, 510)

  if(core_color < 255){
    $('#cpu_core_'+core_id).css('background', 'rgb('+core_color+',255 , 0)')
  }else{
    core_color-=255
    $('#cpu_core_'+core_id).css('background', 'rgb(255 ,'+ (255-core_color) +', 0)')
  }
}
0
Barrard

今日は似たようなものが必要でした。入力は0.0から1.0のパーセントで、出力は赤から緑でした。 jterraceの答えに基づく実装:

Color percentToColor(float percent)
{
    if (percent<0 || percent>1) { return Color.Black; }

    int r, g;
    if (percent<0.5)
    {
        r=255;
        g = (int)(255*percent/0.5);  //closer to 0.5, closer to yellow (255,255,0)
    }
    else
    {
        g=255;
        r = 255 - (int)(255*(percent-0.5)/0.5); //closer to 1.0, closer to green (0,255,0)
    }
    return Color.FromArgb(r, g, 0);
}
0
icy

同じのより。 Delphi Pascalをコード化して簡略化し、セマフォの色(赤/黄/緑)にロックします。

rectangle1.Fill.Color:=DefineColorSemaphore(newcolor);

function TForm1.DefineColorSemaphore(valperc:integer):TAlphaColor;
var
   vcol: TAlphaColorRec;
begin
  vcol.B := 0;    // blue:  always 0
  vcol.A := 255;  // alpha: 255=no
  if (valperc < 50) then
    begin
       // starts @ RGB=255,0,0 and increases G 0->255
       vcol.R := 255;
       vcol.G := trunc(255*valperc/50);
    end
    else
    begin
       // starts @ RGB=255,255,0 and decreases R 255->0
       vcol.R := 255-trunc(255* (valperc - 50)/50);
       vcol.G := 255;
    end;
  result:= TAlphaColor(vcol);
end;
0
Orison Almeida

このメソッド(c#ですが、他の言語に簡単に翻訳できます)は、パーセンテージと色のリストを取得し、パーセンテージに基づいてグラデーションの色を返します。色を渡すときは、値が0から100までの順序である必要があります(したがって、緑、黄、赤をこの順序で渡します)。真ん中に別の色や複数の色が必要な場合は、表示したい順序で渡す色のリストに追加してください。

public Color ColorBasedOnPercent(decimal percent, params Color[] colors)
    {
        if (colors.Length == 0)
        {
            //I am using Transparent as my default color if nothing was passed
            return Color.Transparent;
        }
        if (percent > 1)
        {
            percent = percent / 100;
        }

        //find the two colors within your list of colors that the percent should fall between
        var colorRangeIndex = (colors.Length - 1) * percent;
        var minColorIndex = (int)Math.Truncate(colorRangeIndex);
        var maxColorIndex = minColorIndex + 1;
        var minColor = colors[minColorIndex];

        if (maxColorIndex < colors.Length)
        {
            var maxColor = colors[maxColorIndex];

            //get the differences between all the color values for the two colors you are fading between
            var aScale = maxColor.A - minColor.A;
            var redScale = maxColor.R - minColor.R;
            var greenScale = maxColor.G - minColor.G;
            var blueScale = maxColor.B - minColor.B;

            //the decimal distance of how "far" this color should be from the minColor in the range
            var gradientPct = colorRangeIndex - minColorIndex;

            //for each piece of the color (ARGB), add a percentage(gradientPct) of the distance between the two colors
            int getRGB(int originalRGB, int scale) => (int)Math.Round(originalRGB + (scale * gradientPct));

            return Color.FromArgb(getRGB(minColor.A, aScale), getRGB(minColor.R, redScale), getRGB(minColor.G, greenScale), getRGB(minColor.B, blueScale));
        }
        return minColor;
    }
0
Chaya Sulman

あなたは整数パラメータで関数を作成する必要があります

  • 入力100はRGB(100、0、0)を返します
  • 入力50はRGB(50、50、0)を返します
  • 入力0はRGB(0、100、0)を返します
  • 入力99はRGB(99、1、0)を返します
  • 入力98はRGB(98、2、0)を返します
  • 入力2はRGB(2、98、0)を返します
  • 入力1はRGB(1、99、0)を返します

     private Color fader(int v){
     return Color.FromArgb(v、100-v、0); 
    } 
    
0
Tun Zarni Kyaw