为电能表生成红色和绿色之间的颜色?

我正在写一个 Java 游戏,我想实现一个功率计,来计算射击的难度。

我需要写一个在0-100之间取整数的函数,基于这个数字的大小,它将返回一个介于绿色(功率等级为0)和红色(功率等级为100)之间的颜色。

类似于音量控制的工作原理:
volume control

我需要对一个颜色的红色、绿色和蓝色组件执行什么操作来生成绿色和红色之间的颜色?

所以,我可以运行,比如说,getColor(80),它将返回一个橙色(它的值在 R,G,B 中)或者 getColor(10),它将返回一个更多的绿色/黄色 RGB 值。

我知道我需要增加一个新颜色的 R,G,B 值的组成部分,但我不知道具体什么上升或下降的颜色从绿色-红色变化。


进展:

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

我使用的函数是:

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);
}

其中“ power”是介于0.0和1.0之间的数字。0将返回一个亮红色,1.0将返回一个亮绿色。

爪哇色调图:
Java Hue Chart

92180 次浏览

这样应该可以——只需线性调整红色和绿色的值。假设您的最大红/绿/蓝值是 255,而 n0 .. 100范围内

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

(整数数学修正,向费鲁西奥致敬)

另一种方法是使用 HSV 彩色模型,并循环色调从 0 degrees(红色)到 120 degrees(绿色)的任何饱和度和价值适合你。这应该会给出一个更令人满意的渐变。

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

http://i38.tinypic.com/29o0q4k.jpg

在绿色和红色 差不多之间进行线性插值应该可以,除了中间会有泥泞的棕色。

最灵活和最好看的解决方案是有一个图像文件的地方,具有准确的颜色斜坡你想要的。然后在这里查找像素值。这有灵活性,您可以调整渐变为 刚刚好

如果您仍然希望从代码执行此操作,那么最好在左侧的绿色和黄色之间以及在右侧的黄色和红色之间进行插值。在 RGB 空间中,绿色是(R = 0,G = 255,B = 0) ,黄色是(R = 255,G = 255,B = 0) ,红色是(R = 255,G = 0,B = 0)-这是假设每个颜色成分从0到255。

你需要 线性插值(LERP)的颜色组件。给定一个开始值 V0、一个结束值 V1和所需的 比率(0.0和1.0之间的标准化浮点数) ,通常是这样做的:

v = v0 + ratio * (v1 - v0)

当比率为0.0时给出 v0,当比率为1.0时给出 v1,在其他情况下给出 v0和 v1之间的所有值。

您可以在 RGB 组件上这样做,或者使用其他配色方案,如 HSV 或 HLS。后两个将更加视觉愉悦,因为他们工作的色相和亮度组件,映射到我们的颜色感知更好。

在我的头顶上,这是 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范围。

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);
}
}

简短的复制粘贴答案..。

在爪哇标准站:

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之间的数字,表示红色到绿色的条件。

我创建了一个小函数,它给出了一个百分比值的 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,这个函数将返回所需的颜色,所以如果用百分比值循环这个函数,颜色值将从绿色变为红色。抱歉给你这么糟糕的解释

我会说你想在 HSV 空间中的线段(中间有一个稍微有点太亮的黄色)和 RGB 空间中的线段(中间有一个难看的棕色)之间找到一些东西。我会使用这个,其中 power = 0将给绿色,power = 50将给一个稍微暗黄色,和 power = 100将给红色。

blue = 0;
green = 255 * sqrt( cos ( power * PI / 200 ));
red = 255 * sqrt( sin ( power * PI / 200 ));

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)

如果你需要在 CSS (最小版本2.1)中使用这种渐变(实际上是反过来的) ,你也可以使用 HSL。

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

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

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

一篇不错的文章

维基百科理论

如果你想要一个绿色-黄色-红色的表示,就像公认的答案建议的那样,那么看看这个。

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>

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

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_factor0.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)));
}

假定 interpolationFactor0.0 ... 1.0的范围内。
假定颜色在 0 ... 255的范围内。

以下是 Swift 和 HSV 规模的复制粘贴解决方案:

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 解决方案的 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];
}

其中,level 将是一个介于 0.01.0之间的值。
希望这对谁有帮助!

JavaScript

我使用谷歌可视化与条形图,并希望条是绿色到红色的基础上的百分比。这是我找到的最干净的解决方案,效果非常好。

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,以便范围可以变得动态。结果与 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