Fonction de mise à l'échelle des couleurs
-
05-07-2019 - |
Question
J'essaie de visualiser certaines valeurs sur un formulaire. Ils vont de 0 à 200 et je voudrais que ceux autour de 0 soient verts et deviennent rouge vif à 200.
En principe, la fonction devrait renvoyer une couleur en fonction de la valeur entrée. Des idées?
La solution
En gros, la méthode générale pour une transition en douceur entre deux valeurs est la fonction suivante:
function transition(value, maximum, start_point, end_point):
return start_point + (end_point - start_point)*value/maximum
Cela dit, vous définissez une fonction qui effectue la transition pour les triplets (RVB, HSV, etc.).
function transition3(value, maximum, (s1, s2, s3), (e1, e2, e3)):
r1= transition(value, maximum, s1, e1)
r2= transition(value, maximum, s2, e2)
r3= transition(value, maximum, s3, e3)
return (r1, r2, r3)
En supposant que vous ayez des couleurs RVB pour les triplets s et e , vous pouvez utiliser la fonction de transition3 telle quelle. Cependant, le fait de passer par l’espace chromatique HSV produit plus de données "naturelles". les transitions. Donc, étant donné les fonctions de conversion (volées sans vergogne dans le module colorsys de Python et converties en pseudocode:):
function rgb_to_hsv(r, g, b):
maxc= max(r, g, b)
minc= min(r, g, b)
v= maxc
if minc == maxc then return (0, 0, v)
diff= maxc - minc
s= diff / maxc
rc= (maxc - r) / diff
gc= (maxc - g) / diff
bc= (maxc - b) / diff
if r == maxc then
h= bc - gc
else if g == maxc then
h= 2.0 + rc - bc
else
h = 4.0 + gc - rc
h = (h / 6.0) % 1.0 //comment: this calculates only the fractional part of h/6
return (h, s, v)
function hsv_to_rgb(h, s, v):
if s == 0.0 then return (v, v, v)
i= int(floor(h*6.0)) //comment: floor() should drop the fractional part
f= (h*6.0) - i
p= v*(1.0 - s)
q= v*(1.0 - s*f)
t= v*(1.0 - s*(1.0 - f))
if i mod 6 == 0 then return v, t, p
if i == 1 then return q, v, p
if i == 2 then return p, v, t
if i == 3 then return p, q, v
if i == 4 then return t, p, v
if i == 5 then return v, p, q
//comment: 0 <= i <= 6, so we never come here
, vous pouvez avoir le code suivant:
start_triplet= rgb_to_hsv(0, 255, 0) //comment: green converted to HSV
end_triplet= rgb_to_hsv(255, 0, 0) //comment: accordingly for red
maximum= 200
… //comment: value is defined somewhere here
rgb_triplet_to_display= hsv_to_rgb(transition3(value, maximum, start_triplet, end_triplet))
Autres conseils
Vous ne dites pas dans quel environnement vous faites cela. Si vous pouvez utiliser les couleurs HSV , ce serait assez facile à faire en définissant S = 100. et V = 100 et en déterminant H par:
H = 0.4 * value + 120
La conversion de HSV en RVB est également assez facile.
[EDIT] Remarque: contrairement à d’autres solutions proposées, la couleur sera verte - > jaune - > orange - > rouge.
red = (float)val / 200 * 255;
green = (float)(200 - val) / 200 * 255;
blue = 0;
return red << 16 + green << 8 + blue;
Choisissez un vert que vous aimez (RGB1 = # 00FF00, par exemple) et un rouge que vous aimez (RGB2 = # FF0000, par exemple), puis calculez la couleur comme ceci
R = R1 * (200-i)/200 + R2 * i/200
G = G1 * (200-i)/200 + G2 * i/200
B = B1 * (200-i)/200 + B2 * i/200
Pour un effet optimal et contrôlable, vous devez utiliser l’espace colorimétrique HSV. Avec le HSV, vous pouvez facilement faire varier la teinte, la saturation et / ou la luminosité les unes des autres. Ensuite, vous effectuez la transformation en RVB.
Étendre le code de @ tzot ... vous pouvez également définir un point intermédiaire entre les points de début et de fin, ce qui peut être utile si vous souhaitez une "couleur de transition"!
//comment: s = start_triplet, m = mid_triplet, e = end_triplet
function transition3midpoint = (value, maximum, s, m, e):
mid = maximum / 2
if value < mid
return transition3(value, mid, s, m)
else
return transition3(value - mid, mid, m, e)
En parcourant cet article de Wikipédia , je choisirais personnellement un chemin d'accès dans un espace de couleur, et mappez les valeurs sur ce chemin.
Mais c'est une fonction simple. Je pense que vous conviendrez peut-être mieux à un sélecteur de couleur javascript que vous pourrez trouver avec une couleur rapide qui vous donnera le Hex, et vous pouvez stocker le Hex.
Si vous utilisez des rampes linéaires pour les valeurs rouge et verte comme Peter Parker l'a suggéré, la couleur de la valeur 100 sera essentiellement vert vomi (127, 127, 0). Vous voulez idéalement que ce soit un orange vif ou un jaune à ce point médian. Pour cela, vous pouvez utiliser:
Red = max(value / 100, 1) * 255
Green = (1 - max(value / 100, 1)) * 255
Blue = 0