Как создать случайную шестнадцатеричную строку, которая представляет цвет? - PullRequest
36 голосов
/ 08 апреля 2009

Я создаю несколько диаграмм, для которых нужна шестнадцатеричная строка для цветов.

Пример:

<dataseries name="ford" color="FF00FF" />

Я создаю их динамически, поэтому я хотел бы генерировать шестнадцатеричный код для каждой серии данных случайным образом.

Каков наилучший способ сделать это?

Ответы [ 6 ]

116 голосов
/ 08 апреля 2009

Самый простой способ - использовать String.Format и использовать шестнадцатеричный формат для аргумента.

var random = new Random();
var color = String.Format("#{0:X6}", random.Next(0x1000000)); // = "#A197B9"
16 голосов
/ 08 апреля 2009

IMO, чисто случайные цвета могут быть не предпочтительны, так как вам нужны цвета, которые различимы в человеческих глазах.

А как насчет того, чтобы задать количество цветов и выбрать их случайным образом?

Возможно, вы могли бы найти лучшие ответы в некоторых библиотеках диаграмм с открытым исходным кодом.

15 голосов
/ 08 апреля 2009

Ответ Самуила - лучший способ сделать это, просто убедитесь, что если вы генерируете цвета внутри цикла, вы не создаете новый объект Random каждый раз, потому что new Random() запускает генератор, используя системные часы. Ваш цикл будет работать быстрее, чем могут тикать часы, поэтому вы в конечном итоге будете генерировать несколько одинаковых цветов снова и снова, потому что random засевается с одним и тем же значением.

Это должно выглядеть примерно так:

int numColors = 10;
var colors = new List<string>();
var random = new Random(); // Make sure this is out of the loop!
for (int i = 0; i < numColors; i++) 
{
    colors.Add(String.Format("#{0:X6}", random.Next(0x1000000)));
}

вместо:

int numColors = 10;
var colors = new List<string>();
for (int i = 0; i < numColors; i++) 
{
    var random = new Random(); // Don't put this here!
    colors.Add(String.Format("#{0:X6}", random.Next(0x1000000)));
}
12 голосов
/ 08 апреля 2009

Хороший способ создать хороший набор цветов - определить их, используя фиксированную насыщенность и яркость, и изменить оттенок.

  1. Установите насыщенность и яркость на то, что вам нравится, скажем, 50% насыщенности и 90% яркости.
  2. Теперь разделите 360-градусный оттенок на желаемое количество различных цветов.
  3. Выберите цвета из HSV, используя этот интервал для оттенка, а также фиксированные S и V.

Это дает вам хороший набор цветов, которые выглядят так, как будто они из одного «набора» - все пастельные, или все насыщенные, или все не совсем белые, что угодно. И это довольно легко кодировать, если у вас есть Color.FromHSV ().

Вероятно, он перестает работать, когда вы получите слишком много цветов, хотя они будут неразличимы. Но, возможно, вы все равно получите эту проблему.

В псевдокоде:

Sat = 0.5 * 255 //assuming we want range 0-255...
Brightness = 0.9 * 255
NumberOfColours = 7
HueSeparation = 360 / 7
Colors = []
for (i = 0 ; i< NumberOfColours; i++)
     Colors.Add(Color.FromHSV(HueSeparation * i, Sat, Brightness)

или

n = 7
Colors = [Color.FromHSV(x*360/n, 128, 230) for x in range(n)]

(мне нравятся списки ...)

4 голосов
/ 08 апреля 2009
Random rand = new Random(); // specify a seed
int r = rand.Next(0x1000000); 
Console.WriteLine("#{0:X6}", r);
3 голосов
/ 08 апреля 2009

Я заметил, что вы (Rahkim) прокомментировали сообщение Грега, что хотите, чтобы вы могли поместить его идею (сохранение константы насыщенности и значения и просто изменение оттенка ... хорошая идея) в коде. Вы можете! Или, скорее, кто-то уже есть для вас!

Я нашел этот пост в блоге Преобразование HSV в цвет RGB с использованием C # , и я уверен, что есть и другие. Вы, вероятно, получите более хороший набор цветов, чем, выбирая их совершенно случайно.

Кроме того, конечно, этот метод упрощает получение хорошего набора цветов ... так как Hue начинается с 0-359, вы можете сделать что-то вроде установки Hue примерно так:

Hue = (PreviousHue + 50) % 360;

(Я выбрал 50, поскольку он не входит в 360 равномерно, поэтому, если вы превысите 360, вы не начнете повторять оттенки сразу. Вам нужно будет поиграться со значением, чтобы получить идеальное разделение в зависимости от того, как много разных цветов вы ожидаете.)

Таким образом, вам не нужно беспокоиться о случае, когда код случайным образом выбирает два цвета, которые очень близки друг к другу, когда еще остается много неиспользованного пространства "оттенка".

...