Pergunta

Qual é a maneira mais fácil de converter uma porcentagem em uma cor que varia de Verde (100%) a Vermelho (0%), com Amarelo para 50%?

Estou usando RGB simples de 32 bits - então cada componente é um número inteiro entre 0 e 255.Estou fazendo isso em C#, mas acho que para um problema como esse a linguagem não importa muito.

Com base nas respostas de Marius e Andy, estou usando a seguinte solução:

double red = (percent < 50) ? 255 : 256 - (percent - 50) * 5.12;
double green = (percent > 50) ? 255 : percent * 5.12;
var color = Color.FromArgb(255, (byte)red, (byte)green, 0);

Funciona perfeitamente - O único ajuste que tive que fazer na solução Marius foi usar 256, pois (255 - (por cento - 50) * 5,12 rende -1 quando 100%, resultando em Amarelo por algum motivo no Silverlight (-1, 255, 0 ) -> Amarelo ...

Foi útil?

Solução

Fiz essa função em JavaScript.Ele retorna a cor é uma string css.Toma a porcentagem como variável, com intervalo de 0 a 100.O algoritmo pode ser feito em qualquer idioma:

function setColor(p){
    var red = p<50 ? 255 : Math.round(256 - (p-50)*5.12);
    var green = p>50 ? 255 : Math.round((p)*5.12);
    return "rgb(" + red + "," + green + ",0)";
}

Outras dicas

O que você provavelmente deseja fazer é atribuir alguns pontos de 0% a 100% em um espaço de cores HSV ou HSL.A partir daí você pode interpolar cores (e o amarelo fica entre o vermelho e o verde :) e converta-os para RGB.Isso lhe dará um gradiente bonito entre os dois.

Supondo que você usará a cor como um indicador de status e do ponto de vista da interface do usuário, isso provavelmente não é uma boa ideia, já que somos muito ruins em ver pequenas mudanças na cor.Portanto, dividir o valor em, por exemplo, três a sete grupos proporcionaria diferenças mais perceptíveis quando as coisas mudam, ao custo de alguma precisão (que você provavelmente não seria capaz de avaliar de qualquer maneira).

Então, deixando de lado a matemática, no final eu recomendaria uma tabela de consulta com as seguintes cores, sendo v o valor de entrada:

#e7241d for v <= 12%
#ef832c for v > 12% and v <= 36%
#fffd46 for v > 36% and v <= 60%
#9cfa40 for v > 60% and v <= 84%
#60f83d for v > 84%

Estes foram convertidos muito ingenuamente de valores HSL (0,0, 1,0, 1,0), (30,0, 1,0, 1,0), (60,0, 1,0, 1,0), (90,0, 1,0, 1,0), (120,0, 1,0, 1,0) e você pode querer ajustar um pouco as cores para atender aos seus propósitos (alguns não gostam que o vermelho e o verde não sejam 'puros').

Por favor, veja:

Em pseudocódigo.

  • De 0 a 50%, seu valor hexadecimal seria FFxx00 onde:

    XX = ( Percentage / 50 ) * 255 converted into hex.
    
  • De 50 a 100, seu valor hexadecimal seria xxFF00, onde:

    XX = ((100-Percentage) / 50) * 255 converted into hex.  
    

Espero que ajude e seja compreensível.

Esta é uma solução agradável e limpa que melhora a resposta atualmente aceita de três maneiras:

  1. Remove o número mágico (5.12), tornando o código mais fácil de seguir.
  2. Não produzirá o erro de arredondamento que dá -1 quando a porcentagem é 100%.
  3. Permite personalizar os valores RGB mínimo e máximo usados, para que você possa produzir um intervalo mais claro ou mais escuro do que o simples rgb(255, 0, 0) - rgb(0, 255, 0).

O código mostrado é C# mas é trivial adaptar o algoritmo para qualquer outra linguagem.

private const int RGB_MAX = 255; // Reduce this for a darker range
private const int RGB_MIN = 0; // Increase this for a lighter range

private Color getColorFromPercentage(int percentage)
{
    // Work out the percentage of red and green to use (i.e. a percentage
    // of the range from RGB_MIN to RGB_MAX)
    var redPercent = Math.Min(200 - (percentage * 2), 100) / 100f;
    var greenPercent = Math.Min(percentage * 2, 100) / 100f;

    // Now convert those percentages to actual RGB values in the range
    // RGB_MIN - RGB_MAX
    var red = RGB_MIN + ((RGB_MAX - RGB_MIN) * redPercent);
    var green = RGB_MIN + ((RGB_MAX - RGB_MIN) * greenPercent);

    return Color.FromArgb(red, green, RGB_MIN);
}

Notas

Aqui está uma tabela simples mostrando alguns valores percentuais e as proporções correspondentes de vermelho e verde que queremos produzir:

VALUE   GREEN    RED       RESULTING COLOUR
 100%    100%     0%       green
  75%    100%    50%       yellowy green
  50%    100%   100%       yellow
  25%     50%   100%       orange
   0%      0%   100%       red

Espero que você possa ver claramente isso

  • o valor verde é 2x o valor percentual (mas limitado a 100)
  • o vermelho é o inverso:2x (100 - porcentagem) (mas limitado a 100)

Então, meu algoritmo calcula os valores de uma tabela parecida com esta ...

VALUE   GREEN    RED
 100%    200%     0%
  75%    150%    50%
  50%    100%   100%
  25%     50%   150%
   0%      0%   200%

...e então usa Math.Min() para limitá-los a 100%.

Eu escrevi esta função python com base no código javascript.leva uma porcentagem como decimal.também elevei o valor ao quadrado para manter as cores mais vermelhas por mais tempo na escala percentual.Também reduzi a gama de cores de 255 para 180 para dar um vermelho e verde mais escuro em cada extremidade.eles podem ser brincados para dar cores bonitas.Eu gostaria de adicionar um toque de laranja no meio, mas preciso continuar com o trabalho direito, cara.

def getBarColour(value):
    red = int( (1 - (value*value) ) * 180 )
    green = int( (value * value )* 180 )

    red = "%02X" % red
    green = "%02X" % green

    return '#' + red + green +'00'

Como o amarelo é uma mistura de vermelho e verde, você provavelmente pode começar com #F00 e deslize verde para cima até atingir #FF0, e deslize vermelho para baixo para #0F0:

for (int i = 0; i < 100; i++) {
    var red = i < 50
        ? 255
        : 255 - (256.0 / 100 * ((i - 50) * 2));
    var green = i < 50
        ? 256.0 / 100 * (i * 2)
        : 255;
    var col = Color.FromArgb((int) red, (int) green, 0);
}

Eu uso as seguintes rotinas Python para misturar cores:

def blendRGBHex(hex1, hex2, fraction):
    return RGBDecToHex(blendRGB(RGBHexToDec(hex1), 
                                RGBHexToDec(hex2), fraction))

def blendRGB(dec1, dec2, fraction):
    return [int(v1 + (v2-v1)*fraction) 
        for (v1, v2) in zip(dec1, dec2)]

def RGBHexToDec(hex):
    return [int(hex[n:n+2],16) for n in range(0,len(hex),2)]

def RGBDecToHex(dec):
    return "".join(["%02x"%d for d in dec])

Por exemplo:

>>> blendRGBHex("FF8080", "80FF80", 0.5)
"BFBF80"

Outra rotina envolve isso para combinar perfeitamente entre valores numéricos para "formatação condicional":

def colourRange(minV, minC, avgV, avgC, maxV, maxC, v):
    if v < minV: return minC
    if v > maxV: return maxC
    if v < avgV:
        return blendRGBHex(minC, avgC, (v - minV)/(avgV-minV))
    elif v > avgV:
        return blendRGBHex(avgC, maxC, (v - avgV)/(maxV-avgV))
    else:
        return avgC

Então, no caso de Jonas:

>>> colourRange(0, "FF0000", 50, "FFFF00", 100, "00FF00", 25)
"FF7F00"

Minha solução para ActionScript 3:

var red:Number = (percentage <= 50) ? 255 : 256 - (percentage - 50) * 5.12;
var green:Number = (percentage >= 50) ? 255 : percentage * 5.12;

var redHex:Number = Math.round(red) * 0x10000;
var greenHex:Number = Math.round(green) * 0x100;

var colorToReturn:uint = redHex + greenHex;

Por ser RGB, as cores vão de valores inteiros de -1 (branco) a -16777216 para preto.com vermelho, verde e amarelo em algum lugar no meio disso.Na verdade, o amarelo é -256, enquanto o vermelho é -65536 e o ​​verde é -16744448.Portanto, o amarelo na verdade não está entre o vermelho e o verde na notação RGB.Sei que em termos de comprimento de onda o verde está de um lado e o vermelho está do outro lado do espectro, mas nunca vi este tipo de notação usada em computadores, pois o espectro não representa todas as cores visíveis.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top