Algoritmo para generar aleatoriamente una paleta de colores estéticamente agradable [cerrado]


Estoy buscando un algoritmo simple para generar un gran número de colores aleatorios, estéticamente agradables. Así que no hay colores de neón locos, colores que recuerdan a las heces, etc.

He encontrado soluciones a este problema, pero se basan en paletas de colores alternativas que RGB. Prefiero usar RGB directo que mapear hacia adelante y hacia atrás. Estas otras soluciones también pueden generar a lo sumo solo 32 o tan agradables colores aleatorios.

Cualquier idea sería genial.

Author: Alex L, 2008-09-04

16 answers

Podría promediar los valores RGB de colores aleatorios con los de un color constante:

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


La mezcla de colores aleatorios con blanco (255, 255, 255) crea pasteles neutros al aumentar la luminosidad y mantener el tono del color original. Estos pasteles generados aleatoriamente suelen ir bien juntos, especialmente en grandes números.

Aquí hay algunos colores pastel generados usando el método anterior:

Primero


Usted también podría mezclar el color aleatorio con un pastel constante, lo que resulta en un conjunto teñido de colores neutros. Por ejemplo, usar un azul claro crea colores como estos:

Segundo


Yendo más allá, podría agregar heurísticas a su generador que tengan en cuenta colores complementarios o niveles de sombreado, pero todo depende de la impresión que desee lograr con sus colores aleatorios.

Algunos adicionales recursos:

 402
Author: David Crow,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-04-02 08:37:49

Usaría una rueda de color y dada una posición aleatoria podría agregar el ángulo dorado (137,5 grados)

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

Para obtener diferentes colores cada vez que no se superponen.

Ajustando el brillo para la rueda de color, también puede obtener diferentes combinaciones de colores brillantes/oscuros.

He encontrado esta entrada de blog que explica muy bien el problema y la solución utilizando el oro relación.

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

ACTUALIZACIÓN: Acabo de encontrar este otro enfoque:

Se llama método RYB(rojo, amarillo, azul) y se describe en este documento:

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

Como "Composición de Color Inspirada en la Pintura".

El algoritmo genera los colores y cada nuevo color se elige para maximizar su distancia euclidiana a la los previamente seleccionados.

Aquí puedes encontrar una buena implementación en javascript:

Http://afriggeri.github.com/RYB /

ACTUALIZAR 2:

El Sciences Po Medialb acaba de lanzar una herramienta llamada "I want Hue" que genera paletas de colores para los científicos de datos. Utilizando diferentes espacios de color y generando las paletas mediante el uso de k-means clustering o vectores de fuerza (gráficos de repulsión) Los resultados de esos métodos son muy buenos, muestran la teoría y una implementación en su página web.

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

 81
Author: Fgblanch,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
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;
}

Vio la idea aquí: http://blog.functionalfun.net/2008/07/random-pastel-colour-generator.html

 23
Author: motobói,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-09-04 15:05:23

Convertir a otra paleta es una forma muy superior de hacer esto. Hay una razón por la que lo hacen: otras paletas son "perceptivas", es decir, ponen colores similares muy juntos, y ajustar una variable cambia el color de una manera predecible. Nada de eso es cierto para RGB, donde no hay una relación obvia entre los colores que "van bien juntos".

 9
Author: Nick Johnson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-06-07 20:45:33

Una respuesta que no debe pasarse por alto, porque es simple y presenta ventajas, es la muestra de fotos y pinturas de la vida real. muestra tantos píxeles aleatorios como quieras colores aleatorios en miniaturas de fotos de arte moderno, cezanne, van gogh, monnet, fotos... la ventaja es que puedes obtener colores por tema y que son colores orgánicos. solo tienes que poner 20 - 30 fotos en una carpeta y muestra al azar una foto al azar cada vez.

La conversión a valores HSV es un algoritmo de código generalizado para paleta basada psicológicamente. hsv es más fácil de aleatorizar.

 4
Author: com.prehensible,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
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;
}

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

 4
Author: Petr Bugyík,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:18:22

He tenido éxito usando TriadMixing y CIE94 para evitar colores similares. La siguiente imagen utiliza los colores de entrada rojo, amarillo y blanco. Ver aquí.

TriadMixing + CIE94

 4
Author: Moriarty,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-03-22 03:24:17

Aquí está el generador de color rápido y sucio en C# (usando 'enfoque RYB' descrito en este artículo). Es una reescritura de JavaScript .

Uso:

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

Los primeros dos colores tienden a ser blanco y un tono de negro. A menudo los omito así (usando Linq):

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

Aplicación:

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
Author: m1ch4ls,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-01-26 09:56:06

El método de David Crow en un R de dos líneas:

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
Author: Dave_L,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
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;
} 

Para pastel, pase en números enteros oscuros / claros de luma más alta-es decir, fnGetRandomColour (120, 250)

Créditos: todos los créditos a http://paulirish.com/2009/random-hex-color-code-snippets / stackoverflow.com/questions/12043187/how-to-check-if-hex-color-is-too-black

 2
Author: ChilledFlame,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-02-11 10:28:12

Adaptación JavaScript de la respuesta original de David Crow, IE y código específico de Nodejs incluido.

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) + ')';
}

Ejecute la función usando:

generateRandomComplementaryColor(240, 240, 240);
 1
Author: Reinout van Kempen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-07-25 17:44:38

Podrías tenerlos dentro de un cierto brillo. eso controlaría un poco la cantidad de colores "neón". por ejemplo, si el "brillo"

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

Estaba dentro de un cierto límite alto, tendría un color claro lavado. Por el contrario, si estuviera dentro de cierto límite bajo, sería más oscuro. Esto eliminaría cualquier loco, colores destacados y si eliges un límite muy alto o muy bajo, todos estarían bastante cerca de blanco o negro.

 0
Author: helloandre,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-09-04 02:16:50

Va a ser difícil conseguir lo que quieres algorítmicamente - la gente ha estado estudiando la teoría del color durante mucho tiempo, y ni siquiera conocen todas las reglas.

Sin embargo, hay algunas reglas que puede usar para eliminar combinaciones de colores incorrectas (es decir, hay reglas para contrastar colores y elegir colores complementarios).

Le recomiendo que visite la sección de arte de su biblioteca y eche un vistazo a los libros sobre la teoría del color para obtener una mejor comprensión de lo que es un buen color antes de intentar hacer una, parece que ni siquiera sabe por qué ciertas combinaciones funcionan y otras no.

-Adam

 0
Author: Adam Davis,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-09-04 03:36:43

Recomiendo encarecidamente el uso de una función de sombreado CG HSVtoRGB, son impresionantes... le da control de color natural como un pintor en lugar de control como un monitor crt, que no presumiblemente!

Esta es una forma de hacer 1 valor flotante. es decir, gris, en 1000 ds de combinaciones de color y brillo y saturación, 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);

El resultado es la ALEATORIZACIÓN DE COLOR IMPRESIONANTE! no es natural, pero utiliza degradados de color naturales y se ve orgánico y controlablemente iridiscente / parámetros pastel.

Para perlin, puede usar esta función, es una versión rápida en zig zag 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
Author: com.prehensible,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-04-01 21:43:58

Aquí hay algo que escribí para un sitio que hice. Generará automáticamente un color de fondo plano aleatorio para cualquier div con la clase .flat-color-gen. Jquery solo es necesario para agregar css a la página; no es necesario para la parte principal de esto, que es el método generateFlatColorWithOrder().

JsFiddle Link

(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
Author: Ephraim,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-07-27 14:56:50

Use colores distintos.

Escrito en javascript.

Genera una paleta de visualmente colores distintos.

Distinct-colors es altamente configurable:

  • Elija cuántos colores hay en la paleta
  • Restringir el tono a un rango específico
  • Restringir el croma (saturación) a un rango específico
  • Restringir la luminosidad a un rango específico
  • Configurar la calidad general de la paleta
 0
Author: InternalFX,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-08-20 17:24:55