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

use*_*676 53 c# algorithm rgb

我想根据0到100之间的值显示颜色.在一端(100),它是纯红色,另一端(0),纯绿色.在中间(50),我希望它是黄色的.

而且我希望颜色逐渐从一个渐变到另一个,这样在75,颜色是半红色和半黄色等.

如何编程RGB值以反映这种衰落?谢谢.

小智 77

我有同样的需要,我刚刚解决了这个问题:

myColor = new Color(2.0f * x, 2.0f * (1 - x), 0);
Run Code Online (Sandbox Code Playgroud)

说明:让我们关注颜色分量的[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

  • 一个非常优雅的解决方案 - 值得更多的信任. (4认同)
  • 完美运行!我正在使用 python (PyQt5) 并且不得不稍微修改:`QColor(min(255,2*255*(temp)),min(255,2*255*(1-temp)),0)` (4认同)
  • 满足我们需求的出色解决方案。我们正在用Javascript计算它,从红色到白色再到绿色。当黄色分量从0.0变为1.0并通过比例尺回到0.0时,这会增加一个有趣的变化。计算结果为yellowValue = 1-Math.abs(value-0.5)* 2; (2认同)
  • @GiorgioAresu,我接受了你的原则并将它应用到了一个在这里找到的c​​odepen上的实用工具:http://codepen.io/ahopkins/full/beNWWp/ (2认同)

jte*_*ace 42

颜色的RGB值:

  • 红色255,0,0
  • 黄色255,255,0
  • 绿色0,255,0

在红色和黄色之间,同样将您添加到绿色通道中,直到它达到255.在黄色和绿色之间,同样将您的减法与红色通道隔开.

  • @Ferrybig,考虑到您的评论,正确的插值公式是什么? (2认同)

Ric*_*key 19

这是一个非常简单的颜色分量线性插值.它可能会满足您的需求.

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;
}
Run Code Online (Sandbox Code Playgroud)

  • 在Interpolate函数中,假设d2是你的目标颜色而d1是你的开始颜色,它应该是(d2 - d1)而不是(d1 - d2). (3认同)

Pen*_*One 10

我不知道C#,所以这个答案只是一个建议的方法.让x表示int,从范围0100.这样的事情应该有效:

red   = (x > 50 ? 1-2*(x-50)/100.0 : 1.0);
green = (x > 50 ? 1.0 : 2*x/100.0);
blue  = 0.0
Run Code Online (Sandbox Code Playgroud)

我的想法是从红色开始:(1.0,0.0,0.0).然后增加绿色变黄:(1.0,1.0,0.0).然后减少红色变绿:(0.0,1.0,0.0).

编辑:这是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;
}
Run Code Online (Sandbox Code Playgroud)


Vor*_*ire 7

简化的扩展方法;

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);
}
Run Code Online (Sandbox Code Playgroud)

用法;

var low = 33.0;
var high = 100.0;
var color = Color.Red.Interpolate(Color.Green, low / high);
Run Code Online (Sandbox Code Playgroud)


Sim*_*ier 5

您需要改用HSB 或 HSV 颜色表示,并使用 H(“色调”)值。请参阅此其他 SO 问题以了解 RGB 和 HSB/HSV 之间的转换:如何将 RGB 颜色更改为 HSV?


Cri*_* S. 5

在我用更逼真的颜色试验了一段时间之后,这是我的公式:

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));
}
Run Code Online (Sandbox Code Playgroud)
  • 没有背景(即Color.White)为0(或NULL),或min = max.
  • 对于所有正值,您将在RGB(240,255,240)和RGB(0,155,0)之间获得均匀分布的绿色.
  • 对于所有负值,您将在RGB(255,240,240)和RGB(230,0,0)之间获得均匀分布的红色.

热图