-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathgradient.py
executable file
·101 lines (85 loc) · 2.28 KB
/
gradient.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
#!/usr/bin/env python3-allemande
"""
gradient.py: generate a gradient of colors
Accepts colors in the following formats:
- hex code: #000000
- rgb code: rgb(255,0,0)
- single channel float: 1.0
- single channel int: 255
- rgba hex code: #00000000
- rgba code: rgba(0,255,0,0)
"""
import sys
import numpy as np
import re
import argh
from io import StringIO
# https://stackoverflow.com/questions/25668828/how-to-create-a-list-of-colours-in-a-spectrum
def clamp(x, minimum, maximum):
return max(minimum, min(x, maximum))
def uint8(x):
return clamp(int(x), 0, 255)
def float_to_uint8(x):
return uint8(x * 256)
def rgb_to_hex(rgb):
return '#%02x%02x%02x' % tuple(map(float_to_uint8, rgb))
def hex_to_rgb(hex):
h = hex.lstrip('#')
if 3 <= len(h) <= 4:
a = [h[i]*2 for i in range(3)]
else:
a = [h[i:i+2] for i in range(0, len(h), 2)]
return tuple(int(x, 16) for x in a)
def to_rgb(x):
if isinstance(x, (tuple, list, np.ndarray)):
return x
if x.startswith('#'):
return hex_to_rgb(x)
if x.startswith('rgb(') and x.endswith(')'):
x = x[4:-1]
if re.match(r'\s*[\d.]+$', x):
t = float(x)
if "." not in x:
t = t / 256
return (t, t, t)
if re.match(r'\s*[\d.]+\s*(,\s*[\d.]+\s*){2,3}$', x):
t = map(float, x.split(','))
if "." not in x:
t = [x / 256 for x in t]
return tuple(t)
raise ValueError(f"invalid color code: {x}")
def gradient(start, end, steps, out=sys.stdout, css=False):
if css:
print(f"\t/* gradient.py --css {start} {end} {steps} */", file=out)
start, end = map(to_rgb, (start, end))
steps = int(steps)
a0, a1 = map(np.array, (start, end))
for i in range(steps):
rgb = a0 + (a1 - a0) * i / (steps - 1)
# convert to rgb hex code
hexcode = rgb_to_hex(rgb)
if css:
name = f'col{i}'
print(f"\t--{name}: {hexcode};", file=out)
else:
print(hexcode, file=out)
def test_gradient():
start = "#000000"
end = "rgb(255,255,255)"
out = StringIO()
gradient(start, end, 8, out, css=True)
assert out.getvalue() == """\
/* gradient.py --css #000000 rgb(255,255,255) 8 */
--col0: #000000;
--col1: #242424;
--col2: #484848;
--col3: #6d6d6d;
--col4: #919191;
--col5: #b6b6b6;
--col6: #dadada;
--col7: #ffffff;
"""
if __name__ == '__main__':
parser = argh.ArghParser(description=__doc__)
parser.set_default_command(gradient)
argh.dispatch(parser)