Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,9 @@ easily. Here, is the color scale of the rainbow between red and blue::

>>> red = Color("red")
>>> blue = Color("blue")
>>> list(red.range_to(blue, 5))
>>> list(red.range_to(blue, 3))
[<Color red>, <Color magenta>, <Color blue>]
>>> list(red.range_to(blue, 5, longer=True))
[<Color red>, <Color yellow>, <Color lime>, <Color cyan>, <Color blue>]

Or the different amount of gray between black and white::
Expand Down
71 changes: 55 additions & 16 deletions colour.py
Original file line number Diff line number Diff line change
Expand Up @@ -690,16 +690,52 @@ def web2hex(web, force_long=False):
hsl2web = lambda x: rgb2web(hsl2rgb(x))


def color_scale(begin_hsl, end_hsl, nb):
def color_scale(begin_hsl, end_hsl, nb, longer=False):
"""Returns a list of nb color HSL tuples between begin_hsl and end_hsl

>>> from colour import color_scale

>>> [rgb2hex(hsl2rgb(hsl)) for hsl in color_scale((0, 1, 0.5),
... (1, 1, 0.5), 3)]
>>> [rgb2hex(hsl2rgb(hsl)) for hsl in color_scale((0, 1, 0.5), # longer, as is
... (1, 1, 0.5), 3, longer=True)]
['#f00', '#0f0', '#00f', '#f00']

>>> [rgb2hex(hsl2rgb(hsl))
>>> [rgb2hex(hsl2rgb(hsl)) for hsl in color_scale( # longer, as is, backwards
... (1, 1, 0.5),
... (0, 1, 0.5),
... 3, longer=True)]
['#f00', '#00f', '#0f0', '#f00']

>>> [rgb2hex(hsl2rgb(hsl)) for hsl in color_scale( # shorter, h1 incremented
... (0, 1, 0.5), # lower red
... (1, 1, 0.5), # higher red
... 3)]
['#f00', '#f00', '#f00', '#f00']

>>> [rgb2hex(hsl2rgb(hsl)) for hsl in color_scale( # shorter, h2 incremented
... (1, 1, 0.5), # lower red
... (0, 1, 0.5), # higher red
... 3)]
['#f00', '#f00', '#f00', '#f00']

>>> [rgb2hex(hsl2rgb(hsl)) for hsl in color_scale( # shorter, as is
... (1./3, 1, 0.5), # green
... (2./3, 1, 0.5), # blue
... 3)]
['#0f0', '#0fa', '#0af', '#00f']

>>> [rgb2hex(hsl2rgb(hsl)) for hsl in color_scale( # longer, h1 incremented
... (1./3, 1, 0.5), # green
... (2./3, 1, 0.5), # blue
... 3, longer=True)]
['#0f0', '#fa0', '#f0a', '#00f']

>>> [rgb2hex(hsl2rgb(hsl)) for hsl in color_scale( # longer, h2 incremented
... (2./3, 1, 0.5), # green
... (1./3, 1, 0.5), # blue
... 3, longer=True)]
['#00f', '#f0a', '#fa0', '#0f0']

>>> [rgb2hex(hsl2rgb(hsl)) #luminosity interpolation
... for hsl in color_scale((0, 0, 0),
... (0, 0, 1),
... 15)] # doctest: +ELLIPSIS
Expand All @@ -718,16 +754,19 @@ def color_scale(begin_hsl, end_hsl, nb):
raise ValueError(
"Unsupported negative number of colors (nb=%r)." % nb)

step = tuple([float(end_hsl[i] - begin_hsl[i]) / nb for i in range(0, 3)]) \
if nb > 0 else (0, 0, 0)

def mul(step, value):
return tuple([v * value for v in step])

def add_v(step, step2):
return tuple([v + step2[i] for i, v in enumerate(step)])

return [add_v(begin_hsl, mul(step, r)) for r in range(0, nb + 1)]
h1,s1,l1 = begin_hsl
h2,s2,l2 = end_hsl
if longer == (abs(h1-h2)<0.5):
if h1<h2:
h1+=1
else:
h2+=1
return [(
(h1*(1-v) + h2*v)%1,
s1*(1-v) + s2*v,
l1*(1-v) + l2*v)
for v in (float(step)/(nb) for step in range(nb+1))
]


##
Expand Down Expand Up @@ -1085,8 +1124,8 @@ def set_web(self, value):

## range of color generation

def range_to(self, value, steps):
for hsl in color_scale(self._hsl, Color(value).hsl, steps - 1):
def range_to(self, value, steps, longer=False):
for hsl in color_scale(self._hsl, Color(value).hsl, steps - 1, longer=longer):
yield Color(hsl=hsl)

##
Expand Down