在红色和绿色之间为功率计生成颜色?

我正在写一个Java游戏,我想实现一个功率计,你有多难拍摄一些东西。

我需要写一个int值在0 – 100之间的函数,根据数字的高低,它会返回一个绿色(功率级别为0)和红色(功率级别为100)之间的颜色。

类似于音量控制的工作方式:
音量控制

我需要在一个颜色的红色,绿色和蓝色组件上做什么操作来生成绿色和红色之间的颜色?

所以,我可以运行getColor(80) ,它会返回一个橙色的颜色(R,G,B的值)或getColor(10) ,这将返回一个更绿/黄的RGB值。

我知道我需要为R,G,B值增加一个新颜色的成分,但是我不清楚颜色从绿 – 红变成什么颜色。


进展:

我最终使用HSV / HSB色彩空间,因为我更喜欢渐变色(中间没有深褐色)。

我使用的function是:

 public Color getColor(double power) { double H = power * 0.4; // Hue (note 0.4 = Green, see huge chart below) double S = 0.9; // Saturation double B = 0.9; // Brightness return Color.getHSBColor((float)H, (float)S, (float)B); } 

“功率”是0.0到1.0之间的数字。 0.0会返回一个鲜红的,1.0会返回一个鲜绿的。

Java色调图:
Java色调图表

这应该工作 – 只是线性缩放红色和绿色值。 假设您的最大红色/绿色/蓝色值是255 ,并且n在范围0 .. 100

 R = (255 * n) / 100 G = (255 * (100 - n)) / 100 B = 0 

(修正整math,给费鲁西奥的帽子一angular)

另一种方法是使用HSV颜色模型 ,并将色调从0 degrees (红色)到120 degrees (绿色)以任何饱和度和适合您的值循环。 这应该给一个更加愉快的梯度。

下面是每种技术的演示 – 顶部渐变使用RGB,底部使用HSV:

160wpb4.jpg

在我头顶,这里是HSV空间中的绿色 – 红色色调转换,转换为RGB:

 blue = 0.0 if 0<=power<0.5: #first, green stays at 100%, red raises to 100% green = 1.0 red = 2 * power if 0.5<=power<=1: #then red stays at 100%, green decays red = 1.0 green = 1.0 - 2 * (power-0.5) 

上面例子中的红色,绿色,蓝色值是百分比,你可能要乘以255来得到最常用的0-255范围。

短Copy'n'Paste答案…

在Java标准:

 int getTrafficlightColor(double value){ return java.awt.Color.HSBtoRGB((float)value/3f, 1f, 1f); } 

在Android上:

 int getTrafficlightColor(double value){ return android.graphics.Color.HSVToColor(new float[]{(float)value*120f,1f,1f}); } 

注意:value是介于0到1之间的数字,表示从红到绿的状态。

绿色和红色之间的线性插值几乎可以正常工作,除了中间会出现泥泞的棕色。

最灵活和最好看的解决scheme是有一个图像文件的地方有你想要的确切的颜色坡道。 然后在那里查找像素值。 这具有灵活性,您可以调整渐变恰到好处

如果你仍然想从代码中做到这一点,那么最好在左侧插入绿色和黄色,右侧插入黄色和红色。 在RGB空间中,绿色是(R = 0,G = 255,B = 0),黄色是(R = 255,G = 255,B = 0),红色是(R = 255,G = 0,B = 0 ) – 这是假定每个颜色分量从0到255。

如果你想要一个绿色,黄色,红色的表示,如接受的答案build议,然后看看这个。

http://jsfiddle.net/0awncw5u/2/

 function percentToRGB(percent) { if (percent === 100) { percent = 99 } var r, g, b; if (percent < 50) { // green to yellow r = Math.floor(255 * (percent / 50)); g = 255; } else { // yellow to red r = 255; g = Math.floor(255 * ((50 - percent % 50) / 50)); } b = 0; return "rgb(" + r + "," + g + "," + b + ")"; } function render(i) { var item = "<li style='background-color:" + percentToRGB(i) + "'>" + i + "</li>"; $("ul").append(item); } function repeat(fn, times) { for (var i = 0; i < times; i++) fn(i); } repeat(render, 100); 
 li { font-size:8px; height:10px; } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script> <ul></ul> 

我做了一个小函数,它给你一个百分比值的rgb整数值:

 private int getGreenToRedGradientByValue(int currentValue, int maxValue) { int r = ( (255 * currentValue) / maxValue ); int g = ( 255 * (maxValue-currentValue) ) / maxValue; int b = 0; return ((r&0x0ff)<<16)|((g&0x0ff)<<8)|(b&0x0ff); } 

所以如果你的currentValue是50,你的maxValue是100,这个函数将返回你需要的颜色,所以如果你用百分比值循环这个函数,你的颜色值将会从绿色变成红色。 对不起,不好的解释

接受的答案甚至没有真正回答这个问题。

C ++

以下是我的引擎中的一个简单C ++代码段,可以在三种任意颜色之间进行线性和高效插值:

 const MATH::FLOAT4 color1(0.0f, 1.0f, 0.0f, 1.0f); // Green const MATH::FLOAT4 color2(1.0f, 1.0f, 0.0f, 1.0f); // Yellow const MATH::FLOAT4 color3(1.0f, 0.0f, 0.0f, 1.0f); // Red MATH::FLOAT4 get_interpolated_color(float interpolation_factor) { const float factor_color1 = std::max(interpolation_factor - 0.5f, 0.0f); const float factor_color2 = 0.5f - fabs(0.5f - interpolation_factor); const float factor_color3 = std::max(0.5f - interpolation_factor, 0.0f); MATH::FLOAT4 color; color.x = (color1.x * factor_color1 + color2.x * factor_color2 + color3.x * factor_color3) * 2.0f; color.y = (color1.y * factor_color1 + color2.y * factor_color2 + color3.y * factor_color3) * 2.0f; color.z = (color1.z * factor_color1 + color2.z * factor_color2 + color3.z * factor_color3) * 2.0f; color.w = 1.0f; return(color); } 

interpolation_factor假定在0.0 ... 1.0的范围内。
颜色被认为是在0.0 ... 1.0的范围内(例如OpenGL)。

C#

这是用C#编写的相同函数:

 private readonly Color mColor1 = Color.FromArgb(255, 0, 255, 0); private readonly Color mColor2 = Color.FromArgb(255, 255, 255, 0); private readonly Color mColor3 = Color.FromArgb(255, 255, 0, 0); private Color GetInterpolatedColor(double interpolationFactor) { double interpolationFactor1 = Math.Max(interpolationFactor - 0.5, 0.0); double interpolationFactor2 = 0.5 - Math.Abs(0.5 - interpolationFactor); double interpolationFactor3 = Math.Max(0.5 - interpolationFactor, 0.0); return (Color.FromArgb(255, (byte)((mColor1.R * interpolationFactor1 + mColor2.R * interpolationFactor2 + mColor3.R * interpolationFactor3) * 2.0), (byte)((mColor1.G * interpolationFactor1 + mColor2.G * interpolationFactor2 + mColor3.G * interpolationFactor3) * 2.0), (byte)((mColor1.B * interpolationFactor1 + mColor2.B * interpolationFactor2 + mColor3.B * interpolationFactor3) * 2.0))); } 

interpolationFactor假定在0.0 ... 1.0的范围内。
颜色被假定为在0 ... 255的范围内。

您需要线性插值 (LERP)颜色分量。 给出一个起始值v0 ,一个终值v1和所需的比率 (一个在0.0和1.0之间的归一化浮点数):

 v = v0 + ratio * (v1 - v0) 

当比率为0.0时,给出v0,当比率为1.0时给出v1,以及在其他情况下的所有情况。

您可以在RGB组件上执行此操作,也可以使用HSV或HLS等其他颜色scheme。 后两者在视觉上更加令人愉悦,因为他们的色调和亮度配件更符合我们的色彩感知。

我想说,你需要在HSV空间中的一个线段(在中心有一个稍微太亮的黄色)和RGB空间(其中心有一个丑陋的棕色)的线段之间的东西。 我会用这个, power = 0会给绿色, power = 50会带来一点黄色, power = 100会给红色。

 blue = 0; green = 255 * sqrt( cos ( power * PI / 200 )); red = 255 * sqrt( sin ( power * PI / 200 )); 
 import java.awt.Color; public class ColorUtils { public static Color interpolate(Color start, Color end, float p) { float[] startHSB = Color.RGBtoHSB(start.getRed(), start.getGreen(), start.getBlue(), null); float[] endHSB = Color.RGBtoHSB(end.getRed(), end.getGreen(), end.getBlue(), null); float brightness = (startHSB[2] + endHSB[2]) / 2; float saturation = (startHSB[1] + endHSB[1]) / 2; float hueMax = 0; float hueMin = 0; if (startHSB[0] > endHSB[0]) { hueMax = startHSB[0]; hueMin = endHSB[0]; } else { hueMin = startHSB[0]; hueMax = endHSB[0]; } float hue = ((hueMax - hueMin) * p) + hueMin; return Color.getHSBColor(hue, saturation, brightness); } } 

如果你需要CSS(最低版本2.1)这种渐变(实际上是颠倒过来),你也可以使用HSL。

假设你在一个AngularJs模板中,值是一个从0到1的数字,你想要devise一个元素(背景或文本颜色)…

 hsl({{ value * 120}}, 50%, 35%) 

第一个值:度数(0红色,120绿色)第二个数值:饱和度(50%为中性)第三个数值:亮度(50%中性)

这里有一篇不错的文章

在这里维基百科的理论

这里是Swift和HSV规模的复制和粘贴解决scheme:

UIColor初始化程序在[0,1]中接受色调,饱和度和亮度,因此对于给定 [0,1],我们有:

 let hue: CGFloat = value / 3 let saturation: CGFloat = 1 // Or choose any let brightness: CGFloat = 1 // Or choose any let alpha: CGFloat = 1 // Or choose any let color = UIColor(hue: hue, saturation: saturation, brightness: brightness, alpha: alpha) 

这是Simucal解决scheme的Objective-C版本:

 - (UIColor*) colorForCurrentLevel:(float)level { double hue = level * 0.4; // Hue (note 0.4 = Green) double saturation = 0.9; // Saturation double brightness = 0.9; // Brightness return [UIColor colorWithHue:hue saturation:saturation brightness:brightness alpha:1.0]; } 

哪里水平将是0.01.0之间的值。
希望这可以帮助别人!

在Python 2.7中:

 import colorsys def get_rgb_from_hue_spectrum(percent, start_hue, end_hue): # spectrum is red (0.0), orange, yellow, green, blue, indigo, violet (0.9) hue = percent * (end_hue - start_hue) + start_hue lightness = 0.5 saturation = 1 r, g, b = colorsys.hls_to_rgb(hue, lightness, saturation) return r * 255, g * 255, b * 255 # from green to red: get_rgb_from_hue_spectrum(percent, 0.3, 0.0) # or red to green: get_rgb_from_hue_spectrum(percent, 0.0, 0.3) 

百分比当然是value / max_value 。 或者,如果您的比例不是从0开始,那么(value - min_value) / (max_value - min_value)

JavaScript的

我正在使用Google可视化条形图,并希望酒吧是从绿色到红色根据百分比。 这原来是我find的最干净的解决scheme,完美地工作。

 function getGreenToRed(percent){ r = percent<50 ? 255 : Math.floor(255-(percent*2-100)*255/100); g = percent>50 ? 255 : Math.floor((percent*2)*255/100); return 'rgb('+r+','+g+',0)'; } 

只要确保你的百分比是50的50%而不是 0.50。

自包含的例子

 <html> <head> <script> //-------------------------------------------------------------------------- function gradient(left, mid, right) { var obj = {} var lt50 = {"r":(mid.r-left.r)/50.0, "g":(mid.g-left.g)/50.0, "b":(mid.b-left.b)/50.0} var gt50 = {"r":(right.r-mid.r)/50.0, "g":(right.g-mid.g)/50.0, "b":(right.b-mid.b)/50.0} obj.getColor = function(percent) { if (percent == 50.0) { return mid; } if (percent < 50.0) { return "rgb("+Math.floor(left.r+lt50.r*percent+0.5)+","+ Math.floor(left.g+lt50.g*percent+0.5)+","+ Math.floor(left.b+lt50.b*percent+0.5)+")"; } var p2 = percent-50.0; return "rgb("+Math.floor(mid.r+gt50.r*p2+0.5)+","+ Math.floor(mid.g+gt50.g*p2+0.5)+","+ Math.floor(mid.b+gt50.b*p2+0.5)+")"; } return obj; } //-------------------------------------------------------------------------- var g_gradient = gradient( {"r":255, "g":20, "b":20}, // Left is red {"r":255, "g":255, "b":20}, // Middle is yellow {"r":20, "g":255, "b":20} ); // right is green //-------------------------------------------------------------------------- function updateColor() { var percent = document.getElementById('idtext').value.length; var oscore = document.getElementById('idscore'); if (percent > 100.0) { percent = 100.0; } if (percent < 0.0) { percent = 0.0; } var col = g_gradient.getColor(percent) oscore.style['background-color'] = col; oscore.innerHTML = percent + '%'; } </script> </head> <body onLoad="updateColor()"> <input size='100' placeholder='type text here' id='idtext' type="text" oninput="updateColor()" /> <br /> <br /> <div id='idscore' style='text-align:center; width:200px; border-style:solid; border-color:black; border-width:1px; height:20px;'> </div> </body> </html> 

我已经将接受的答案更新为(0,100)范围的前半部分和后半部分,并将最大值取代为100,以使范围变成dynamic的。 结果与HSV模型完全一样,但仍然使用RGB。 关键是要在(255,255,0)中间表示黄色。 我已经把这个想法和接受的答案和另一个VBA代码结合起来,所以在VBA中实现它,并在Excel中使用。 我希望这个逻辑有帮助,可以在其他语言/应用程序中使用。

 Sub UpdateConditionalFormatting(rng As Range) Dim cell As Range Dim max As Integer max = WorksheetFunction.max(rng) For Each cell In rng.Cells If cell.Value >= 0 And cell.Value < max / 2 Then cell.Interior.Color = RGB(255 * cell.Value / (max / 2), 255, 0) ElseIf cell.Value >= max / 2 And cell.Value <= max Then cell.Interior.Color = RGB(255, 255 * ((max) - cell.Value) / (max / 2), 0) End If Next cell End Sub 

干杯,Pavlin

这将从红色到黄色,然后是绿色
值从0到100不等

 -(UIColor*) redToGreenColorWithPosition:(int) value { double R, G; if (value > 50) { R = (255 * (100 - value)/ 50) ; G = 255; }else { R = 255; G = (255 * (value*2)) / 100; } return [UIColor colorWithRed:R/255.0f green:G/255.0f blue:0.0f alpha:1.0f]; } 

VB

 Public Function GetPercentageColor( _ ByVal iPercent As Long, Optional _ ByVal bOpposit As Boolean) As Long ' 0->100% - Green->Yellow->Red ' bOpposit - Red->Yellow->Green If bOpposit Then iPercent = (100 - iPercent) Select Case iPercent Case Is < 1: GetPercentageColor = 65280 ' RGB(0, 255, 0) Case Is > 99: GetPercentageColor = 255 ' RGB(255, 0, 0) Case Is < 50: GetPercentageColor = RGB(255 * iPercent / 50, 255, 0) Case Else: GetPercentageColor = RGB(255, (255 * (100 - iPercent)) / 50, 0) End Select End Function