Algorithmus zur zufälligen Erzeugung einer ästhetisch ansprechenden Farbpalette [geschlossen]


301

Ich suche nach einem einfachen Algorithmus, um eine große Anzahl zufälliger, ästhetisch ansprechender Farben zu erzeugen. Also keine verrückten Neonfarben, Farben, die an Kot erinnern usw.

Ich habe Lösungen für dieses Problem gefunden, aber sie basieren auf alternativen Farbpaletten als RGB. Ich würde lieber nur RGB verwenden, als hin und her zu mappen. Diese anderen Lösungen können auch höchstens 32 oder so ansprechende zufällige Farben erzeugen.

Irgendwelche Ideen wären toll.


2
Ich würde eine Website erstellen, die bei jedem Besuch eine zufällige Farbe erzeugt. Haben Sie eine "diese Farbe rockt" / "diese Farbe saugt" Abstimmung. Dann sortieren Sie nach dem Stimmenverhältnis.
Nosredna

Sie könnten HSL und HSV auschecken.
Jim Keener

48
"Farben, die an Kot erinnern" Ich liebe es
lol

Das ist kein Algorithmus.
Matt The Ninja

Ich werde einen Kommentar hinzufügen, da die Frage geschlossen ist. Ich habe es nicht ausprobiert, aber es wäre interessant, einen fraktalen oder prozeduralen Weg zu versuchen, indem ich den Algorithmus oder die Varianten der Mittelpunktverschiebung ( lighthouse3d.com/opengl/terrain/index.php?mpd2 ) oder Perlin Noise verwende, aber anstelle von Höhen um die rgb-komponenten der farben zu mischen.
Alfoks

Antworten:


426

Sie können die RGB-Werte von Zufallsfarben mit denen einer konstanten Farbe mitteln:

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


Durch Mischen von zufälligen Farben mit Weiß (255, 255, 255) werden neutrale Pastellfarben erzeugt, indem die Helligkeit erhöht wird, während der Farbton der Originalfarbe beibehalten wird. Diese zufällig erzeugten Pastelle passen normalerweise gut zusammen, besonders in großer Anzahl.

Hier sind einige Pastellfarben, die mit der obigen Methode erzeugt wurden:

Zuerst


Sie können die zufällige Farbe auch mit einem konstanten Pastell mischen, was zu einem getönten Satz neutraler Farben führt. Wenn Sie beispielsweise ein Hellblau verwenden, werden folgende Farben erstellt:

Zweite


Wenn Sie weiter gehen, können Sie Ihrem Generator Heuristiken hinzufügen, die Komplementärfarben oder Schattierungsstufen berücksichtigen. Dies hängt jedoch alles von dem Eindruck ab, den Sie mit Ihren zufälligen Farben erzielen möchten.

Einige zusätzliche Ressourcen:


3
Die einzige Einschränkung scheint der Verlust der Unterscheidbarkeit zu sein. Wenn Sie den Durchschnitt von Rot, Grün und Blau mit einer Farbe wie Weiß nehmen, rücken natürlich alle Farben näher an Weiß heran und verringern die Unterschiede zwischen ihnen. Wenn Sie sich zum Beispiel den ersten Screenshot ansehen: Wenn diese Grüns nebeneinander liegen, kann ich sie sicherlich unterscheiden, aber was ist, wenn sie in einer produzierten Grafik nicht nebeneinander liegen? Könnte problematisch sein.
Zelphir Kaltstahl

Versuchen Sie beim Generieren einer zufälligen Farbkomponente, die Obergrenze auf etwas weniger wie 200 zu beschränken.
Nickolodeon

87

Ich würde ein Farbrad verwenden und bei einer zufälligen Position den goldenen Winkel (137,5 Grad) hinzufügen.

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

um jedes Mal andere Farben zu erhalten, die sich nicht überlappen.

Wenn Sie die Helligkeit für das Farbrad einstellen, können Sie auch verschiedene Hell / Dunkel-Farbkombinationen erhalten.

Ich habe diesen Blog-Beitrag gefunden, der das Problem und die Lösung mit dem Goldenen Schnitt sehr gut erklärt.

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

UPDATE: Ich habe gerade diesen anderen Ansatz gefunden:

Es heißt RYB-Methode (rot, gelb, blau) und wird in diesem Artikel beschrieben:

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

als "Paint Inspired Color Compositing".

Der Algorithmus generiert die Farben und jede neue Farbe wird ausgewählt, um ihren euklidischen Abstand zu den zuvor ausgewählten zu maximieren.

Hier finden Sie eine gute Implementierung in Javascript:

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

UPDATE 2:

Die Sciences Po Medialb haben gerade ein Tool namens "I want Hue" veröffentlicht, das Farbpaletten für Datenwissenschaftler generiert. Verwenden verschiedener Farbräume und Generieren der Paletten mithilfe von k-Mittel-Clustering oder Kraftvektoren (Abstoßungsgraphen) Die Ergebnisse dieser Methoden sind sehr gut. Sie zeigen die Theorie und eine Implementierung auf ihrer Webseite.

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


iWantHue ist die Antwort. Geh dorthin. Sei erstaunt.
Irongaze.com

23

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

Sah die Idee hier: http://blog.functionalfun.net/2008/07/random-pastel-colour-generator.html


Nicht ganz richtig: Sie müssen auch einstellige Zahlen auf Null setzen ... Wie auch immer, hier ist eine funktionierende Geige für Suchende: jsfiddle.net/RedDevil/LLYBQ ----- Scratch that ... das habe ich nicht Beachten Sie das +127 Bit ... Aber dann werden keine dunklen Farbtöne erzeugt.
Kumarshar

2
Die ursprüngliche Idee war, willkürlich angenehme Farben zu erzeugen. Die dunklen
Töne

11

Das Konvertieren in eine andere Palette ist eine weitaus bessere Möglichkeit, dies zu tun. Es gibt einen Grund, warum sie das tun: Andere Paletten sind "wahrnehmbar" - das heißt, sie setzen ähnliche scheinbare Farben nahe beieinander und das Anpassen einer Variablen ändert die Farbe auf vorhersehbare Weise. Nichts davon gilt für RGB, wo es keine offensichtliche Beziehung zwischen Farben gibt, die "gut zusammenpassen".


6

Ich hatte Erfolg mit TriadMixing und CIE94 , um ähnliche Farben zu vermeiden. Das folgende Bild verwendet die Eingabefarben Rot, Gelb und Weiß. Siehe hier .

TriadMixing + CIE94


5

Eine Antwort, die nicht übersehen werden sollte, weil sie einfach ist und Vorteile bietet, ist die Auswahl von Fotos und Gemälden aus dem wirklichen Leben. Probieren Sie so viele zufällige Pixel aus, wie Sie möchten, und wählen Sie zufällige Farben auf Miniaturansichten von Bildern der modernen Kunst, Cezanne, Van Gogh, Monnet, Fotos ... Der Vorteil ist, dass Sie Farben nach Thema erhalten können und dass es sich um organische Farben handelt. Legen Sie einfach 20 - 30 Bilder in einen Ordner und probieren Sie jedes Mal ein zufälliges Bild aus.

Die Konvertierung in HSV-Werte ist ein weit verbreiteter Codealgorithmus für psychologisch basierte Paletten. hsv ist einfacher zu randomisieren.


1
mkweb.bcgsc.ca/color_summarizer/?analyze Hier ist ein Online-Tool, das Fotos aus dem wirklichen Leben analysieren und zu Ihnen zurückkehren kann. äußerst nützliche Website, die wichtig ist, wenn Sie versuchen, avantgardistische Algorithmen für zufällige Farben zu entwerfen
com.prehensible

4

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

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


3

Hier ist ein schneller und schmutziger Farbgenerator in C # (unter Verwendung des in diesem Artikel beschriebenen 'RYB-Ansatzes' ). Es ist ein Umschreiben von JavaScript .

Verwenden:

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

Die ersten beiden Farben sind in der Regel weiß und schwarz. Ich überspringe sie oft so (mit Linq):

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

Implementierung:

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

Ich habe die Java-Antwort entfernt, aber bei Bedarf ist die Java-Version in dieser Übersicht
Dylan Watson

3

David Crows Methode in einem R-Zweiliner:

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

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

Geben Sie für Pastell höhere Luma-Ganzzahlen für Dunkel / Hell ein - dh fnGetRandomColour (120, 250).

Credits: Alle Credits für http://paulirish.com/2009/random-hex-color-code-snippets/ stackoverflow.com/questions/12043187/how-to-check-if-hex-color-is-too-black


1

JavaScript-Anpassung der ursprünglichen Antwort von David Crow, einschließlich IE- und Nodejs-spezifischem Code.

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

Führen Sie die Funktion aus mit:

generateRandomComplementaryColor(240, 240, 240);

1

Verwenden Sie unterschiedliche Farben .

Geschrieben in Javascript.

Es wird eine Palette visuell unterschiedlicher Farben erzeugt.

eindeutige Farben sind hoch konfigurierbar:

  • Wählen Sie aus, wie viele Farben in der Palette enthalten sind
  • Beschränken Sie den Farbton auf einen bestimmten Bereich
  • Beschränken Sie die Farbintensität (Sättigung) auf einen bestimmten Bereich
  • Beschränken Sie die Helligkeit auf einen bestimmten Bereich
  • Konfigurieren Sie die allgemeine Qualität der Palette

0

Sie könnten sie innerhalb einer bestimmten Helligkeit haben. das würde die Menge der "Neon" -Farben ein wenig kontrollieren. zum Beispiel, wenn die "Helligkeit"

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

war innerhalb einer bestimmten hohen Grenze, würde es eine ausgewaschene, helle Farbe haben. Umgekehrt wäre es dunkler, wenn es innerhalb einer bestimmten Untergrenze wäre. Dies würde alle verrückten, herausragenden Farben eliminieren und wenn Sie eine wirklich hohe oder sehr niedrige Grenze wählen würden, wären sie alle ziemlich nahe an Weiß oder Schwarz.


0

Es wird schwierig sein, algorithmisch das zu bekommen, was Sie wollen - die Leute haben lange Zeit Farbtheorie studiert und kennen nicht einmal alle Regeln.

Es gibt jedoch einige Regeln, mit denen Sie schlechte Farbkombinationen ausmerzen können (dh es gibt Regeln für das Zusammenprallen von Farben und das Auswählen von Komplementärfarben).

Ich würde empfehlen, dass Sie die Kunstabteilung Ihrer Bibliothek besuchen und Bücher über Farbtheorie lesen, um besser zu verstehen, was eine gute Farbe ist, bevor Sie versuchen, eine zu erstellen. Es scheint, dass Sie nicht einmal wissen, warum bestimmte Kombinationen funktionieren und andere nicht. t.

-Adam


0

Ich würde dringend empfehlen, eine CG HSVtoRGB-Shader-Funktion zu verwenden. Sie sind fantastisch. Sie bietet Ihnen eine natürliche Farbkontrolle wie bei einem Maler anstelle einer Kontrolle wie bei einem CRT-Monitor, was Sie vermutlich nicht tun!

Dies ist eine Möglichkeit, 1 Float-Wert zu erstellen. dh Grau, in 1000 ds Kombinationen aus Farbe, Helligkeit und Sättigung usw.:

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

Das Ergebnis ist eine fantastische Farb-Randomisierung! Es ist nicht natürlich, aber es verwendet natürliche Farbverläufe und es sieht organisch und kontrollierbar schillernd / pastellfarben aus.

Für Perlin können Sie diese Funktion verwenden, es ist eine schnelle Zick-Zack-Version von 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

Hier ist etwas, das ich für eine Seite geschrieben habe, die ich gemacht habe. Es wird automatisch eine zufällige flache Hintergrundfarbe für jedes Div mit der Klasse generiert .flat-color-gen. Jquery wird nur zum Hinzufügen von CSS zur Seite benötigt. Es ist nicht erforderlich für den Hauptteil davon, der die generateFlatColorWithOrder()Methode ist.

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);
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.