算法:如何使用RGB值从红色通过黄色渐变为绿色?

| 我想基于0到100的值显示颜色。一端(100)是纯红色,另一端(0)是纯绿色。在中间(50),我希望它是黄色的。 我希望颜色逐渐从一种逐渐淡入另一种,以便在75时,颜色是一半红色和一半黄色,等等。 如何编程RGB值以反映这种褪色?谢谢。     
已邀请:
        颜色的RGB值: 红色255,0,0 黄色255,255,0 绿色0、255、0 在红色和黄色之间,将您添加到绿色通道的空间平均分配,直到达到255。在黄色和绿色之间,将您从红色通道减去的空间平均分配。     
        我有同样的需求,我只是解决了这个问题:
myColor = new Color(2.0f * x, 2.0f * (1 - x), 0);
说明: 让我们关注颜色分量的[0.0-1.0]范围,而不是[0-255]范围: 绿色= 0.0、1.0、0.0 黄色= 1.0、1.0、0.0 红色= 1.0、0.0、0.0 如果仅将绿色分量从0.0(在一端)缩放到1.0(在另一端),然后对红色分量做同样的事情(但是向后移动),则会得到难看且不均匀的颜色分布。 为了使外观更好看,我们可以编写很多代码,或者可以更聪明。 如果仔细看一下单个成分,您会发现我们可以将范围分成两个相等的部分:在第一个部分中,我们将红色成分从0.0增加到1.0,将绿色保留为1.0,将蓝色保留为0.0;在第二个步骤中,我们减少绿色分量,而其余两个保持不变。通过最大化我们的值以简化代码,我们可以利用以下事实:高于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     
        这是颜色分量的非常简单的线性插值。它可能满足您的需求。
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;
}
    
        我不懂C#,所以这个答案只是建议的方法。令
x
表示note3ѭ,范围从
0
100
。这样的事情应该起作用:
red   = (x > 50 ? 1-2*(x-50)/100.0 : 1.0);
green = (x > 50 ? 1.0 : 2*x/100.0);
blue  = 0.0
这个想法是从红色开始:
(1.0,0.0,0.0)
。然后增加绿色以获得黄色::8ѭ。然后减少红色以获得绿色::9ѭ。 编辑:这是C#中的代码
static Color GetColorFromRedYellowGreenGradient(double percentage)
{
    var red = (percentage > 50 ? 1 - 2 * (percentage - 50) / 100.0 : 1.0) * 255;
    var green = (percentage > 50 ? 1.0 : 2 * percentage / 100.0) * 255;
    var blue = 0.0;
    Color result = Color.FromArgb((int)red, (int)green, (int)blue);
    return result;
}
    
        简化的扩展方法;
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);
    
        您需要改用HSB或HSV颜色表示,并使用H(\“ Hue \”)值播放。在RGB和HSB / HSV之间进行转换时,请参阅其他SO问题:如何将RGB颜色更改为HSV?     
        在尝试使用更逼真的色彩一段时间后,这是我的公式:
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)之间均匀分布的红色。     
        看一下LinearGradientBrush。它应该是您要寻找的东西的完整实现。     
        您只需要创建一个带有整数参数的函数 输入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)     专用彩色推子(int v){        返回Color.FromArgb(v,100-v,0);     }     
        今天我需要类似的东西。输入是从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);
}
    
        我使用此功能将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)\')
  }
}
    
        我为UIColor编写了一个Swift 4扩展,该扩展将百分比(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)
        }
    }
}}
    
此方法(使用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;
    }
    
        更多相同。只是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;
    
        最近,我打算使用Javascript做同样的事情。我遵循了两个步骤。 首先在0-1范围内缩放值(scaledValue =(值-最小值)/(最大值-最小值)) 如果值小于或等于0.5,则增加红色通道的值,如果值大于0.5,则减小绿色通道的值 这是我用于此目的的代码。
var blue = 0.0, red = 0.0, green = 0.0;

if(scaledValue <= 0.5)
{
    red = (scaledValue * 2) * 255.0;
    green = 255.0;
    blue = 0;
}else
{
    red = 255.0;
    green = 255.0 + 255.0 - ((scaledValue  * 2)* 255);
    blue = 0;
}
用于显示此功能的示例代码在C ++中 此解决方案的灵感来自@jterrace答案。     

要回复问题请先登录注册