Source code for uw.color

"""Color-manipulating utility routines.

Convenient functions for converting between RGB and HSV color spaces,
formatting colors for use in HTML/CSS, and generating a series of
(relatively) contrasting hues.
"""

import math

from itertools import islice

from ll.xist import xsc
from ll.xist.ns import html

[docs]def rgb2hsv (rgb): """Convert RGB color to HSV. :param rgb: a 3-tuple containing the R, G, and B values. :return: the HSV representation of the color as a 3-tuple. """ r, g, b = rgb _min = min (r, g, b) _max = max (r, g, b) if _max == 0: return 0, 0, 0 delta = _max - _min s = delta / _max v = _max if r == _max: h = (g - b) / delta elif g == _max: h = 2 + (b - r) / delta elif b == _max: h = 4 + (r - g) / delta else: raise return h * 60, s, v
[docs]def hsv2rgb (hsv): """Convert HSV color to RGB. :param hsv: a 3-tuple containing the H, S, and V values. :return: the RGB representation of the color as a 3-tuple. """ h, s, v = hsv h /= 60 i = math.floor (h) f = h - i p = v * (1 - s) q = v * (1 - s * f) t = v * (1 - s * (1 - f)) i %= 6 if i == 0: return v, t, p if i == 1: return q, v, p if i == 2: return p, v, t if i == 3: return p, q, v if i == 4: return t, p, v if i == 5: return v, p, q
[docs]def rgb2html (rgb): """Write an RGB color in HTML representation. :param rgb: a 3-tuple containing the R, G, and B values. :return: HTML/CSS attribute value representing the color. """ r, g, b = rgb r = round (r * 255) g = round (g * 255) b = round (b * 255) return '#%02X%02X%02X' % (r, g, b)
[docs]def hues (start=0): """Generate a sequence of hues intended to be contrasting. :param start: the starting point in the sequence of colors. :return: a generator which returns successive hue values. The hues start out with red (assuming the default start value is used) and rotate around the spectrum spaced out so that the set of hues returned up to any point is evenly distributed according to hue values. No attempt is made to optimize the distribution for human color perception, i.e., filling in some parts of the spectrum more or less densely to improve the human-visible contrast. """ step = 360 / ((1 + math.sqrt (5)) / 2) h = start while True: yield h h += step
[docs]def html_row (i, hsv): """Create a table row to demonstrate a hue. :param int i: the number of the row within the table, for inclusion in the first column. :param hsv: the color to demonstrate. :return: an HTML <tr> element showing the color, as well as related colors with 70% and 40% of the saturation of the given color. For use by :func:`html_sample`. """ h, s, v = hsv main_colour = rgb2html (hsv2rgb ((h, s, v))) second_colour = rgb2html (hsv2rgb ((h, s * 0.7, v))) third_colour = rgb2html (hsv2rgb ((h, s * 0.4, v))) return html.tr ( html.td (i, ' ', int (h) % 360), html.td (main_colour, style="background-color: %s" % main_colour), html.td (second_colour, style="background-color: %s" % second_colour), html.td (third_colour, style="background-color: %s" % third_colour), )
[docs]def html_sample (n): """Create a sample HTML page showing hues generated by :func:`hues`. :param int n: the number of hues to generate. :return: an HTML document containing a table with one row per hue. """ return xsc.Frag ( html.DocTypeHTML401transitional (), html.html ( html.head (html.title ()), html.body ( html.table ( html_row (i, base_colour) for i, base_colour in enumerate (islice (hues (), n)) ) ) ) )