image-to-color-wheel / color_wheel.py
T.Masuda
create app
1e2f65e
raw
history blame contribute delete
No virus
3.85 kB
import math
from color import Color
class ColorWheel:
@property
def base_color(self):
return self._base_color
@property
def hue(self):
return [
self.base_color, self.add_h(1.0 / 12), self.add_h(2.0 / 12), self.add_h(3.0 / 12), self.add_h(4.0 / 12), self.add_h(5.0 / 12),
self.add_h(-6.0 / 12), self.add_h(-5.0 / 12), self.add_h(-4.0 / 12), self.add_h(-3.0 / 12), self.add_h(-2.0 / 12), self.add_h(-1.0 / 12)
]
@property
def tone(self):
return [self.add_white(-2.0 / 16), self.add_white(-1.0 / 16), self.base_color, self.add_white(1.0 / 16), self.add_white(2.0 / 16)]
@property
def tone15(self):
return [self.add_white(-7.0 / 16), self.add_white(-6.0 / 16), self.add_white(-5.0 / 16), self.add_white(-4.0 / 16), self.add_white(-3.0 / 16),
self.add_white(-2.0 / 16), self.add_white(-1.0 / 16), self.base_color, self.add_white(1.0 / 16), self.add_white(2.0 / 16),
self.add_white(3.0 / 16), self.add_white(4.0 / 16), self.add_white(5.0 / 16), self.add_white(6.0 / 16), self.add_white(7.0 / 16)]
@property
def complementary_colors(self):
return [self.base_color, self.add_h(0.5)]
@property
def triadic_colors(self):
return [self.add_h(-4.0 / 12), self.base_color, self.add_h(4.0 / 12)]
@property
def split_complementary_colors(self):
return [self.add_h(-5.0 / 12), self.base_color, self.add_h(5.0 / 12)]
@property
def analogous_colors(self):
return [self.add_h(-2.0 / 12), self.add_h(-1.0 / 12), self.base_color, self.add_h(1.0 / 12), self.add_h(2.0 / 12)]
def __init__(self, c):
self._base_color = c
self._r = c.r / 255.0
self._g = c.g / 255.0
self._b = c.b / 255.0
@staticmethod
def from_hsv(h, s, v):
r, g, b = ColorWheel.hsv_to_rgb(h, s, v)
c = Color.from_rgb(round(r * 255), round(g * 255), round(b * 255))
return ColorWheel(c)
def add_white(self, value):
r, g, b = (self._r + value, self._g + value, self._b + value)
r = min(max(r, 0.0), 1.0)
g = min(max(g, 0.0), 1.0)
b = min(max(b, 0.0), 1.0)
return self._from_rgb(r, g, b)
def add_h(self, value):
h, s, v = ColorWheel.rgb_to_hsv(self._r, self._g, self._b)
h = (h + value) % 1.0
if h < 0.0:
h += 1.0
r, g, b = ColorWheel.hsv_to_rgb(h, s, v)
return self._from_rgb(r, g, b)
def add_s(self, value):
h, s, v = ColorWheel.rgb_to_hsv(self._r, self._g, self._b)
s += value
s = min(max(s, 0.0), 1.0)
r, g, b = ColorWheel.hsv_to_rgb(h, s, v)
return self._from_rgb(r, g, b)
def add_v(self, value):
h, s, v = ColorWheel.rgb_to_hsv(self._r, self._g, self._b)
v += value
v = min(max(v, 0.0), 1.0)
r, g, b = ColorWheel.hsv_to_rgb(h, s, v)
return self._from_rgb(r, g, b)
@staticmethod
def rgb_to_hsv(r, g, b):
if r < 0.0 or r > 1.0:
raise ValueError()
if g < 0.0 or g > 1.0:
raise ValueError()
if b < 0.0 or b > 1.0:
raise ValueError()
cmax = max(r, g, b)
cmin = min(r, g, b)
h = cmax - cmin
if h > 0.0:
if cmax == r:
h = (g - b) / h
if h < 0.0:
h += 6.0
elif cmax == g:
h = 2.0 + (b - r) / h
else:
h = 4.0 + (r - g) / h
h /= 6.0
s = cmax - cmin
if cmax != 0.0:
s /= cmax
v = cmax
return h, s, v
@staticmethod
def hsv_to_rgb(h, s, v):
if h < 0.0 or h > 1.0:
raise ValueError()
if s < 0.0 or s > 1.0:
raise ValueError()
if v < 0.0 or v > 1.0:
raise ValueError()
r = v
g = v
b = v
if s > 0.0:
h *= 6.0
i = math.floor(h)
f = h - i
if i == 1:
r *= 1 - s * f
b *= 1 - s
elif i == 2:
r *= 1 - s
b *= 1 - s * (1 - f)
elif i == 3:
r *= 1 - s
g *= 1 - s * f
elif i == 4:
r *= 1 - s * (1 - f)
g *= 1 - s
elif i == 5:
g *= 1 - s
b *= 1 - s * f
else:
g *= 1 - s * (1 - f)
b *= 1 - s
return r, g, b
def _from_rgb(self, r, g, b):
return Color.from_argb(self.base_color.a, round(r * 255), round(g * 255), round(b * 255))