Algoritmo per la generazione casuale di un esteticamente gradevole tavolozza di colori [chiuso]

StackOverflow https://stackoverflow.com/questions/43044

  •  09-06-2019
  •  | 
  •  

Domanda

Sto cercando un semplice algoritmo per generare un gran numero di casuale, esteticamente gradevoli colori.In modo che nessun pazzo colori al neon, colori che ricordano le feci, etc.

Ho trovato soluzioni a questo problema, ma si basano sui metodi alternativi di tavolozze di colori RGB.Piuttosto vorrei solo usare direttamente RGB di mappatura e indietro.Queste altre soluzioni, al massimo, può generare solo 32 o in modo piacevole di colori casuali.

Tutte le idee sarebbe grande.

È stato utile?

Soluzione

Si potrebbe in media i valori RGB dei colori casuali con quelli di un colore costante:

(esempio in 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;
}


Miscelazione casuale i colori con il bianco (255, 255, 255) crea neutri pastello, aumentando la leggerezza, mantenendo la tonalità del colore originale.Questi generati in modo casuale pastelli di solito vanno bene insieme, soprattutto in grandi numeri.

Qui ci sono alcuni colori pastello generato utilizzando il metodo di cui sopra:

First


Si possono anche mescolare il colore casuale con un costante pastello, che si traduce in un colorato set di colori neutri.Per esempio, l'utilizzo di una luce blu crea i colori come questi:

Second


Andando oltre, si potrebbe aggiungere l'euristica per il vostro generatore di prendere in considerazione i colori complementari o livelli di ombreggiatura, ma tutto dipende da l'impressione che si desidera ottenere con i tuoi colori casuali.

Risorse aggiuntive:

Altri suggerimenti

Vorrei utilizzare una ruota colore e dato una posizione casuale si potrebbe aggiungere il golden angolo (137,5 gradi)

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

per ottenere colori diversi ogni volta che non si sovrappongono.

Regolazione della luminosità per la ruota dei colori si potrebbe ottenere anche diverse scuro, combinazioni di colori.

Ho trovato questo post del blog che spiega molto bene il problema e la soluzione con il rapporto aureo.

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

AGGIORNAMENTO: Ho appena trovato quest'altro approccio:

Si chiama RYB(rosso, giallo, blu) il metodo è descritto in questo articolo:

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

come "Vernice di Colore Ispirata Composizione".

L'algoritmo genera i colori e ogni nuovo colore viene scelto per ottimizzare la sua euclideo distanza a quelli selezionati in precedenza.

Qui potete trovare una buona implementazione in javascript:

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

AGGIORNA 2:

L'Sciences Po Medialb hanno appena rilasciato un tool chiamato "voglio Tonalità" che generano tavolozze di colori per i dati di scienziati.Utilizzando diversi spazi di colore e di generare le palette utilizzando k-means clustering o vettori forza ( repulsione grafici) I risultati di tali metodi sono molto buoni, essi mostrano la teoria e un'implementazione nella loro pagina web.

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

In 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;
}

Visto che l'idea qui: http://blog.functionalfun.net/2008/07/random-pastel-colour-generator.html

La conversione a un'altra palette è di gran lunga superiore modo per fare questo.C'è un motivo se non che:altre tavolozze sono 'percettivo' - che è, hanno messo simili apparente colori vicini, e la regolazione di una variabile cambia il colore in modo prevedibile.Niente di questo è vero per RGB, dove c'è un'evidente relazione tra i colori che "vanno bene".

Una risposta che non deve essere trascurato, perché è semplice e presenta dei vantaggi, è di campionamento della vita reale, foto e dipinti.esempio di come molti pixel casuali come si desidera che i colori casuali sulle miniature d'arte moderna di foto, cezanne, van gogh, monet, le foto...il vantaggio è che si possono ottenere colori tema e che sono colori organici.appena messo 20 - 30 foto in una cartella e un campione casuale di una foto a caso ogni volta.

Conversione di HSV valori è diffusa l'algoritmo del codice per psicologicamente a base di tavolozza.hsv è più semplice casualità.

In 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;
}

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

Ho avuto successo utilizzando TriadMixing e CIE94 per evitare di colori simili.L'immagine seguente si utilizza l'ingresso di colori rosso, giallo e bianco.Vedere qui.

TriadMixing + CIE94

Qui è rapido e sporco colore generatore in C# (con 'RYB approccio descritto in questo articolo).E ' una riscrittura da JavaScript.

Uso:

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

Primi due colori tendono ad essere di colore bianco e una tonalità di nero.Mi capita spesso di saltare in questo modo (usando Linq):

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

Attuazione:

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]));
        }
    }
}

David Crow metodo in una R con due 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))
}
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;
} 

Il pastello, passare superiore luma buio/luce interi - ie fnGetRandomColour(120, 250)

Crediti:tutti i crediti per http://paulirish.com/2009/random-hex-color-code-snippets/ stackoverflow.com/questions/12043187/come-controllare-se-hex-colore-è-troppo-nero

JavaScript adattamento di David Crow originale risposta, IE e Nodejs specifico codice incluso.

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

Eseguire la funzione utilizzando:

generateRandomComplementaryColor(240, 240, 240);

si potrebbero essere all'interno di una certa luminosità.che sarebbe controllare la quantità di "neon" i colori un po'.per esempio, se la "luminosità"

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

era all'interno di un certo alto legato, sarebbe lavato fuori, la luce di un colore.Al contrario, se si è entro un certo limite inferiore, sarebbe più scura.Ciò consentirebbe di eliminare qualsiasi pazzo, standout colori e se si è scelto un limite molto alte o molto basso, sarebbero stati tutti abbastanza vicino al bianco o nero.

Sta andando essere duro per ottenere ciò che si vuole in modo algoritmico - persone che hanno studiato la teoria dei colori per un lungo periodo di tempo, e che non sanno nemmeno tutte le regole.

Tuttavia, ci sono alcuni regole che è possibile utilizzare per abbattere i cattivi combinazioni di colori (vale a dire, ci sono delle regole per colori contrastanti, e la scelta di colori complementari).

Io ti consiglio di visitare la vostra biblioteca della sezione di arte e check out libri sulla teoria del colore per ottenere una migliore comprensione di ciò che è un buon colore prima di provare a fare uno - sembra che si potrebbe anche non sapere perché alcune combinazioni di lavoro e non degli altri.

-Adam

Mi piacerebbe consiglia di utilizzare un CG HSVtoRGB shader funzione, sono impressionanti...ti dà colore naturale, il controllo, come un pittore, invece, di controllo come un monitor crt, che si arent presumibilmente!

Questo è un modo per fare 1 valore float.cioèGrigio, in 1000 ds di combinazioni di colore e di luminosità e saturazione ecc:

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);

il risultato è IMPRESSIONANTE COLORE RANDOMIZZAZIONE!non è naturale, ma non sfrutta le naturali sfumature di colore e sembra organici e controlleably irridescent / pastello parametri.

Per perlin, è possibile utilizzare questa funzione, è veloce zig zag versione di 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;
}

Qui c'è qualcosa che ho scritto per un sito che ho fatto.Si auto-genera casualmente un piatto di colore di sfondo per ogni div con classe .flat-color-gen.Jquery è necessaria solo ai fini di aggiungere css alla pagina;non è necessario per la maggior parte di questo, che è il generateFlatColorWithOrder() metodo.

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);

Utilizzare diversi colori.

Scritto in javascript.

Esso genera una tavolozza di visivamente colori distinti.

diversi colori è altamente configurabile:

  • Scegliere il numero di colori nella tavolozza
  • Limitare la tonalità di una gamma specifica
  • Limitare il chroma (saturazione) a un intervallo specifico
  • Limitare la leggerezza di una gamma specifica
  • Configurare la qualità generale della tavolozza
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top