Подтвердить что ты не робот

Алгоритм: Как я исчезаю от красного до зеленого через желтый, используя значения RGB?

Я хочу отобразить цвет на основе значения от 0 до 100. На одном конце (100) он чистый красный, другой конец (0), чистый зеленый. В середине (50) я хочу, чтобы он был желтым.

И я хочу, чтобы цвета постепенно исчезали из одного в другое, так что в 75 цвет был наполовину красным и наполовину желтым и т.д.

Как мне запрограммировать значения RGB, чтобы отразить это затухание? Спасибо.

4b9b3361

Ответ 1

Значения RGB для цветов:

  • Красный 255, 0, 0
  • Желтый 255, 255, 0
  • Зеленый 0, 255, 0

Между красным и желтым, равномерно разместите свои добавления к зеленому каналу, пока не достигнет 255. Между желтым и зеленым, равномерно выведите ваши вычитания из красного канала.

Ответ 2

У меня была такая же потребность, и я просто решил с этим:

myColor = new Color(2.0f * x, 2.0f * (1 - x), 0);

Объяснение: Вместо диапазона [0–255] сосредоточимся на диапазоне [0,0–1,0] для цветовых компонентов:

  • Зеленый = 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; во втором мы уменьшаем зеленый компонент, оставляя остальные 2 такими, какие они есть. Мы можем воспользоваться тем фактом, что любое значение выше 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] диапазонов и все готово.

Если ваш х движется в другом диапазоне (например, [0-100]), вам нужно выбрать подходящий коэффициент вместо 2

Ответ 3

Вот очень простая линейная интерполяция цветовых компонентов. Это может удовлетворить ваши потребности.

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

Ответ 4

Я не знаю С#, поэтому этот ответ - всего лишь предлагаемый подход. Пусть x обозначает int, который находится в диапазоне от 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). Затем увеличьте зеленый цвет, чтобы получить желтый цвет: (1.0,1.0,0.0). Затем уменьшите красный цвет, чтобы получить зеленый цвет: (0.0,1.0,0.0).

Изменить: Вот код в С#

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

Ответ 5

Упрощенный метод расширения;

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

Ответ 7

После того, как я немного поэкспериментировал с более реалистичными цветами, вот моя формула:

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));
}
  • Вы не получаете фон (то есть Color.White) для 0 (или NULL), или когда min = max.
  • Для всех положительных значений вы получите равномерно распределенный зеленый цвет между RGB (240, 255, 240) и RGB (0, 155, 0).
  • Для всех отрицательных значений вы получаете равномерно распределенный красный цвет между RGB (255, 240, 240) и RGB (230, 0, 0).

heat map

Ответ 8

Взгляните на LinearGradientBrush. Это должна быть полная реализация того, что вы ищете.

Ответ 9

вам просто нужно создать функцию с целым параметром

  • вход 100 вернет RGB (100, 0, 0)
  • вход 50 будет возвращать RGB (50, 50, 0)
  • input 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)

        private Color fader(int v){
           return Color.FromArgb(v, 100-v, 0); 
        }
    

Ответ 10

Мне сегодня нужно было что-то подобное. Входной сигнал составлял от 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);
}

Ответ 11

Я отобразил значения скорости ЦП между 1400 МГц и 3500 МГц в значения 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)')
  }
}

Ответ 12

Я написал расширение Swift 4 для UIColor, которое преобразует процент (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)
        }
    }
}}

Ответ 13

Этот метод (в С#, но может быть легко переведен на другие языки) берет процент и список цветов и возвращает цвет градиента, основанный на вашем проценте. Когда вы передаете цвета, они должны быть в порядке от 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;
    }

Ответ 14

Больше того же самого. Просто 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;