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

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

  •  09-06-2019
  •  | 
  •  

Frage

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 reines RGB verwenden, als hin und her zuzuordnen.Auch diese anderen Lösungen können höchstens etwa 32 ansprechende Zufallsfarben erzeugen.

Irgendwelche Ideen wären großartig.

War es hilfreich?

Lösung

Sie könnten die RGB-Werte zufälliger Farben 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 das Mischen zufälliger Farben mit Weiß (255, 255, 255) entstehen neutrale Pastelltöne, indem die Helligkeit erhöht und gleichzeitig der Farbton der Originalfarbe beibehalten wird.Diese zufällig generierten Pastelle passen in der Regel gut zusammen, insbesondere in großer Zahl.

Hier sind einige Pastellfarben, die mit der oben genannten Methode generiert wurden:

First


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 helles Blau verwenden, entstehen Farben wie diese:

Second


Darüber hinaus könnten Sie Ihrem Generator Heuristiken hinzufügen, die Komplementärfarben oder Schattierungsstufen berücksichtigen, aber alles hängt davon ab, welchen Eindruck Sie mit Ihren Zufallsfarben erzielen möchten.

Einige zusätzliche Ressourcen:

Andere Tipps

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

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

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

Durch Anpassen der Helligkeit für das Farbrad können Sie auch verschiedene helle/dunkle Farbkombinationen erhalten.

Ich habe diesen Blogbeitrag gefunden, der das Problem und die Lösung mithilfe des Goldenen Schnitts wirklich gut erklärt.

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

AKTUALISIEREN: 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 so ausgewählt, dass ihr euklidischer Abstand zu den zuvor ausgewählten Farben maximiert wird.

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.Verwendung verschiedener Farbräume und Generierung der Paletten mithilfe von K-Means-Clustering oder Kraftvektoren (Abstoßungsdiagramme). 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

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

Habe die Idee hier gesehen: http://blog.Functionalfun.net/2008/07/random-pastel-colour-generator.html

Die Konvertierung in eine andere Palette ist hierfür eine weitaus bessere Möglichkeit.Es gibt einen Grund, warum sie das tun:Andere Paletten sind „wahrnehmungsbezogen“ – das heißt, sie bringen ähnlich erscheinende Farben nahe beieinander und die Anpassung 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“.

Eine Antwort, die nicht übersehen werden sollte, weil sie einfach ist und Vorteile bietet, ist das Ausprobieren von Fotos und Gemälden aus dem wirklichen Leben.Probieren Sie so viele zufällige Pixel aus, wie Sie möchten, zufällige Farben auf Miniaturansichten von Bildern moderner Kunst, Cezanne, Van Gogh, Monnet, Fotos ...Der Vorteil besteht darin, dass Sie Farben nach Themen erhalten können und dass es sich um organische Farben handelt.Legen Sie einfach 20 bis 30 Bilder in einen Ordner und wählen 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.

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

Ich hatte Erfolg damit TriadMixing Und CIE94 um ähnliche Farben zu vermeiden.Das folgende Bild verwendet die Eingabefarben Rot, Gelb und Weiß.Sehen Hier.

TriadMixing + CIE94

Hier ist ein schneller und schmutziger Farbgenerator in C# (unter Verwendung des hier beschriebenen „RYB-Ansatzes“) Artikel).Es ist eine Neufassung von JavaScript.

Verwenden:

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

Die ersten beiden Farben sind in der Regel Weiß und ein Schwarzton.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]));
        }
    }
}

David Crows Methode in einem R-Zweizeiler:

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

Übergeben Sie für Pastell höhere Luma-Dunkel-/Hell-Ganzzahlen, z. B. fnGetRandomColor(120, 250).

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

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

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

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

Liegt die Farbe innerhalb einer bestimmten Obergrenze, weist sie eine ausgewaschene, helle Farbe auf.Umgekehrt wäre es dunkler, wenn es innerhalb einer bestimmten Untergrenze läge.Dadurch würden alle verrückten, auffälligen Farben eliminiert, und wenn Sie eine sehr hohe oder sehr niedrige Grenze wählen würden, kämen sie alle ziemlich nahe an Weiß oder Schwarz.

Es wird schwierig sein, algorithmisch das zu bekommen, was man will – die Leute beschäftigen sich schon seit langem mit der Farbtheorie und kennen noch nicht einmal alle Regeln.

Es gibt jedoch welche manche Regeln, mit denen Sie schlechte Farbkombinationen aussortieren können (z. B. gibt es Regeln für Farbkollisionen und die Auswahl von Komplementärfarben).

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

-Adam

Ich würde dringend empfehlen, eine CG HSVtoRGB-Shader-Funktion zu verwenden, sie sind großartig ...Es gibt Ihnen eine natürliche Farbkontrolle wie ein Maler statt einer Kontrolle wie ein CRT-Monitor, den Sie vermutlich nicht haben!

Dies ist eine Möglichkeit, 1 Float-Wert zu erstellen.d.h.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 FARBRANDOMISIERUNG!Es ist nicht natürlich, aber es verwendet natürliche Farbverläufe und sieht organisch aus und hat kontrollierbare Schiller-/Pastellparameter.

Für Perlin können Sie diese Funktion verwenden, es handelt sich um 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;
}

Hier ist etwas, das ich für eine von mir erstellte Website geschrieben habe.Es wird automatisch eine zufällige flache Hintergrundfarbe für jedes Div mit der Klasse generiert .flat-color-gen.Jquery ist nur zum Hinzufügen von CSS zur Seite erforderlich.Für den Hauptteil hiervon ist es nicht erforderlich generateFlatColorWithOrder() Methode.

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

Verwenden verschiedene Farben.

In Javascript geschrieben.

Es generiert eine Palette von visuell deutliche Farben.

„distinct-colors“ ist hochgradig 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 Chroma (Sättigung) auf einen bestimmten Bereich
  • Beschränken Sie die Helligkeit auf einen bestimmten Bereich
  • Konfigurieren Sie die allgemeine Qualität der Palette
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top