33 votes

Comment générer des couleurs "verdâtres" aléatoires

Quelqu'un a-t-il des suggestions sur la façon de faire des couleurs aléatoires qui sont toutes verdâtres ? Pour l'instant, je génère les couleurs de cette façon :

color = (randint(100, 200), randint(120, 255), randint(100, 200))

Ça marche la plupart du temps, mais j'ai souvent des couleurs brunâtres.

54voto

theomega Points 8874

Une solution simple : Utilisez le HSL ou HSV espace couleur au lieu de rgb (convertissez-le en RGB par la suite si vous en avez besoin). La différence réside dans la signification du tuple : Là où RGB signifie des valeurs pour le rouge, le vert et le bleu, dans HSL le H est la couleur (120 degré ou 0.33 signifiant vert par exemple) et le S est pour la saturation et le V pour la luminosité. Gardez donc le H à une valeur fixe (ou pour des couleurs encore plus aléatoires, vous pouvez le rendre aléatoire en ajoutant/soustrayant un petit nombre aléatoire) et rendre aléatoire le S et le V. Voir l wikipedia article.

21voto

dbr Points 66401

Comme d'autres l'ont suggéré, il est beaucoup plus facile de générer des couleurs aléatoires dans l'espace couleur HSV (ou HSL, la différence n'a pas d'importance dans ce cas).

Il s'agit donc d'un code permettant de générer des couleurs "vertes" aléatoires et (à des fins de démonstration) de les afficher sous la forme d'une série de simples balises HTML colorées :

#!/usr/bin/env python2.5
"""Random green colour generator, written by dbr, for
http://stackoverflow.com/questions/1586147/how-to-generate-random-greenish-colors
"""

def hsv_to_rgb(h, s, v):
    """Converts HSV value to RGB values
    Hue is in range 0-359 (degrees), value/saturation are in range 0-1 (float)

    Direct implementation of:
    http://en.wikipedia.org/wiki/HSL_and_HSV#Conversion_from_HSV_to_RGB
    """
    h, s, v = [float(x) for x in (h, s, v)]

    hi = (h / 60) % 6
    hi = int(round(hi))

    f = (h / 60) - (h / 60)
    p = v * (1 - s)
    q = v * (1 - f * s)
    t = v * (1 - (1 - f) * s)

    if hi == 0:
        return v, t, p
    elif hi == 1:
        return q, v, p
    elif hi == 2:
        return p, v, t
    elif hi == 3:
        return p, q, v
    elif hi == 4:
        return t, p, v
    elif hi == 5:
        return v, p, q

def test():
    """Check examples on..
    http://en.wikipedia.org/wiki/HSL_and_HSV#Examples
    ..work correctly
    """
    def verify(got, expected):
        if got != expected:
            raise AssertionError("Got %s, expected %s" % (got, expected))

    verify(hsv_to_rgb(0, 1, 1), (1, 0, 0))
    verify(hsv_to_rgb(120, 0.5, 1.0), (0.5, 1, 0.5))
    verify(hsv_to_rgb(240, 1, 0.5), (0, 0, 0.5))

def main():
    """Generate 50 random RGB colours, and create some simple coloured HTML
    span tags to verify them.
    """
    test() # Run simple test suite

    from random import randint, uniform

    for i in range(50):
        # Tweak these values to change colours/variance
        h = randint(90, 140) # Select random green'ish hue from hue wheel
        s = uniform(0.2, 1)
        v = uniform(0.3, 1)

        r, g, b = hsv_to_rgb(h, s, v)

        # Convert to 0-1 range for HTML output
        r, g, b = [x*255 for x in (r, g, b)]

        print "<span style='background:rgb(%i, %i, %i)'>&nbsp;&nbsp;</span>" % (r, g, b)

if __name__ == '__main__':
    main()

La sortie (lorsqu'elle est visualisée dans un navigateur web) devrait ressembler à quelque chose du genre :

Example output, showing random green colours

Editar : Je ne connaissais pas le module colorsys. Au lieu de l'exemple ci-dessus hsv_to_rgb vous pouvez utiliser la fonction colorsys.hsv_to_rgb ce qui permet de raccourcir considérablement le code (il ne s'agit pas d'un remplacement direct, comme le fait mon hsv_to_rgb s'attend à ce que la teinte soit en degrés au lieu de 0-1) :

#!/usr/bin/env python2.5
from colorsys import hsv_to_rgb
from random import randint, uniform

for x in range(50):
    h = uniform(0.25, 0.38) # Select random green'ish hue from hue wheel
    s = uniform(0.2, 1)
    v = uniform(0.3, 1)

    r, g, b = hsv_to_rgb(h, s, v)

    # Convert to 0-1 range for HTML output
    r, g, b = [x*255 for x in (r, g, b)]

    print "<span style='background:rgb(%i, %i, %i)'>&nbsp;&nbsp;</span>" % (r, g, b)

16voto

Anthony Mills Points 5333

Consultez le colorsys module :

http://docs.python.org/library/colorsys.html

Utilisez l'espace couleur HSL ou HSV. Rendez la teinte aléatoire pour qu'elle soit proche du vert, puis choisissez des éléments complètement aléatoires pour la saturation et le V (luminosité).

9voto

Matt Bayliss Points 106

Si vous vous en tenez au RVB, il suffit de s'assurer que la valeur G est supérieure à la valeur R et B, et d'essayer de garder les valeurs de bleu et de rouge similaires pour que la teinte ne devienne pas trop folle. En partant de Slaks, peut-être quelque chose comme (je ne connais pratiquement rien à Python) :

greenval = randint(100, 255)
redval = randint(20,(greenval - 60))
blueval = randint((redval - 20), (redval + 20))
color = (redval, greenval, blueval)

5voto

DigitalRoss Points 80400

Dans ce cas, vous avez donc la chance de vouloir des variations sur une couleur primaire, mais pour des utilisations artistiques comme celle-ci, il est préférable de spécifier les coordonnées de la roue chromatique plutôt que les magnitudes des couleurs primaires.

Vous voulez probablement quelque chose de la colorsys module comme :

colorsys.hsv_to_rgb(h, s, v)
    Convert the color from HSV coordinates to RGB coordinates.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X