Генерировать цвета между красным и зеленым для измерителя мощности? - PullRequest
133 голосов
/ 04 декабря 2008

Я пишу 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.0 вернет ярко-красный, 1.0 вернет ярко-зеленый.

Диаграмма оттенка Java:
Java Hue Chart

Ответы [ 19 ]

1 голос
/ 25 июня 2015

Вот решение копирования и вставки для весов 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)
1 голос
/ 05 октября 2014

В 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).

1 голос
/ 05 июля 2011
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);
    }
}
1 голос
/ 01 февраля 2016

JavaScript

Я использую Google Visualization с гистограммой и хотел, чтобы столбцы были зелеными или красными в процентах. Это оказалось самым чистым решением, которое я нашел, и оно отлично работает.

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.

1 голос
/ 24 января 2015

Если вам нужен этот вид градиента (фактически обратный) в CSS (мин. Версия 2.1), вы также можете использовать HSL.

Предположим, вы находитесь в шаблоне AngularJs, а значение является числом от 0 до 1, и вы хотите стилизовать элемент (цвет фона или текста) ...

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

Первое значение: градусы (0 красных, 120 зеленых) Второе значение: насыщенность (50% нейтрально) Третье значение: легкость (нейтральность 50%)

Хорошая статья здесь

Теория в Википедии здесь

0 голосов
/ 04 апреля 2017

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
0 голосов
/ 09 декабря 2016

Я обновил принятый ответ, разделив его на первую и вторую половину диапазона (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

Ура, Павлин

0 голосов
/ 17 марта 2017

Это будет варьироваться от красного до желтого, а затем до зеленого
значение варьируется от 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];
}
0 голосов
/ 03 февраля 2016

Автономный пример

<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>
...