Algorithme pour générer au hasard une palette de couleurs agréable sur le plan esthétique [fermé]

je cherche un algorithme simple pour générer un grand nombre de couleurs aléatoires et esthétiquement agréables. Donc pas de couleurs folles au néon, des couleurs qui rappellent les excréments,etc.

j'ai trouvé des solutions à ce problème mais ils s'appuient sur des palettes de couleurs alternatives que RGB. Je préfère utiliser le RGB direct plutôt que de faire des allers-retours. Ces autres solutions peuvent générer seulement 32 ou si agréable des couleurs aléatoires.

Toutes les idées seraient grand.

279
demandé sur Alex L 2008-09-04 05:54:12

16 réponses

vous pouvez faire la moyenne des valeurs RVB de couleurs aléatoires avec celles d'une couleur constante:

(exemple en Java)

public Color generateRandomColor(Color mix) {
    Random random = new Random();
    int red = random.nextInt(256);
    int green = random.nextInt(256);
    int blue = random.nextInt(256);

    // mix the color
    if (mix != null) {
        red = (red + mix.getRed()) / 2;
        green = (green + mix.getGreen()) / 2;
        blue = (blue + mix.getBlue()) / 2;
    }

    Color color = new Color(red, green, blue);
    return color;
}



Le mélange de couleurs aléatoires avec le blanc (255, 255, 255) crée des pastels neutres en augmentant la légèreté tout en gardant la teinte de la couleur originale. Ces pastels générés au hasard vont généralement bien ensemble, surtout en grand nombre.

Voici quelques couleurs pastel générées en utilisant la méthode ci-dessus:

First



Vous pouvez également mélanger la couleur au hasard avec un pastel constant, ce qui donne un ensemble teinté de couleurs neutres. Par exemple, l'utilisation d'un bleu clair crée des couleurs comme celles-ci:

Second



En allant plus loin, vous pourriez ajouter heuristique à votre générateur qui prend en compte les couleurs complémentaires ou les niveaux d'ombrage, mais tout dépend de l'impression que vous voulez obtenir avec vos couleurs aléatoires.

Quelques ressources supplémentaires:

402
répondu David Crow 2012-04-02 08:37:49

j'utiliserais une roue de couleur et donné une position aléatoire vous pourriez ajouter l'angle d'or (137,5 degrés)

http://en.wikipedia.org/wiki/Golden_angle

afin d'obtenir des couleurs différentes à chaque fois, qui ne se chevauchent pas.

ajustement de la luminosité pour la roue de couleur, vous pourriez obtenir également différentes combinaisons de couleurs claires/sombres.

j'ai trouvé ce billet de blog que explique vraiment bien le problème et la solution en utilisant le ratio d'or.

http://martin.ankerl.com/2009/12/09/how-to-create-random-colors-programmatically /

mise à JOUR: je viens de trouver cette autre approche:

c'est la méthode RYB(rouge, jaune, bleu) et elle est décrite dans cet article:

http://threekings.tk/mirror/ryb_TR.pdf

que "Peinture de Couleurs Inspirée de Compositing".

L'algorithme génère les couleurs et chaque couleur est choisie de manière à maximiser sa distance euclidienne sélectionné précédemment.

Ici vous pouvez trouver une bonne implémentation en javascript:

http://afriggeri.github.com/RYB /

mise à JOUR 2:

les Sciences Po Medialb viennent de sortir un outil appelé" I want Hue " qui génère des palettes de couleurs pour les scientifiques de données. En utilisant des espaces de couleurs différentes et en générant les palettes en utilisant k-means clustering ou Vecteurs de force ( graphiques de répulsion) les résultats de ces méthodes sont très bons, ils montrent la théorie et une mise en œuvre dans leur page web.

http://tools.medialab.sciences-po.fr/iwanthue/index.php

81
répondu Fgblanch 2013-02-12 11:26:22

en javascript:

function pastelColors(){
    var r = (Math.round(Math.random()* 127) + 127).toString(16);
    var g = (Math.round(Math.random()* 127) + 127).toString(16);
    var b = (Math.round(Math.random()* 127) + 127).toString(16);
    return '#' + r + g + b;
}

a vu l'idée ici: http://blog.functionalfun.net/2008/07/random-pastel-colour-generator.html

23
répondu motobói 2012-09-04 15:05:23

la conversion à une autre palette est une façon bien supérieure de le faire. Il y a une raison pour laquelle ils font cela: d'autres palettes sont 'perceptuelles' - c'est-à-dire qu'ils mettent des couleurs apparentes similaires étroitement ensemble, et en ajustant une variable change la couleur d'une manière prévisible. Rien de tout cela n'est vrai pour le RGB, où il n'y a pas de relation évidente entre des couleurs qui "vont bien ensemble".

9
répondu Nick Johnson 2009-06-07 20:45:33

une réponse qui ne devrait pas être négligée, parce que c'est simple et présente des avantages, est l'échantillonnage de photos et de peintures de la vie réelle. échantillonnez autant de pixels aléatoires que vous voulez des couleurs aléatoires sur les vignettes des photos d'art moderne, Cezanne, van gogh, monnet, photos... l'avantage est que vous pouvez obtenir des couleurs par thème et qu'ils sont organiques couleurs. il suffit de mettre 20 à 30 photos dans un dossier et de prélever au hasard une photo à chaque fois.

la Conversion en valeurs HSV est généralisée code de l'algorithme pour psychologiquement base de la palette. le VHS est plus facile à randomiser.

4
répondu com.prehensible 2013-08-16 08:59:14

en php:

function pastelColors() {
    $r = dechex(round(((float) rand() / (float) getrandmax()) * 127) + 127);
    $g = dechex(round(((float) rand() / (float) getrandmax()) * 127) + 127);
    $b = dechex(round(((float) rand() / (float) getrandmax()) * 127) + 127);

    return "#" . $r . $g . $b;
}

source: https://stackoverflow.com/a/12266311/2875783

4
répondu Petr Bugyík 2017-05-23 12:18:22

j'ai eu du succès en utilisant TriadMixing et CIE94 pour éviter des couleurs similaires. L'image suivante utilise les couleurs d'entrée rouge, jaune et blanc. Voir ici .

TriadMixing + CIE94

4
répondu Moriarty 2018-03-22 03:24:17

Voici quick and dirty color generator en C# (en utilisant 'RYB approach' décrit dans cet article ). C'est une réécriture de JavaScript .

utilisation:

List<Color> ColorPalette = ColorGenerator.Generate(30).ToList();

les deux premières couleurs ont tendance à être le blanc et une nuance de noir. Je les saute souvent comme ceci (en utilisant Linq):

List<Color> ColorsPalette = ColorGenerator
            .Generate(30)
            .Skip(2) // skip white and black
            .ToList(); 

mise en Œuvre:

public static class ColorGenerator
{

    // RYB color space
    private static class RYB
    {
        private static readonly double[] White = { 1, 1, 1 };
        private static readonly double[] Red = { 1, 0, 0 };
        private static readonly double[] Yellow = { 1, 1, 0 };
        private static readonly double[] Blue = { 0.163, 0.373, 0.6 };
        private static readonly double[] Violet = { 0.5, 0, 0.5 };
        private static readonly double[] Green = { 0, 0.66, 0.2 };
        private static readonly double[] Orange = { 1, 0.5, 0 };
        private static readonly double[] Black = { 0.2, 0.094, 0.0 };

        public static double[] ToRgb(double r, double y, double b)
        {
            var rgb = new double[3];
            for (int i = 0; i < 3; i++)
            {
                rgb[i] = White[i]  * (1.0 - r) * (1.0 - b) * (1.0 - y) +
                         Red[i]    * r         * (1.0 - b) * (1.0 - y) +
                         Blue[i]   * (1.0 - r) * b         * (1.0 - y) +
                         Violet[i] * r         * b         * (1.0 - y) +
                         Yellow[i] * (1.0 - r) * (1.0 - b) *        y +
                         Orange[i] * r         * (1.0 - b) *        y +
                         Green[i]  * (1.0 - r) * b         *        y +
                         Black[i]  * r         * b         *        y;
            }

            return rgb;
        }
    }

    private class Points : IEnumerable<double[]>
    {
        private readonly int pointsCount;
        private double[] picked;
        private int pickedCount;

        private readonly List<double[]> points = new List<double[]>();

        public Points(int count)
        {
            pointsCount = count;
        }

        private void Generate()
        {
            points.Clear();
            var numBase = (int)Math.Ceiling(Math.Pow(pointsCount, 1.0 / 3.0));
            var ceil = (int)Math.Pow(numBase, 3.0);
            for (int i = 0; i < ceil; i++)
            {
                points.Add(new[]
                {
                    Math.Floor(i/(double)(numBase*numBase))/ (numBase - 1.0),
                    Math.Floor((i/(double)numBase) % numBase)/ (numBase - 1.0),
                    Math.Floor((double)(i % numBase))/ (numBase - 1.0),
                });
            }
        }

        private double Distance(double[] p1)
        {
            double distance = 0;
            for (int i = 0; i < 3; i++)
            {
                distance += Math.Pow(p1[i] - picked[i], 2.0);
            }

            return distance;
        }

        private double[] Pick()
        {
            if (picked == null)
            {
                picked = points[0];
                points.RemoveAt(0);
                pickedCount = 1;
                return picked;
            }

            var d1 = Distance(points[0]);
            int i1 = 0, i2 = 0;
            foreach (var point in points)
            {
                var d2 = Distance(point);
                if (d1 < d2)
                {
                    i1 = i2;
                    d1 = d2;
                }

                i2 += 1;
            }

            var pick = points[i1];
            points.RemoveAt(i1);

            for (int i = 0; i < 3; i++)
            {
                picked[i] = (pickedCount * picked[i] + pick[i]) / (pickedCount + 1.0);
            }

            pickedCount += 1;
            return pick;
        }

        public IEnumerator<double[]> GetEnumerator()
        {
            Generate();
            for (int i = 0; i < pointsCount; i++)
            {
                yield return Pick();
            }
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }
    }

    public static IEnumerable<Color> Generate(int numOfColors)
    {
        var points = new Points(numOfColors);

        foreach (var point in points)
        {
            var rgb = RYB.ToRgb(point[0], point[1], point[2]);
            yield return Color.FromArgb(
                (int)Math.Floor(255 * rgb[0]),
                (int)Math.Floor(255 * rgb[1]),
                (int)Math.Floor(255 * rgb[2]));
        }
    }
}
3
répondu m1ch4ls 2014-01-26 09:56:06

David Crow de la méthode dans un R deux-liner:

GetRandomColours <- function(num.of.colours, color.to.mix=c(1,1,1)) {
  return(rgb((matrix(runif(num.of.colours*3), nrow=num.of.colours)*color.to.mix)/2))
}
3
répondu Dave_L 2015-02-13 13:40:11
function fnGetRandomColour(iDarkLuma, iLightLuma) 
{       
  for (var i=0;i<20;i++)
  {
    var sColour = ('ffffff' + Math.floor(Math.random() * 0xFFFFFF).toString(16)).substr(-6);

    var rgb = parseInt(sColour, 16);   // convert rrggbb to decimal
    var r = (rgb >> 16) & 0xff;  // extract red
    var g = (rgb >>  8) & 0xff;  // extract green
    var b = (rgb >>  0) & 0xff;  // extract blue

    var iLuma = 0.2126 * r + 0.7152 * g + 0.0722 * b; // per ITU-R BT.709


    if (iLuma > iDarkLuma && iLuma < iLightLuma) return sColour;
  }
  return sColour;
} 

pour le pastel, passer dans les entiers supérieurs de Luma dark / light-ie fnGetRandomColour (120, 250)

Crédits: tous les crédits à http://paulirish.com/2009/random-hex-color-code-snippets / stackoverflow.com/questions/12043187/how-to-check-if-hex-color-is-too-black

2
répondu ChilledFlame 2013-02-11 10:28:12

adaptation JavaScript de la réponse originale de David Crow, IE et le code spécifique Nodejs inclus.

generateRandomComplementaryColor = function(r, g, b){
    //--- JavaScript code
    var red = Math.floor((Math.random() * 256));
    var green = Math.floor((Math.random() * 256));
    var blue = Math.floor((Math.random() * 256));
    //---

    //--- Extra check for Internet Explorers, its Math.random is not random enough.
    if(!/MSIE 9/i.test(navigator.userAgent) && !/MSIE 10/i.test(navigator.userAgent) && !/rv:11.0/i.test(navigator.userAgent)){
        red = Math.floor((('0.' + window.crypto.getRandomValues(new Uint32Array(1))[0]) * 256));
        green = Math.floor((('0.' + window.crypto.getRandomValues(new Uint32Array(1))[0]) * 256));
        blue = Math.floor((('0.' + window.crypto.getRandomValues(new Uint32Array(1))[0]) * 256));
    };
    //---

    //--- nodejs code
    /*
    crypto = Npm.require('crypto');
    red = Math.floor((parseInt(crypto.randomBytes(8).toString('hex'), 16)) * 1.0e-19 * 256);
    green = Math.floor((parseInt(crypto.randomBytes(8).toString('hex'), 16)) * 1.0e-19 * 256);
    blue = Math.floor((parseInt(crypto.randomBytes(8).toString('hex'), 16)) * 1.0e-19 * 256);
    */
    //---

    red = (red + r)/2;
    green = (green + g)/2;
    blue = (blue + b)/2;

    return 'rgb(' + Math.floor(red) + ', ' + Math.floor(green) + ', ' + Math.floor(blue) + ')';
}

exécutez la fonction en utilisant:

generateRandomComplementaryColor(240, 240, 240);
1
répondu Reinout van Kempen 2015-07-25 17:44:38

vous pourriez les avoir dans une certaine luminosité. ça contrôlerait un peu la quantité de couleurs "néon". par exemple, si la "luminosité"

brightness = sqrt(R^2+G^2+B^2)

était dans une certaine limite supérieure, il aurait une couleur claire. À l'inverse, s'il se trouvait à l'intérieur d'une certaine limite inférieure, il serait plus sombre. Cela éliminerait n'importe quelles couleurs folles et remarquables et si vous choisissez une limite vraiment haut ou vraiment bas, ils seraient tous assez proche de blanc ou noir.

0
répondu helloandre 2008-09-04 02:16:50

il va être difficile d'obtenir ce que vous voulez algorithmiquement - les gens ont étudié la théorie des couleurs depuis longtemps, et ils ne connaissent même pas toutes les règles.

cependant, il y a quelques règles que vous pouvez utiliser pour éliminer de mauvaises combinaisons de couleurs (c'est-à-dire, il y a des règles pour fracasser les couleurs, et le choix des couleurs complémentaires).

je vous recommande de visiter la section art de votre bibliothèque et de vérifier les livres sur la théorie de la couleur pour gagnez une meilleure compréhension de ce qui est une bonne couleur avant d'essayer d'en faire une - il semble que vous ne savez même pas pourquoi certaines combinaisons fonctionnent et d'autres non.

- Adam

0
répondu Adam Davis 2008-09-04 03:36:43

je recommande fortement l'utilisation D'une fonction de shader CG HSVtoRGB, ils sont géniaux... il vous donne le contrôle des couleurs naturelles comme un peintre au lieu de contrôle comme un moniteur de crt, que vous n'êtes probablement pas!

C'est une façon de faire 1 valeur flottante. i.e. gris, en 1000 ds de combinaisons de couleur et de luminosité et de saturation etc:

int rand = a global color randomizer that you can control by script/ by a crossfader etc.
float h = perlin(grey,23.3*rand)
float s = perlin(grey,54,4*rand)
float v = perlin(grey,12.6*rand)

Return float4 HSVtoRGB(h,s,v);

résultat est la randomisation impressionnante des couleurs! ce n'est pas naturel, mais il utilise naturels dégradés de couleurs et il semble organique et contrôlablement irridescent / paramètres pastel.

pour perlin, vous pouvez utiliser cette fonction, c'est une version zig zag rapide de perlin.

function  zig ( xx : float ): float{    //lfo nz -1,1
    xx= xx+32;
    var x0 = Mathf.Floor(xx);
    var x1 = x0+1;
    var v0 = (Mathf.Sin (x0*.014686)*31718.927)%1;
    var v1 = (Mathf.Sin  (x1*.014686)*31718.927)%1;
    return Mathf.Lerp( v0 , v1 , (xx)%1 )*2-1;
}
0
répondu com.prehensible 2014-04-01 21:43:58

voici quelque chose que j'ai écrit pour un site que j'ai créé. Il générera automatiquement une couleur de fond plane aléatoire pour toute div de la classe .flat-color-gen . Jquery n'est nécessaire que pour ajouter css à la page; il n'est pas nécessaire pour la partie principale de ceci, qui est la méthode generateFlatColorWithOrder() .

JsFiddle Lien

(function($) {
    function generateFlatColorWithOrder(num, rr, rg, rb) {
        var colorBase = 256;
        var red = 0;
        var green = 0;
        var blue = 0;
        num = Math.round(num);
        num = num + 1;
        if (num != null) {

            red = (num*rr) % 256;
            green = (num*rg) % 256;
            blue = (num*rb) % 256;
        }
        var redString = Math.round((red + colorBase) / 2).toString();
        var greenString = Math.round((green + colorBase) / 2).toString();
        var blueString = Math.round((blue + colorBase) / 2).toString();
        return "rgb("+redString+", "+greenString+", "+blueString+")";
        //return '#' + redString + greenString + blueString;
    }

    function generateRandomFlatColor() {
        return generateFlatColorWithOrder(Math.round(Math.random()*127));
    }

    var rr = Math.round(Math.random()*1000);
    var rg = Math.round(Math.random()*1000);
    var rb = Math.round(Math.random()*1000);
    console.log("random red: "+ rr);
    console.log("random green: "+ rg);
    console.log("random blue: "+ rb);
    console.log("----------------------------------------------------");
    $('.flat-color-gen').each(function(i, obj) {
        console.log(generateFlatColorWithOrder(i));
        $(this).css("background-color",generateFlatColorWithOrder(i, rr, rg, rb).toString());
    });
})(window.jQuery);
0
répondu Ephraim 2015-07-27 14:56:50

Utiliser distinctes-couleurs .

écrit en javascript.

il génère une palette de visuellement couleurs distinctes.

distinct-couleurs est hautement configurable:

  • choisissez combien de couleurs sont dans la palette
  • restreindre la teinte à une plage spécifique
  • restreindre le chroma (saturation) à un fourchette spécifique
  • limiter la légèreté à une plage spécifique
  • configurer la qualité générale de la palette
0
répondu InternalFX 2015-08-20 17:24:55