Как генерировать случайные "зеленоватые" цвета
У кого-нибудь есть предложения о том, как сделать рандомизированные цвета, которые все зеленоватые? Сейчас я генерирую цвета следующим образом:
color = (randint(100, 200), randint(120, 255), randint(100, 200))
В основном это работает, но я получаю коричневые цвета.
Ответы
Ответ 1
Простое решение: Используйте цветовое пространство HSL или HSV вместо rgb (затем конвертируйте его в RGB, если вы нужно это). Разница заключается в значении кортежа: где RGB означает значения для красного, зеленого и синего, в HSL H - цвет (например, 120 градусов или 0,33, что означает зеленый), а S - насыщенность, а V - яркость. Поэтому держите H по фиксированному значению (или даже для более случайных цветов, которые вы могли бы рандомизировать с помощью add/sub маленького случайного числа) и рандомизировать S и V. См. wikipedia.
Ответ 2
Как показали другие, генерация случайных цветов намного проще в цветовом пространстве HSV (или в HSL, разница в этом не имеет значения)
Итак, код для генерации случайных "зеленых" цветов и (для демонстрационных целей) отображает их как серию простых цветных тегов HTML span:
#!/usr/bin/env python2.5
"""Random green colour generator, written by dbr, for
http://stackoverflow.com/questions/1586147/how-to-generate-random-greenish-colors
"""
def hsv_to_rgb(h, s, v):
"""Converts HSV value to RGB values
Hue is in range 0-359 (degrees), value/saturation are in range 0-1 (float)
Direct implementation of:
http://en.wikipedia.org/wiki/HSL_and_HSV#Conversion_from_HSV_to_RGB
"""
h, s, v = [float(x) for x in (h, s, v)]
hi = (h / 60) % 6
hi = int(round(hi))
f = (h / 60) - (h / 60)
p = v * (1 - s)
q = v * (1 - f * s)
t = v * (1 - (1 - f) * s)
if hi == 0:
return v, t, p
elif hi == 1:
return q, v, p
elif hi == 2:
return p, v, t
elif hi == 3:
return p, q, v
elif hi == 4:
return t, p, v
elif hi == 5:
return v, p, q
def test():
"""Check examples on..
http://en.wikipedia.org/wiki/HSL_and_HSV#Examples
..work correctly
"""
def verify(got, expected):
if got != expected:
raise AssertionError("Got %s, expected %s" % (got, expected))
verify(hsv_to_rgb(0, 1, 1), (1, 0, 0))
verify(hsv_to_rgb(120, 0.5, 1.0), (0.5, 1, 0.5))
verify(hsv_to_rgb(240, 1, 0.5), (0, 0, 0.5))
def main():
"""Generate 50 random RGB colours, and create some simple coloured HTML
span tags to verify them.
"""
test() # Run simple test suite
from random import randint, uniform
for i in range(50):
# Tweak these values to change colours/variance
h = randint(90, 140) # Select random green'ish hue from hue wheel
s = uniform(0.2, 1)
v = uniform(0.3, 1)
r, g, b = hsv_to_rgb(h, s, v)
# Convert to 0-1 range for HTML output
r, g, b = [x*255 for x in (r, g, b)]
print "<span style='background:rgb(%i, %i, %i)'> </span>" % (r, g, b)
if __name__ == '__main__':
main()
Выход (при просмотре в веб-браузере) должен выглядеть примерно так:
![Example output, showing random green colours]()
Изменить: я не знал о модуле colorsys. Вместо вышеуказанной функции hsv_to_rgb
вы можете использовать colorsys.hsv_to_rgb, что делает код намного короче (это не совсем капля замена, так как моя функция hsv_to_rgb
ожидает, что оттенок будет в градусах вместо 0-1):
#!/usr/bin/env python2.5
from colorsys import hsv_to_rgb
from random import randint, uniform
for x in range(50):
h = uniform(0.25, 0.38) # Select random green'ish hue from hue wheel
s = uniform(0.2, 1)
v = uniform(0.3, 1)
r, g, b = hsv_to_rgb(h, s, v)
# Convert to 0-1 range for HTML output
r, g, b = [x*255 for x in (r, g, b)]
print "<span style='background:rgb(%i, %i, %i)'> </span>" % (r, g, b)
Ответ 3
Проверьте модуль colorsys
:
http://docs.python.org/library/colorsys.html
Используйте цветовое пространство HSL или HSV. Рандомизируйте оттенок, чтобы он был близок к зеленому, затем выберите абсолютно случайный материал для насыщения и V (яркость).
Ответ 4
Если вы придерживаетесь RGB, вам просто нужно убедиться, что значение G больше, чем R и B, и старайтесь сохранять одинаковые синие и красные значения, чтобы оттенок не слишком сумасшедший. Расширение от Slaks, может быть, что-то вроде (я почти ничего не знаю о Python):
greenval = randint(100, 255)
redval = randint(20,(greenval - 60))
blueval = randint((redval - 20), (redval + 20))
color = (redval, greenval, blueval)
Ответ 5
Итак, в этом случае вам посчастливилось захотеть вариации основного цвета, но для таких художественных целей лучше указать координаты цветовых колец, а не первичные цветовые величины.
Вероятно, вы хотите что-то из модуля colorsys
, например:
colorsys.hsv_to_rgb(h, s, v)
Convert the color from HSV coordinates to RGB coordinates.
Ответ 6
Решение с цветовым пространством HSx является очень хорошим. Однако, если вам нужно что-то чрезвычайно упрощенное и не имеет особых требований к распределению цветов (например, равномерность), упрощенное решение на основе RGB должно просто удостовериться, что значение G больше, чем R и B
rr = randint(100, 200)
rb = randint(100, 200)
rg = randint(max(rr, rb) + 1, 255)
Это даст вам "зеленоватые" цвета. Некоторые из них будут всегда слегка зеленоватыми. Вы можете увеличить гарантированную степень зеленоватости, увеличив (абсолютно или относительно) нижнюю границу последнего вызова randint
.
Ответ 7
Вы хотите работать с HSL вместо RGB. Вы можете найти диапазон оттенков, который удовлетворяет "зеленоватым" и выбирает из него случайный оттенок. Вы также можете выбрать случайную насыщенность и легкость, но вы, вероятно, захотите сохранить насыщенность около 1 и свою легкость около 0,5, но вы можете играть с ними.
Ниже приведен код actionscript для преобразования HSL в RGB. Я не касался python через некоторое время, или он опубликовал версию python.
Я нахожу, что зеленоватый - это что-то вроде 0,47 * PI до 0,8 * PI.
/**
@param h hue [0, 2PI]
@param s saturation [0,1]
@param l lightness [0,1]
@return object {r,g,b} {[0,1],[0,1][0,1]}
*/
public function hslToRGB(h:Number, s:Number, l:Number):Color
{
var q:Number = (l<0.5)?l*(1+s):l+s-l*s;
var p:Number = 2*l-q;
var h_k:Number = h/(Math.PI*2);
var t_r:Number = h_k+1/3;
var t_g:Number = h_k;
var t_b:Number = h_k-1/3;
if (t_r < 0) ++t_r; else if (t_r > 1) --t_r;
if (t_g < 0) ++t_g; else if (t_g > 1) --t_g;
if (t_b < 0) ++t_b; else if (t_b > 1) --t_b;
var c:Color = new Color();
if (t_r < 1/6) c.r = p+((q-p)*6*t_r);
else if (t_r < 1/2) c.r = q;
else if (t_r < 2/3) c.r = p+((q-p)*6*(2/3-t_r));
else c.r = p;
if (t_g < 1/6) c.g = p+((q-p)*6*t_g);
else if (t_g < 1/2) c.g = q;
else if (t_g < 2/3) c.g = p+((q-p)*6*(2/3-t_g));
else c.g = p;
if (t_b < 1/6) c.b = p+((q-p)*6*t_b);
else if (t_b < 1/2) c.b = q;
else if (t_b < 2/3) c.b = p+((q-p)*6*(2/3-t_b));
else c.b = p;
return c;
}
Ответ 8
Самый простой способ сделать это - убедиться, что красные и синие компоненты совпадают, например: (Простите мой Python)
rb = randint(100, 200)
color = (rb, randint(120, 255), rb)
Ответ 9
Я бы пошел с подходом HSV, о котором все говорили. Другой подход состоял бы в том, чтобы получить красивую фотографию с высоким разрешением, в которой есть зелень, вырезать незеленые части и выбирать из нее случайные пиксели, используя PIL.