Algorytm losowego generowania estetycznej palety kolorów [zamknięty]

Szukam prostego algorytmu do generowania dużej liczby losowych, estetycznych kolorów. Więc bez szalonych neonowych kolorów, kolorów przypominających odchody itp.

Znalazłem rozwiązania tego problemu, ale polegają one na alternatywnych paletach kolorów niż RGB. Wolałbym po prostu używać prostego RGB niż mapowania tam iz powrotem. Te inne rozwiązania mogą również co najwyżej generować tylko 32 lub tak przyjemne losowe kolory.

Wszelkie pomysły byłyby świetne.

Author: Alex L, 2008-09-04

16 answers

Możesz uśrednić wartości RGB kolorów losowych z wartościami o stałym kolorze:

(przykład w Javie)

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


Mieszanie losowych kolorów z bielą (255, 255, 255) tworzy neutralne Pastele zwiększając lekkość, zachowując odcień oryginalnego koloru. Te losowo generowane Pastele Zwykle pasują do siebie, szczególnie w dużych ilościach.

Oto kilka pastelowych kolorów wygenerowanych powyższą metodą:

Pierwszy


Ty może również mieszać losowy kolor ze stałym pastelem, co skutkuje przyciemnionym zestawem neutralnych kolorów. Na przykład użycie jasnoniebieskiego tworzy kolory takie jak:

Drugi


Idąc dalej, możesz dodać heurystykę do generatora, która uwzględnia uzupełniające się kolory lub poziomy cieniowania, ale wszystko zależy od wrażenia, które chcesz osiągnąć za pomocą losowych kolorów.

Niektóre dodatkowe zasoby:

 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/doraprojects.net/template/agent.layouts/content.php on line 54
2012-04-02 08:37:49

Użyłbym koła kolorów i biorąc pod uwagę losową pozycję można dodać złoty kąt (137,5 stopni)

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

W celu uzyskania za każdym razem różnych kolorów, które nie nakładają się na siebie.

Dostosowując jasność do koła kolorów można uzyskać również różne kombinacje kolorów jasny / ciemny.

Znalazłem ten wpis na blogu, który naprawdę dobrze wyjaśnia problem i rozwiązanie za pomocą złotego / align = "left" /

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

UPDATE: właśnie znalazłem inne podejście:

Jest to metoda RYB (czerwona, żółta, niebieska) opisana w artykule:

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

Jako "Kompozycja Kolorów Inspirowana Farbą".

Algorytm generuje kolory i każdy nowy kolor jest wybierany tak, aby zmaksymalizować jego odległość euklidesową do wcześniej wybrane.

Tutaj znajdziesz dobrą implementację w javascript:

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

Aktualizacja 2:

Sciences Po Medialb wydało właśnie narzędzie o nazwie "I want Hue", które generuje palety kolorów dla analityków danych. Korzystanie z różnych przestrzeni kolorów i generowanie palet za pomocą klastrów k lub wektorów siły (Wykresów odpychania) wyniki z tych metod są bardzo dobre, pokazują teorii i implementacji na ich stronie internetowej.

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/doraprojects.net/template/agent.layouts/content.php on line 54
2013-02-12 11:26:22

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

Widziałem pomysł tutaj: 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/doraprojects.net/template/agent.layouts/content.php on line 54
2012-09-04 15:05:23

Konwersja na inną paletę jest o wiele lepszym sposobem na to. Nie bez powodu robią to: inne palety są "percepcyjne" - to znaczy umieszczają podobne pozornie kolory blisko siebie, a dopasowanie jednej zmiennej zmienia kolor w przewidywalny sposób. Nic z tego nie jest prawdą w przypadku RGB, gdzie nie ma oczywistej zależności między kolorami, które "dobrze ze sobą współgrają".

 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/doraprojects.net/template/agent.layouts/content.php on line 54
2009-06-07 20:45:33

Odpowiedzią, której nie należy przeoczyć, ponieważ jest prosta i ma zalety, jest próbkowanie prawdziwych zdjęć i obrazów. próbkuj tyle losowych pikseli, ile chcesz losowych kolorów na miniaturach zdjęć sztuki współczesnej, cezanne ' a, van Gogha, Monneta, zdjęć... zaletą jest to, że można uzyskać kolory według motywu i że są to Kolory organiczne. po prostu umieść 20-30 zdjęć w folderze i za każdym razem losowo próbkuj losowe zdjęcie.

Konwersja na wartości HSV jest szeroko rozpowszechnionym algorytmem kodowym dla psychologicznie oparta paleta. HSV jest łatwiejsze do randomizacji.

 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/doraprojects.net/template/agent.layouts/content.php on line 54
2013-08-16 08:59:14

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

Źródło: 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/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:18:22

Udało mi się użyć Triadmixingu i CIE94, aby uniknąć podobnych kolorów. Poniższy obraz używa kolorów wejściowych: czerwonego, żółtego i białego. Zobacz tutaj .

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/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-22 03:24:17

Oto szybki i brudny generator kolorów w C# (używając 'podejścia RYB' opisanego w tym artykule ). Jest to przepisanie z JavaScript .

Zastosowanie:

List<Color> ColorPalette = ColorGenerator.Generate(30).ToList();
Pierwsze dwa kolory to Biel i odcień czerni. Często pomijam je w ten sposób (używając Linq):
List<Color> ColorsPalette = ColorGenerator
            .Generate(30)
            .Skip(2) // skip white and black
            .ToList(); 

Realizacja:

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/doraprojects.net/template/agent.layouts/content.php on line 54
2014-01-26 09:56:06

Metoda Davida Crowa w dwuliniowej R:

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/doraprojects.net/template/agent.layouts/content.php on line 54
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;
} 

Dla pasteli, pass in higher Luma dark / light integers-ie fnGetRandomColour (120, 250)

Kredyty: wszystkie kredyty do 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/doraprojects.net/template/agent.layouts/content.php on line 54
2013-02-11 10:28:12

Adaptacja JavaScript oryginalnej odpowiedzi Davida Crowa, w tym kod specyficzny dla IE i Nodejs.

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

Uruchom funkcję używając:

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/doraprojects.net/template/agent.layouts/content.php on line 54
2015-07-25 17:44:38

Możesz mieć je w pewnej jasności. to by trochę kontrolowało ilość "neonowych" kolorów. na przykład, jeśli "Jasność"

brightness = sqrt(R^2+G^2+B^2)
Był w pewnej wysokiej granicy, miał wyprany, jasny kolor. Z drugiej strony, gdyby był w pewnej niskiej granicy, byłby ciemniejszy. Wyeliminowałoby to wszelkie szalone, wyróżniające się kolory, a jeśli wybierzesz Wiązanie naprawdę wysokie lub naprawdę niskie, wszystkie byłyby dość blisko białego lub czarnego.
 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/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-04 02:16:50

Trudno będzie dostać to, czego chcesz - ludzie od dawna studiują teorię kolorów i nawet nie znają wszystkich zasad.

Istnieją jednak pewne reguły, których można użyć do wybierania złych kombinacji kolorów (tj. istnieją reguły zderzania kolorów i wybierania kolorów uzupełniających).

Polecam odwiedzenie Działu Sztuki w bibliotece i zapoznanie się z książkami na temat teorii kolorów, aby lepiej zrozumieć, co jest dobrym kolorem zanim spróbujesz zrobić jedną-wygląda na to, że możesz nawet nie wiedzieć, dlaczego niektóre kombinacje działają, a inne nie.

- 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/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-04 03:36:43

Zdecydowanie polecam korzystanie z funkcji cieniowania CG HSVtoRGB, są niesamowite... daje Ci naturalną kontrolę kolorów jak malarz zamiast kontroli jak monitor crt, którego prawdopodobnie nie jesteś!

Jest to sposób na utworzenie 1 wartości zmiennoprzecinkowej. tj. szary, w 1000 ds kombinacji kolorów, jasności i nasycenia itp:

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

Wynik to niesamowita randomizacja kolorów! nie jest naturalny, ale wykorzystuje naturalne gradienty kolorów i wygląda organicznie i kontrolnie irridescent / pastelowe parametry.

Dla Perlina, możesz użyć tej funkcji, jest to szybka zig zag wersja Perlina.

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/doraprojects.net/template/agent.layouts/content.php on line 54
2014-04-01 21:43:58

Oto coś, co napisałem dla strony, którą zrobiłem. Automatycznie wygeneruje losowy płaski kolor tła dla dowolnego div z klasą .flat-color-gen. Jquery jest wymagane tylko w celu dodania css do strony; nie jest wymagane dla głównej części tego, czyli metody 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/doraprojects.net/template/agent.layouts/content.php on line 54
2015-07-27 14:56:50

Użyj distinct-colors.

Napisane w javascript.

Generuje paletę wizualnie różnych kolorów.

Distinct-colors jest wysoce konfigurowalny:

  • Wybierz ile kolorów znajduje się w palecie
  • Ogranicz odcień do określonego zakresu
  • Ogranicz chroma (nasycenie) do określonego zakresu
  • Ogranicz lekkość do określonego zakresu
  • Konfiguracja ogólnej jakości palety
 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/doraprojects.net/template/agent.layouts/content.php on line 54
2015-08-20 17:24:55