Algoritmo per generare in modo casuale una tavolozza di colors esteticamente piacevole

Sto cercando un semplice algoritmo per generare un gran numero di colors casuali ed esteticamente gradevoli. Quindi niente colors al neon pazzi, colors che ricordano le feci, ecc.

Ho trovato soluzioni a questo problema ma si basano su tavolozze di colors alternative rispetto a RGB. Preferirei usare solo RGB diretto che mappare avanti e indietro. Queste altre soluzioni possono anche generare al massimo solo 32 colors piacevoli a piacere.

Qualunque idea sarebbe apprezzata.

Puoi calcolare la media dei valori RGB dei colors 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; } 

La miscelazione di colors casuali con il bianco (255, 255, 255) crea pastelli neutri aumentando la luminosità mantenendo la tonalità del colore originale. Questi pastelli generati casualmente di solito vanno bene insieme, specialmente in grandi numeri.

Ecco alcuni colors pastello generati usando il metodo sopra riportato:

Primo

Puoi anche mescolare il colore casuale con un pastello costante, che si traduce in un insieme colorato di colors neutri. Ad esempio, l’utilizzo di una luce blu crea colors come questi:

Secondo

Andando oltre, potresti aggiungere euristiche al tuo generatore che tiene conto di colors o livelli di ombreggiatura complementari, ma tutto dipende dall’impressione che vuoi ottenere con i tuoi colors casuali.

Alcune risorse aggiuntive:

Vorrei usare una ruota dei colors e data una posizione casuale si potrebbe aggiungere l’angolo dorato (137,5 gradi)

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

per ottenere colors diversi ogni volta che non si sovrappongono.

Regolando la luminosità della ruota dei colors è ansible ottenere anche diverse combinazioni di colors chiari / scuri.

Ho trovato questo post sul blog che spiega molto bene il problema e la soluzione che utilizza la sezione aurea.

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

AGGIORNAMENTO: ho appena trovato questo altro approccio:

Si chiama RYB (rosso, giallo, blu) ed è descritto in questo documento:

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

come “Paint Inspired Color Compositing”.

L’algoritmo genera i colors e ogni nuovo colore viene scelto per massimizzare la sua distanza euclidea rispetto a quelli selezionati in precedenza.

Qui puoi trovare una buona implementazione in javascript:

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

AGGIORNAMENTO 2:

The Sciences Po Medialb ha appena rilasciato uno strumento chiamato “I want Hue” che genera tavolozze di colors per i data scientist. Usare diversi spazi colore e generare le tavolozze usando k-means clustering o force vettori (repulsion graphs) I risultati di questi metodi sono molto buoni, 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; } 

Ho visto l’idea qui: http://blog.functionalfun.net/2008/07/random-pastel-colour-generator.html

La conversione in un’altra tavolozza è un modo molto superiore per farlo. C’è una ragione per cui lo fanno: le altre tavolozze sono “percettive” – ​​cioè, mettono simili colors apparenti vicini tra loro e la regolazione di una variabile cambia il colore in modo prevedibile. Nulla di ciò è vero per RGB, in cui non esiste una relazione evidente tra i colors che “vanno bene insieme”.

Una risposta che non deve essere trascurata, perché è semplice e presenta vantaggi, è il campionamento di foto e dipinti reali. campiona tutti i pixel casuali che desideri per i colors casuali sulle miniature delle immagini di arte moderna, cezanne, van gogh, monnet, foto … il vantaggio è che puoi ottenere colors per tema e che sono colors organici. metti solo 20 – 30 foto in una cartella e campiona casualmente una foto a caso ogni volta.

La conversione ai valori HSV è un algoritmo di codice molto diffuso per la tavolozza basata psicologicamente. hsv è più facile da randomizzare.

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 usando TriadMixing e CIE94 per evitare colors simili. L’immagine seguente utilizza i colors di input rosso, giallo e bianco. Vedi qui

TriadMixing + CIE94

Ecco un generatore di colore veloce e sporco in C # (usando l’approccio RYB descritto in questo articolo ). È una riscrittura da JavaScript .

Uso:

 List ColorPalette = ColorGenerator.Generate(30).ToList(); 

I primi due colors tendono ad essere bianchi e una tonalità di nero. Salto spesso in questo modo (usando Linq):

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

Implementazione:

 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 { private readonly int pointsCount; private double[] picked; private int pickedCount; private readonly List points = new List(); 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 GetEnumerator() { Generate(); for (int i = 0; i < pointsCount; i++) { yield return Pick(); } } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } } public static IEnumerable 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])); } } } 

Il metodo di David Crow in un R-due linee:

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

Per i colors pastello, passa più in alto luma scuro / interi chiari - cioè fnGetRandomColour (120, 250)

Crediti: tutti i crediti per http://paulirish.com/2009/random-hex-color-code-snippets/ stackoverflow.com/questions/12043187/how-to-check-if-hex-color-is-too-black

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

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

Esegui la funzione usando:

 generateRandomComplementaryColor(240, 240, 240); 

potresti averli entro una certa luminosità. che controllerebbe un po ‘la quantità di colors “neon”. per esempio, se la “luminosità”

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

era all’interno di un certo limite elevato, avrebbe un colore sbiadito e chiaro. Al contrario, se fosse all’interno di un certo limite inferiore, sarebbe più scuro. Questo eliminerebbe tutti i colors folli e standout e se scegliessi un limite veramente alto o molto basso, sarebbero tutti abbastanza vicini al bianco o al nero.

Sarà difficile ottenere ciò che vuoi algoritmicamente – le persone hanno studiato a lungo la teoria dei colors, e non conoscono nemmeno tutte le regole.

Tuttavia, vi sono alcune regole che è ansible utilizzare per selezionare combinazioni di colors errati (ad esempio, esistono regole per contrastare i colors e scegliere colors complementari).

Ti consiglio di visitare la sezione artistica della tua biblioteca e di consultare i libri sulla teoria dei colors per ottenere una migliore comprensione di ciò che è un buon colore prima di provare a crearne uno: sembra che tu non sappia nemmeno perché determinate combinazioni funzionano e altri non lo fanno t.

-Adamo

Consiglio vivamente l’uso di una funzione shader CG HSVtoRGB, sono fantastici … ti dà il controllo del colore naturale come un pittore invece del controllo come un monitor CRT, che non sei presumibilmente!

Questo è un modo per rendere 1 valore float. cioè Grigio, in 1000 ds di combinazioni di colors e 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 è una RANDOMIZZAZIONE INCREDIBILE DEL COLORE! non è naturale, ma utilizza sfumature di colore naturali e ha un aspetto organico e parametri irreparabilmente pastello / pastelli.

Perlin, puoi usare questa funzione, è una versione zigzag veloce 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; } 

Ecco qualcosa che ho scritto per un sito che ho realizzato. Genera automaticamente un colore di sfondo piatto casuale per ogni div con la class .flat-color-gen . Jquery è richiesto solo allo scopo di aggiungere css alla pagina; non è richiesto per la parte principale di questo, che è il metodo generateFlatColorWithOrder() .

Link JsFiddle

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

Usa colors distinti .

Scritto in javascript

Genera una tavolozza di colors visivamente distinti.

i colors distinti sono altamente configurabili:

  • Scegli quanti colors ci sono nella tavolozza
  • Limita la tonalità a un intervallo specifico
  • Limita il croma (saturazione) a un intervallo specifico
  • Limita la luminosità a un intervallo specifico
  • Configura la qualità generale della tavolozza