Algoritmo para generar al azar una paleta de colores estéticamente agradable

Estoy buscando un algoritmo simple para generar una gran cantidad de colores aleatorios y estéticamente agradables. Así que no hay colores de neón locos, colores que recuerden a las heces, etc.

He encontrado soluciones a este problema, pero se basan en paletas de colores alternativos a RGB. Preferiría simplemente utilizar un RGB directo que un mapeo de ida y vuelta. Estas otras soluciones también pueden, a lo sumo, generar solo 32 colores aleatorios agradables.

Cualquier idea sería genial.

Puede promediar los valores RGB de colores aleatorios con los de un color constante:

(ejemplo en 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 combinación de colores aleatorios con blanco (255, 255, 255) crea pasteles neutros al boost la luminosidad y mantener el tono del color original. Estos pasteles generados aleatoriamente generalmente van bien juntos, especialmente en grandes cantidades.

Aquí hay algunos colores pastel generados usando el método anterior:

primero

También podría mezclar el color aleatorio con un pastel constante, lo que da como resultado un conjunto de colores neutros tintados. Por ejemplo, usar un azul claro crea colores como estos:

Segundo

Yendo más lejos, podría agregar heurísticas a su generador que tengan en cuenta los colores complementarios o los niveles de sombreado, pero todo depende de la impresión que desee lograr con sus colores aleatorios.

Algunos recursos adicionales:

Usaría una rueda de colores y, dada una posición aleatoria, podría agregar el ángulo dorado (137,5 grados)

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

para obtener diferentes colores cada vez que no se superpongan.

Al ajustar el brillo de la rueda de colores, también puede obtener diferentes combinaciones de colores shinys / oscuros.

Encontré esta publicación de blog que explica muy bien el problema y la solución usando la proporción áurea.

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

ACTUALIZACIÓN: Acabo de encontrar este otro enfoque:

Se llama método RYB (rojo, amarillo, azul) y se describe en este documento:

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

como “Compuesto de color inspirado en la pintura”.

El algoritmo genera los colores y cada nuevo color se elige para maximizar su distancia euclidiana a los previamente seleccionados.

Aquí puedes encontrar una buena implementación en javascript:

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

ACTUALIZACIÓN 2:

The Sciences Po Medialb acaba de lanzar una herramienta llamada “I want Hue” que genera paletas de colores para los científicos de datos. Usar diferentes espacios de color y generar las paletas utilizando k-means clustering o force vectores (gráficos de repulsión) Los resultados de esos métodos son muy buenos, muestran la teoría y una implementación en su página web.

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

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

Vi la idea aquí: http://blog.functionalfun.net/2008/07/random-pastel-colour-generator.html

La conversión a otra paleta es una forma muy superior de hacer esto. Hay una razón por la que lo hacen: otras paletas son “perceptivas”, es decir, colocan colores parecidos similares muy juntos y el ajuste de una variable cambia el color de manera predecible. Nada de eso es cierto para RGB, donde no existe una relación obvia entre los colores que “van bien juntos”.

Una respuesta que no debe pasarse por alto, ya que es simple y presenta ventajas, es el muestreo de fotos y pinturas de la vida real. muestra tantos píxeles aleatorios como quieras en colores aleatorios en miniaturas de fotos de arte moderno, cezanne, van gogh, monnet, fotos … la ventaja es que puedes obtener colores por tema y que son colores orgánicos. solo ponga 20 – 30 fotos en una carpeta y muestree al azar una foto al azar cada vez.

La conversión a valores de HSV es un algoritmo de código generalizado para la paleta de base psicológica. hsv es más fácil de aleatorizar.

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

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

Tuve éxito usando TriadMixing y CIE94 para evitar colores similares. La siguiente imagen usa colores de entrada rojo, amarillo y blanco. Mira aquí .

TriadMixing + CIE94

Aquí hay un generador de color rápido y sucio en C # (usando el ‘enfoque RYB’ descrito en este artículo ). Es una reescritura de JavaScript .

Utilizar:

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

Los primeros dos colores tienden a ser de color blanco y un tono de negro. A menudo me los salteo así (usando Linq):

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

Implementación:

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

El método de David Crow en un R de dos líneas:

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

Para pastel, pase en números enteros / oscuros más claros de luminancia, es decir, fnGetRandomColour (120, 250)

Créditos: todos los créditos a http://paulirish.com/2009/random-hex-color-code-snippets/ stackoverflow.com/questions/12043187/how-to-check-if-hex-color-is-too-black

Adaptación de JavaScript de la respuesta original de David Crow, IE y el código específico de Nodej incluido.

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

Ejecute la función usando:

 generateRandomComplementaryColor(240, 240, 240); 

podrías tenerlos dentro de un cierto brillo. eso controlaría un poco la cantidad de colores “neón”. por ejemplo, si el “brillo”

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

estaba dentro de un cierto límite alto, tendría un color claro descolorido. Por el contrario, si estuviera dentro de un cierto límite bajo, sería más oscuro. Esto eliminaría cualquier color loco y destacado, y si elegías un límite realmente alto o muy bajo, todos estarían bastante cerca de blanco o negro.

Va a ser difícil obtener lo que desea de forma algorítmica: las personas han estado estudiando la teoría del color durante mucho tiempo, y ni siquiera conocen todas las reglas.

Sin embargo, hay algunas reglas que puede usar para eliminar combinaciones de colores incorrectos (es decir, existen reglas para los colores que chocan y para elegir colores complementarios).

Te recomendaría que visites la sección de arte de tu biblioteca y saques libros sobre la teoría del color para comprender mejor qué es un buen color antes de intentar crear uno; parece que ni siquiera sabrás por qué ciertas combinaciones funcionan y otras no. t.

-Adán

Recomiendo encarecidamente usar una función de sombreado CG HSVtoRGB, son increíbles … te da un control de color natural como un pintor en lugar de control como un monitor de crt, ¡lo que probablemente no es!

Esta es una forma de hacer 1 valor flotante. es decir, gris, en 1000 ds de combinaciones de color y brillo y saturación, etc.

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

¡El resultado es una ALEATORIZACIÓN DE COLORES INCREÍBLE! no es natural, pero usa gradientes de color naturales y tiene un aspecto orgánico y controlablemente irritacente / en colores pastel.

Para perlin, puedes usar esta función, es una versión rápida en zig zag de 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; } 

Aquí hay algo que escribí para un sitio que hice. .flat-color-gen generará un fondo de color aleatorio para cualquier div con la clase .flat-color-gen . Jquery solo es necesario para agregar css a la página; no es necesario para la parte principal de esto, que es el método 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); 

Usa distintos colores .

Escrito en javascript

Genera una paleta de colores visualmente distintos.

distinct-colors es altamente configurable:

  • Elija cuántos colores hay en la paleta
  • Restringir el tono a un rango específico
  • Restringir el croma (saturación) a un rango específico
  • Restringe la ligereza a un rango específico
  • Configurar la calidad general de la paleta