Алгоритм случайного генерирования эстетически приятной цветовой палитры
Я ищу простой алгоритм для генерации большого количества случайных, эстетически приятных цветов. Так что никаких сумасшедших неоновых цветов, цветов, напоминающих фекалии и т.д.
Я нашел решения этой проблемы, но они полагаются на альтернативные цветовые палитры, чем RGB.
Я бы предпочел просто использовать прямой RGB, чем отображение взад и вперед. Эти другие решения также могут генерировать только 32 или около того приятных случайных цветов.
Любые идеи были бы замечательными.
Ответы
Ответ 1
Вы можете выровнять значения RGB случайных цветов с цветами, которые имеют постоянный цвет:
(пример в 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;
}
Смешивание случайных цветов с белым (255, 255, 255) создает нейтральные пастели, увеличивая легкость, сохраняя оттенок исходного цвета. Эти случайно сгенерированные пастели обычно хорошо сочетаются, особенно в больших количествах.
Вот несколько пастельных цветов, сгенерированных с использованием вышеуказанного метода:
![First]()
Вы также можете смешивать случайный цвет с постоянной пастелью, что приводит к тонированному набору нейтральных цветов. Например, использование синего цвета создает такие цвета:
![Second]()
Идя дальше, вы можете добавить эвристику к своему генератору, который учитывает дополнительные цвета или уровни затенения, но все зависит от впечатления, которое вы хотите достичь с помощью случайных цветов.
Некоторые дополнительные ресурсы:
Ответ 2
Я бы использовал цветное колесо и получил случайную позицию, вы могли бы добавить золотой угол (137,5 градуса)
http://en.wikipedia.org/wiki/Golden_angle
чтобы получать разные цвета каждый раз, когда они не перекрываются.
Регулировка яркости для цветового круга позволяет получить различные комбинации ярких/темных цветов.
Я нашел этот пост в блоге, который очень хорошо объясняет проблему и решение, используя золотой коэффициент.
http://martin.ankerl.com/2009/12/09/how-to-create-random-colors-programmatically/
ОБНОВЛЕНИЕ: Я только что нашел этот другой подход:
Он назвал RYB (красный, желтый, синий) метод и описан в этой статье:
http://threekings.tk/mirror/ryb_TR.pdf
как "Paint Inspired Color Compositing".
Алгоритм генерирует цвета, и каждый новый цвет выбирается так, чтобы максимизировать его эвклидово расстояние до ранее выбранных.
Здесь вы можете найти хорошую реализацию в javascript:
http://afriggeri.github.com/RYB/
ОБНОВЛЕНИЕ 2:
Наука Po Medialb только что выпустила инструмент под названием "Я хочу Хюэ", который генерирует цветовые палитры для ученых-данных. Использование разных цветовых пространств и создание палитр с помощью k -средних кластеров или векторов силы (графики отталкивания). Результаты этих методов очень хороши, они показывают теорию и реализацию на их веб-странице.
http://tools.medialab.sciences-po.fr/iwanthue/index.php
Ответ 3
В 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;
}
Вызвали идею здесь: http://blog.functionalfun.net/2008/07/random-pastel-colour-generator.html
Ответ 4
Преобразование в другую палитру - это намного лучший способ сделать это. Там есть причина, по которой они делают: другие палитры "перцептуальны", то есть они сближают похожие кажущиеся цвета, а корректировка одной переменной меняет цвет предсказуемым образом. Ничто из этого не верно для RGB, где нет очевидной взаимосвязи между цветами, которые "хорошо сочетаются".
Ответ 5
Ответ, который не следует упускать из виду, потому что он прост и представляет собой преимущества, - это выборка из реальных фотографий и картин. образец как много случайных пикселей, как вы хотите случайные цвета на миниатюры современного искусства, сезанна, ван Гога, монне, фотографии... Преимущество в том, что вы можете получать цвета по темам и что они являются органическими цветами. просто поместите 20-30 фотографий в папку и произвольный образец случайного изображения каждый раз.
Преобразование значений HSV - это распространенный кодовый алгоритм для психологической палитры. hsv легче рандомизировать.
Ответ 6
В 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;
}
источник: fooobar.com/questions/25856/...
Ответ 7
Вот быстрый и грязный генератор цвета в С# (используя "подход RYB", описанный в этой статье ). Это переписать из JavaScript.
Применение:
List<Color> ColorPalette = ColorGenerator.Generate(30).ToList();
Первые два цвета имеют белый цвет и оттенок черного. Я часто пропускаю их так (используя Linq):
List<Color> ColorsPalette = ColorGenerator
.Generate(30)
.Skip(2) // skip white and black
.ToList();
Реализация:
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]));
}
}
}
Ответ 8
Метод Дэвида Кроу в двустроне 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))
}
Ответ 9
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;
}
Для пастели передать более высокие темные/светлые числа яркости - то есть fnGetRandomColour (120, 250)
Кредиты: все кредиты http://paulirish.com/2009/random-hex-color-code-snippets/stackoverflow.com/questions/12043187/how-to-check-if-hex-color-is-too-black
Ответ 10
вы могли бы иметь их в определенной яркости. что немного контролирует количество "неоновых" цветов. например, если "яркость"
brightness = sqrt(R^2+G^2+B^2)
находился в пределах определенной высокой границы, он имел бы размытый, светлый цвет. И наоборот, если бы он находился в пределах определенной границы, было бы темнее. Это устранило бы любые сумасшедшие, выдающиеся цвета, и если бы вы выбрали действительно высокий или очень низкий уровень, все они были бы достаточно близки к белому или черному.
Ответ 11
JavaScript-адаптация оригинального ответа Дэвида Кроу, включая IE и 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) + ')';
}
Запустите функцию, используя:
generateRandomComplementaryColor(240, 240, 240);
Ответ 12
Будет сложно получить то, что вы хотите алгоритмически - люди изучают теорию цвета в течение длительного времени, и они даже не знают всех правил.
Однако существуют некоторые правила, которые вы можете использовать для устранения плохих комбинаций цветов (т.е. существуют правила для сочетания цветов и выбора дополнительных цветов).
Я бы порекомендовал вам посетить секцию библиотеки и проверить книги по теории цвета, чтобы лучше понять, что хорошего цвета, прежде чем пытаться это сделать - кажется, вы даже не знаете, почему работают определенные комбинации и другие не делают.
-Adam
Ответ 13
Я бы настоятельно рекомендовал использовать шейдерную функцию CG HSVtoRGB, они потрясающие... это дает вам естественный контроль цвета, как художник, а не как монитор crt, который вы предположительно считаете!
Это способ сделать 1 значение float. то есть серый, в 1000 дс комбинаций цвета, яркости и насыщенности и т.д.:
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);
результат - УДИВИТЕЛЬНАЯ ЦВЕТНАЯ РЕНДОМИЗАЦИЯ! он не является естественным, но он использует естественные цветовые градиенты, и он выглядит органично и контролируемо обводящими/пастельными параметрами.
Для перлина вы можете использовать эту функцию, это быстрая зигзагообразная версия 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;
}
Ответ 14
Вот что я написал для сайта, который я сделал. Он автоматически генерирует случайный плоский фоновый цвет для любого div с классом .flat-color-gen
. JQuery требуется только для добавления css на страницу; это не требуется для основной части этого, что является методом generateFlatColorWithOrder()
.
ссылка 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);
Ответ 15
Используйте distinct-colors.
Написано в javascript.
Создает палитру визуально разных цветов.
отличительные цвета очень настраиваются:
- Выберите количество цветов в палитре
- Ограничить оттенок до определенного диапазона
- Ограничить цветность (насыщенность) до определенного диапазона
- Ограничьте яркость до определенного диапазона.
- Настроить общее качество палитры
Ответ 16
У меня есть успех, используя TriadMixing и CIE94, чтобы избежать подобных цветов. На следующем изображении используются цвета ввода: красный, желтый и белый. См. здесь.
![TriadMixing + CIE94]()