def propagate(self, led_block): """ Normalize the state, level, and color for an LED block so that they are consistent with each other when the state is on. No changes are made if the state is off. """ # Shortcut nvo_data = led_block.nvoLoadStatus.data nvo_data.control = LoadControl.load_control_t.LOAD_REPORT if nvo_data.state: # State is on; get the color and check the level red_coordinate = float(nvo_data.color.color_value.RGB.red) / float(MAX_RED_LEVEL) green_coordinate = float(nvo_data.color.color_value.RGB.green) / float(MAX_GREEN_LEVEL) blue_coordinate = float(nvo_data.color.color_value.RGB.blue) / float(MAX_BLUE_LEVEL) is_black = True if red_coordinate + blue_coordinate + green_coordinate == 0. else False print('Normalize LED settings for {0}R:{1}G:{2}B, is_black={3}, and level={4}'.format( red_coordinate, green_coordinate, blue_coordinate, is_black, nvo_data.level)) if math.isnan(nvo_data.level) or \ nvo_data.level < 0.: # Level not specified; check the color if is_black: # Color is black; set to white and set level to 100% nvo_data.color.encoding = ColorEncoding.color_encoding_t.COLOR_RGB nvo_data.color.color_value.RGB.red = MAX_RED_LEVEL nvo_data.color.color_value.RGB.green = MAX_GREEN_LEVEL nvo_data.color.color_value.RGB.blue = MAX_BLUE_LEVEL nvo_data.level = float(MAX_BRIGHTNESS_LEVEL) else: # Color specified; set the level from the color hls_color = colorsys.rgb_to_hls(red_coordinate, green_coordinate, blue_coordinate) nvo_data.level = \ float((hls_color[LUMINANCE]/MAX_LUMINANCE_LEVEL)*MAX_BRIGHTNESS_LEVEL) print('Level not specified; new level is {0}'.format( nvo_data.level)) else: # Level specified print('Level specified as {0}'.format(nvo_data.level)) if nvo_data.level == 0.: # State is on but level if 0; set the level to 100% nvo_data.level = float(MAX_BRIGHTNESS_LEVEL) print('Level changed from 0 to {0}'.format(nvo_data.level)) if is_black: # State is on but color is black; set to white then adjust the level red_coordinate = 1.0 green_coordinate = 1.0 blue_coordinate = 1.0 # Level and color specified; adjust color to match the level print('Adjusted level is {0}'.format(nvo_data.level)) lightness_coordinate = nvo_data.level / float(MAX_BRIGHTNESS_LEVEL) hls_color = colorsys.rgb_to_hls(red_coordinate, green_coordinate, blue_coordinate) adjusted_rgb = colorsys.hls_to_rgb(hls_color[HUE], lightness_coordinate, hls_color[SATURATION]) nvo_data.color.encoding = ColorEncoding.color_encoding_t.COLOR_RGB nvo_data.color.color_value.RGB.red = int(adjusted_rgb[RED] * 255.) nvo_data.color.color_value.RGB.green = int(adjusted_rgb[GREEN] * 255.) nvo_data.color.color_value.RGB.blue = int(adjusted_rgb[BLUE] * 255.) print('Adjusted color: {0}H:{1}L:{2}S, {3}R:{4}G:{5}B, {6}HLS'.format( hls_color[HUE], lightness_coordinate, hls_color[SATURATION], adjusted_rgb[RED], adjusted_rgb[GREEN], adjusted_rgb[BLUE], hls_color))
def __str__(self): # TODO bit of a hack? if self.tokens is not None and isinstance(self.tokens, ParserValue): return self.tokens.value type = self.type c = self.value if type == 'hsl' or type == 'hsla' and c[3] == 1: h, l, s = colorsys.rgb_to_hls(c[0] / 255.0, c[1] / 255.0, c[2] / 255.0) return 'hsl(%s, %s%%, %s%%)' % (to_str(h * 360.0), to_str(s * 100.0), to_str(l * 100.0)) if type == 'hsla': h, l, s = colorsys.rgb_to_hls(c[0] / 255.0, c[1] / 255.0, c[2] / 255.0) return 'hsla(%s, %s%%, %s%%, %s)' % (to_str(h * 360.0), to_str(s * 100.0), to_str(l * 100.0), to_str(c[3])) r, g, b = to_str(c[0]), to_str(c[1]), to_str(c[2]) are_integral = True for n in c[:3]: # replicating old logic; perhaps needs rethinking n2 = round(n * 100, 1) if n2 != int(n2): are_integral = False break if c[3] == 1: if not are_integral: return 'rgb(%s%%, %s%%, %s%%)' % (to_str(c[0] * 100.0 / 255.0), to_str(c[1] * 100.0 / 255.0), to_str(c[2] * 100.0 / 255.0)) return '#%02x%02x%02x' % (round(c[0]), round(c[1]), round(c[2])) if not are_integral: return 'rgba(%s%%, %s%%, %s%%, %s)' % (to_str(c[0] * 100.0 / 255.0), to_str(c[1] * 100.0 / 255.0), to_str(c[2] * 100.0 / 255.0), to_str(c[3])) return 'rgba(%d, %d, %d, %s)' % (round(c[0]), round(c[1]), round(c[2]), to_str(c[3]))
def __call__(self, data): # TODO support color, support cubic spline interpolation v = self.e(data) for i, (value, threshold) in enumerate(self.pairs): if threshold is None: return value elif v >= threshold: xmin = threshold xmax = self.pairs[i+1][1] xspn = xmax-xmin y = (v-xmin)/xspn if self.method == Interpolate.CUBIC: pass elif self.method == Interpolate.COSINE: y = math.cos(math.pi*y) if self.mode == Interpolate.NUMERIC: return y*value + (1-y)*self.pairs[i+1][0] elif self.mode == Interpolate.COLOR: lc = np.array(colorsys.rgb_to_hls(*value[0:3]/255.0), dtype=np.float32) rc = np.array(colorsys.rgb_to_hls(*self.pairs[i+1][0][0:3]/255.0), dtype=np.float32) fc = y*lc + (1-y)*rc return tuple(fc) else: raise NotImplementedError()
def get_billiards_number(white_color_ratio, r, g, b): billiards_type = _get_billiardsType(white_color_ratio) if billiards_type == BilliardsType.White: return 0 if billiards_type == BilliardsType.Little and _is_black(r, g, b): return 8 if _get_max_band(r, g, b) == "G": return 6 + billiards_type if _get_max_band(r, g, b) == "B": h, l, s = colorsys.rgb_to_hls(r, g, b) if abs(h - 0.5) < abs(h - 0.833333): return 2 + billiards_type else: return 4 + billiards_type if _get_max_band(r, g, b) == "R": if r - g < g - b : # yellow color return 1 + billiards_type h, l, s = colorsys.rgb_to_hls(r, g, b) if abs(h - 0.166667) < abs(h - 0.833333): if _is_black(0, g, b): # pure red color return 3 + billiards_type else: return 5 + billiards_type else: return 7 + billiards_type
def get_hsl_gradient_point(val, min_val, max_val, start_rgb, end_rgb): """ Return an RGB position on a HSL gradient. RGB tuples have values in the range [0 .. 255]. """ if (val < min_val): val = min_val elif (val > max_val): val = max_val start = colorsys.rgb_to_hls( \ start_rgb[0] / 255, start_rgb[1] / 255, start_rgb[2] / 255) end = colorsys.rgb_to_hls( \ end_rgb[0] / 255, end_rgb[1] / 255, end_rgb[2] / 255) hls = [0, 0, 0] for i in range(3): ch_delta = end[i] - start[i] val_range = max_val - min_val normal_val = val - min_val normal_max_val = max_val - min_val hls[i] = start[i] + ch_delta * (normal_val / normal_max_val) rgb = colorsys.hls_to_rgb(*hls) return (int(rgb[0] * 255), int(rgb[1] * 255), int(rgb[2] * 255))
def darken(rgb_hex): # Split into r, g, and b whilst converting to decimal values r_var = int(list(rgb_hex)[0]+list(rgb_hex)[1], 16)/255.0 g_var = int(list(rgb_hex)[2]+list(rgb_hex)[3], 16)/255.0 b_var = int(list(rgb_hex)[4]+list(rgb_hex)[5], 16)/255.0 # Converts to hsl h_var = round(rgb_to_hls(r_var, g_var, b_var)[0]*255) l_var = round(rgb_to_hls(r_var, g_var, b_var)[1]*255) s_var = round(rgb_to_hls(r_var, g_var, b_var)[2]*255) # Makes lighter code if l_var < 10: l2_var = 0 else: l2_var = l_var-10 r2_var = round(hls_to_rgb(h_var/255.0, l2_var/255.0, s_var/255.0)[0]*255) g2_var = round(hls_to_rgb(h_var/255.0, l2_var/255.0, s_var/255.0)[1]*255) b2_var = round(hls_to_rgb(h_var/255.0, l2_var/255.0, s_var/255.0)[2]*255) if len(hex(r2_var)[2:]) == 1: r_hex = "0"+hex(r2_var)[2:] else: r_hex = hex(r2_var)[2:] if len(hex(g2_var)[2:]) == 1: g_hex = "0"+hex(g2_var)[2:] else: g_hex = hex(g2_var)[2:] if len(hex(b2_var)[2:]) == 1: b_hex = "0"+hex(b2_var)[2:] else: b_hex = hex(b2_var)[2:] return r_hex+g_hex+b_hex # the lighter code
def rgba_to_color(r, g, b, a, format='rgba'): r = min(max(r, 0), 1) g = min(max(g, 0), 1) b = min(max(b, 0), 1) a = min(max(a, 0), 1) if format == 'hex': return '#%02x%02x%02x' % (r * 255 + .5, g * 255 + .5, b * 255 + .5) if format == 'rgb': return 'rgb(%.0f, %.0f, %.0f)' % (r * 255, g * 255, b * 255) if format == 'rgba': return 'rgba(%.0f, %.0f, %.0f, %.3f)' % (r * 255, g * 255, b * 255, a) if format == 'rgb_p': return 'rgb(%.0f%%, %.0f%%, %.0f%%)' % (r * 100, g * 100, b * 100) if format == 'rgba_p': return ('rgba(%.0f%%, %.0f%%, %.0f%%, %.3f)' % (r * 100, g * 100, b * 100, a)) if format == 'hsl': h, l, s = colorsys.rgb_to_hls(r, g, b) return 'hsl(%.0f, %.0f%%, %.0f%%)' % (h * 360, s * 100, l * 100) if format == 'hsla': h, l, s = colorsys.rgb_to_hls(r, g, b) return ('hsla(%.0f, %.0f%%, %.0f%%, %.3f)' % (h * 360, s * 100, l * 100, a)) raise ValueError, 'Invalid color format: %s' % format
def _color_subtree(node, color=None, level=0, max_lum=0.9, min_lum=0.1): global colormap node.color = color #max_lum = 1 if color is not None: hls = np.asarray(colorsys.rgb_to_hls(*color)) max_lum = min(max_lum, hls[1] + 0.2) min_lum = max(min_lum, hls[1] - 0.2) children_sizes = map(len, node.children) indices = np.argsort(children_sizes)[::-1] luminosities = np.linspace(max_lum, min_lum, len(node.children)+1) #for child, luminosity, offset in zip(node.children, luminosities, offsets): for i, idx in enumerate(indices): child = node.children[idx] if level <= min_level: color = next(colormap) _color_subtree(child, color, level+1) else: hls = np.asarray(colorsys.rgb_to_hls(*color)) #rbg = colorsys.hls_to_rgb(hls[0], (luminosities[i]+luminosities[i+1])/2, hls[2]) rbg = colorsys.hls_to_rgb(hls[0], luminosities[i+1], hls[2]) _color_subtree(child, np.asarray(rbg), level+1, luminosities[i], luminosities[i+1])
def _color_subtree(node, color=None, level=0): global colormap node.color = color max_luminosity = 0 if color is not None: hls = np.asarray(colorsys.rgb_to_hls(*color)) max_luminosity = hls[1] #luminosities = np.linspace(0.3, 0.8, len(node.children)) children_sizes = map(len, node.children) indices = np.argsort(children_sizes)[::-1] luminosities = np.linspace(max_luminosity, 0.2, len(node.children)) #for child, luminosity, offset in zip(node.children, luminosities, offsets): for idx, luminosity in zip(indices, luminosities): child = node.children[idx] if level <= min_level: color = next(colormap) _color_subtree(child, color, level+1) else: hls = np.asarray(colorsys.rgb_to_hls(*color)) #if hls[1] > 0.8: # hls[1] -= 0.3 #elif hls[1] < 0.3: # hls[1] += 0.3 rbg = colorsys.hls_to_rgb(hls[0], luminosity, hls[2]) _color_subtree(child, np.asarray(rbg), level+1)
def __init__(self, fn, left_color, right_color, null_color=None, stops=32): self.fn = fn self.left_color = left_color self.right_color = right_color self.null_color = null_color self.lc = np.array(colorsys.rgb_to_hls(*left_color[0:3]/255.0) + (left_color[3]/255.0,), dtype=np.float32) self.rc = np.array(colorsys.rgb_to_hls(*right_color[0:3]/255.0) + (right_color[3]/255.0,), dtype=np.float32) self.stops = stops
def similarColor(self, color1, color2, debug=False): c1 = self.toRGB(color1) c2 = self.toRGB(color2) h1 = colorsys.rgb_to_hls(c1[0], c1[1], c1[2]) h2 = colorsys.rgb_to_hls(c2[0], c2[1], c2[2]) if debug: print h1,h2 return (h1[1]<=h2[1]+20 and h1[1] >= h2[1]-20) and (h1[0]<=h2[0]+0.1 and h1[0] >= h2[0]-0.1)
def at(self, v0, v1, t): """ Returns the color value along the path at time t for a path whose start value is v0, and whose end value is v1. """ c0 = normalized_color(v0, has_alpha=True, as_int=False) c1 = normalized_color(v1, has_alpha=True, as_int=False) h0, l0, s0 = rgb_to_hls(*c0[:3]) h1, l1, s1 = rgb_to_hls(*c1[:3]) return hls_to_rgb( h0 + ((h1 - h0) * t * self.use_h), l0 + ((l1 - l0) * t * self.use_l), s0 + ((s1 - s0) * t * self.use_s) ) + (c0[3] + ((c1[3] - c0[3]) * t * self.use_a),)
def value_to_hsl(self, value, as_str=False): """ :param value: float value to convert to HSL color :param as_str: Toggle to force resulting HSL color as a string in the form 'hsl({}, {}%, {}%)' :type as_str: bool :returns: HSL color as tuple or string Convert the given value to the appropriate color resulting color is represented in HSL (not rgb) """ if value < self.minimum_value: value = self.minimum_value elif value > self.maximum_value: value = self.maximum_value if self.minimum_value < 0: offset = abs(self.minimum_value) minimum_value = self.minimum_value + offset maximum_value = self.maximum_value + offset value = value + offset else: minimum_value = self.minimum_value maximum_value = self.maximum_value if all(i == 0 for i in (value, minimum_value, maximum_value)): scale = 1.0 else: scale = float(value - minimum_value) / float(maximum_value - minimum_value) # scale all channels linearly between START_COLOR and END_COLOR start_rgb = self.get_rgb_tuple(self.hex_min_color) end_rgb = self.get_rgb_tuple(self.hex_max_color) # convert rgb to hsl # --> put rgb values on scale between 0, and 1 for usage with colorsys conversion functions # results in values 0-1 for all (h,l,s) start_hls = rgb_to_hls(*[v / 255.0 for v in start_rgb]) end_hls = rgb_to_hls(*[v / 255.0 for v in end_rgb]) h, l, s = [float(scale * (end - start) + start) for start, end in zip(start_hls, end_hls)] # adjust to expected scales 0-360, 0-100, 0-100 h *= 360 l *= 100 s *= 100 assert 0 <= h <= 360 assert 0 <= l <= 100 assert 0 <= s <= 100 hsl_color = (int(h), int(s), int(l)) if as_str: hsl_color = "hsl({}, {}%, {}%)".format(*hsl_color) return hsl_color
def closeness(color_a, color_b): ra, ga, ba, aa = color_a rb, gb, bb, ab = color_b ha, la, sa = colorsys.rgb_to_hls(ra, ga, ba) hb, lb, sb = colorsys.rgb_to_hls(rb, gb, bb) maxh = max(ha, hb) minh = min(ha, hb) difference = min(maxh-minh, (minh+1)-maxh) return difference
def _get_insensitive_color(self, key, state, element): new_state = state.copy() new_state["insensitive"] = False fill = self.get_key_rgba(key, "fill", new_state) rgba = self.get_key_rgba(key, element, new_state) h, lf, s = colorsys.rgb_to_hls(*fill[:3]) h, ll, s = colorsys.rgb_to_hls(*rgba[:3]) # Leave only one third of the lightness difference # between label and fill color. amount = (ll - lf) * 2.0 / 3.0 return brighten(-amount, *rgba)
def blend(c, bg, alpha_h, alpha_l, alpha_s): """Fade from c to bg in the hue, lightness, saturation colorspace.""" r1,g1,b1 = int2rgb(c) h1,l1,s1 = colorsys.rgb_to_hls(r1/256.0, g1/256.0, b1/256.0) r2,g2,b2 = int2rgb(bg) h2,l2,s2 = colorsys.rgb_to_hls(r2/256.0, g2/256.0, b2/256.0) h = alpha_h * h1 + (1 - alpha_h) * h2 l = alpha_l * l1 + (1 - alpha_l) * l2 s = alpha_s * s1 + (1 - alpha_s) * s2 r,g,b = colorsys.hls_to_rgb(h, l, s) r = round(r * 256.0) g = round(g * 256.0) b = round(b * 256.0) t = rgb2int(int(r),int(g),int(b)) return int(t)
def tint(self, colour): '''Return new tinted image''' r, g, b = hex_to_float(colour) h, _, s = colorsys.rgb_to_hls(r, g, b) result = StringIO.StringIO() for i in xrange(0, self._size[0] * self._size[1] * 4, 4): r, g, b, a = tuple(ord(c) / 255. for c in self._rgba[i:i+4]) _, l, _ = colorsys.rgb_to_hls(r, g, b) r, g, b = colorsys.hls_to_rgb(h, l, s) result.write(''.join(chr(int(i * 255)) for i in [r, g, b, a])) return self.__class__(rgba=result.getvalue(), size=self._size)
def set_hls_values(color, h=None, l=None, s=None): """Independently manipulate the h, l, or s channels of a color. Parameters ---------- color : matplotlib color hex, rgb-tuple, or html color name h, l, s : floats between 0 and 1, or None new values for each channel in hls space Returns ------- new_color : rgb tuple new color code in RGB tuple representation """ # Get rgb tuple representation rgb = mplcol.colorConverter.to_rgb(color) vals = list(colorsys.rgb_to_hls(*rgb)) for i, val in enumerate([h, l, s]): if val is not None: vals[i] = val rgb = colorsys.hls_to_rgb(*vals) return rgb
def to_hls(integer): rgb = NicoSubtitle.to_rgb(integer) rgb_decimals = map(lambda x: int(x, 16), (rgb[0:2], rgb[2:4], rgb[4:6])) rgb_coordinates = map(lambda x: x / 255, rgb_decimals) hls_corrdinates = colorsys.rgb_to_hls(*rgb_coordinates) hls = hls_corrdinates[0] * 360, hls_corrdinates[1] * 100, hls_corrdinates[2] * 100 return hls
def convert_color(c, to_schema='rgb'): """ Convert a color to another schema. """ color_attrs = c.keys() # RGB to x if ''.join(sorted(color_attrs)) == 'bgr': if to_schema == 'rgb': return c elif to_schema == 'hsv': hsv = colorsys.rgb_to_hsv(c['r']/255.0, c['g']/255.0, c['b']/255.0) return dict(zip(['h', 's', 'v'], hsv)) elif to_schema == 'hls': hsv = colorsys.rgb_to_hls(c['r']/255.0, c['g']/255.0, c['b']/255.0) return dict(zip(['h', 'l', 's'], hsv)) # HSV to x elif ''.join(sorted(color_attrs)) == 'hsv': from_schema = 'hsv' if to_schema == 'hsv': return c elif to_schema == 'rgb': rgb = colorsys.hsv_to_rgb(c['h'], c['s'], c['v']) return dict(zip(['r', 'g', 'b'], [int(255 * attr) for attr in rgb])) # HLS to x elif ''.join(sorted(color_attrs)) == 'hls': from_schema = 'hls' if to_schema == 'hls': return c elif to_schema == 'rgb': rgb = colorsys.hls_to_rgb(c['h'], c['l'], c['s']) return dict(zip(['r', 'g', 'b'], [int(255 * attr) for attr in rgb]))
def fromhex_hsva(k, col): (fr, fg, fb) = (int(col[1:3], 16)/255.0, int(col[3:5], 16)/255.0, int(col[5:7], 16)/255.0) if k.startswith("hsv"): (nh, ns, nv) = colorsys.rgb_to_hsv(fr, fg, fb) else: (nh, nv, ns) = colorsys.rgb_to_hls(fr, fg, fb) return (str(int(nh * 360)), str(int(ns * 100)) + '%', str(int(nv * 100)) + '%')
def create_html_data(tags, size=(500,500), layout=LAYOUT_MIX, fontname=DEFAULT_FONT, rectangular=False): """ Create data structures to be used for HTML tag clouds. """ sizeRect, tag_store = _draw_cloud(tags, layout, size=size, fontname=fontname, rectangular=rectangular) tag_store = sorted(tag_store, key=lambda tag: tag.tag['size']) tag_store.reverse() data = { 'css': {}, 'links': [] } color_map = {} for color_index, tag in enumerate(tags): if not color_map.has_key(tag['color']): color_name = "c%d" % color_index hslcolor = colorsys.rgb_to_hls(tag['color'][0] / 255.0, tag['color'][1] / 255.0, tag['color'][2] / 255.0) lighter = hslcolor[1] * 1.4 if lighter > 1: lighter = 1 light = colorsys.hls_to_rgb(hslcolor[0], lighter, hslcolor[2]) data['css'][color_name] = ('#%02x%02x%02x' % tag['color'], '#%02x%02x%02x' % (light[0] * 255, light[1] * 255, light[2] * 255)) color_map[tag['color']] = color_name for stag in tag_store: metrics = stag.font.metrics(stag.tag['tag']) line_offset = 0 if min([f[2] for f in metrics]) < stag.font.get_descent() * 0.1: line_offset = stag.font.get_linesize() - 1.95 * (stag.font.get_ascent() + abs(stag.font.get_descent() * 0.9) - stag.rect.height) else: line_offset = stag.font.get_linesize() - 1.95 * (stag.font.get_ascent() - stag.rect.height) tag = { 'tag': stag.tag['tag'], 'cls': color_map[stag.tag['color']], 'top': stag.rect.y - 10, 'left': stag.rect.x, 'size': stag.tag['size'] - 6, 'height': stag.rect.height * 1.15, 'width': stag.rect.width, 'lh': line_offset } data['links'].append(tag) data['size'] = (sizeRect.w, sizeRect.h * 1.15) return data
def get_cont_col(col): (h, l, s) = colorsys.rgb_to_hls(int(col[1:3], 16)/255.0, int(col[3:5], 16)/255.0, int(col[5:7], 16)/255.0) l1 = 1 - l if abs(l1 - l) < .15: l1 = .15 (r, g, b) = colorsys.hls_to_rgb(h, l1, s) return tohex(int(r * 255), int(g * 255), int(b * 255)) # true complementary
def _box_colors(vals, color, sat): """Find colors to use for boxplots or violinplots.""" if color is None: # Default uses either the current palette or husl current_palette = mpl.rcParams["axes.color_cycle"] if len(vals) <= len(current_palette): colors = color_palette(n_colors=len(vals)) else: colors = husl_palette(len(vals), l=.7) else: try: color = mpl.colors.colorConverter.to_rgb(color) colors = [color for _ in vals] except ValueError: colors = color_palette(color, len(vals)) # Desaturate a bit because these are patches colors = [mpl.colors.colorConverter.to_rgb(c) for c in colors] colors = [desaturate(c, sat) for c in colors] # Determine the gray color for the lines light_vals = [colorsys.rgb_to_hls(*c)[1] for c in colors] l = min(light_vals) * .6 gray = (l, l, l) return colors, gray
def ascii_and_color_for_region(region, luminances): # Do a simple average of HSL. # Use the L to determine which character to use # Use RGB average for the actual letter color # This should give a mix of whitespace and color to represent the cell source = region.load() total_h, total_s, total_l = (0,0,0) total_r, total_g, total_b = (0,0,0) region_x, region_y = region.size total_pixels = region_x * region_y for x in range(region_x): for y in range(region_y): r, g, b, a = source[x,y] h, l, s = rgb_to_hls(r/255, g/255, b/255) total_h += h total_l += l total_s += s total_r += r total_g += g total_b += b avg_h, avg_l, avg_s = (total_h/total_pixels, total_l/total_pixels, total_s/total_pixels) letter = ascii_for_luminance(avg_l, luminances) color_percentage = hls_to_rgb(avg_h, avg_l, avg_s) return (letter, (total_r/total_pixels, total_g/total_pixels, total_b/total_pixels))
def _to_hlsa ( self, color ): """ Returns a GUI toolkit neutral color converted to an HLSA tuple. """ return tuple( list( rgb_to_hls( color[0] / 255.0, color[1] / 255.0, color[2] / 255.0 ) ) + [ color[3] / 255.0 ] )
def col_from_hash(self, hashTriple, hue1=None): col = hashTriple * 1.0 / 255.0 colHls = colorsys.rgb_to_hls(col[0], col[1], col[2]) colHls = list(colHls) # ensure different hues if hue1 and abs(colHls[0] - hue1) < 0.15: colHls[0] += 0.15 colHls[0] %= 1.0 # limit saturation if colHls[2] > 0.6: colHls[2] *= 0.6 # limit lightness if colHls[1] > 0.36: colHls[1] *= 0.6 if colHls[1] > 0.36: colHls[1] *= 0.6 # additional darker color colHlsD = np.copy(colHls) if colHls[1] < 0.18: colHls[1] *= 2.0 else: colHlsD[1] *= 0.5 return hls_to_np_col(colHls), hls_to_np_col(colHlsD), colHls[0]
def __init__(self, frame_number, filename, frame): self.filename = filename self.frame_number = frame_number b, g, r, a = cv2.mean(frame) self.frame_color_RGB = (r, g, b) self.frame_color_HSV = colorsys.rgb_to_hls(r, g, b) cv2.imwrite(filename, frame)
def desaturate(color, prop): """Decrease the saturation channel of a color by some percent. Parameters ---------- color : matplotlib color hex, rgb-tuple, or html color name prop : float saturation channel of color will be multiplied by this value Returns ------- new_color : rgb tuple desaturated color code in RGB tuple representation """ # Check inputs if not 0 <= prop <= 1: raise ValueError("prop must be between 0 and 1") # Get rgb tuple rep rgb = mplcol.colorConverter.to_rgb(color) # Convert to hls h, l, s = colorsys.rgb_to_hls(*rgb) # Desaturate the saturation channel s *= prop # Convert back to rgb new_color = colorsys.hls_to_rgb(h, l, s) return new_color
def find_match(req, hexnumber, list): r, g, b = req.hex_to_rgbfloat(hexnumber) h, l, s = colorsys.rgb_to_hls(r, g, b) ndf = 0 color = None df = -1 q = ColorModel.all().filter("t =", ColorModel.color_lists.index(list)) results = q.fetch(limit=10000) for c in results: ndf = ( ((r - c.r) ** 2) + ((g - c.g) ** 2) + ((b - c.b) ** 2) + (((h - c.h) ** 2) + ((s - c.s) ** 2) + ((l - c.l) ** 2)) * 2 ) if not 0 < df < ndf: df = ndf color = c if not color: return ColorModel.get_by_key_name("0000000") else: return color
def addNoiseTo(color, hueNoise, lightNoise, satNoise): hue, lightness, saturation = colorsys.rgb_to_hls(*color) hue = max(0, min(1, hue + hueNoise)) lightness = max(0, min(1, lightness + lightNoise)) saturation = max(0, min(1, saturation + satNoise)) return colorsys.hls_to_rgb(hue, lightness, saturation)
def with_l_factor(self, factor): h, l, s = colorsys.rgb_to_hls(self.color[0], self.color[1], self.color[2]) r, g, b = colorsys.hls_to_rgb(h, Color.clamp(l * factor), s) return Color(r, g, b, self.color[3])
def hsla(self): h, l, s = colorsys.rgb_to_hls(self.r / 255.0, self.g / 255.0, self.b / 255.0) return "hsla({:g},{:g}%,{:g}%,{:g})".format(h * 360.0, s * 100.0, l * 100.0, self.a)
def hex_to_hls(hex): r, g, b = map(lambda x: int(x, 16) / 255, (hex[1:3], hex[3:5], hex[5:7])) return rgb_to_hls(r, g, b)
def plot_genome_landscape(): df, w, q = df_from_files(snakemake.input.data_files) # replace NaNs introduced by the outer merge with the prediction with zeros # NaNs occur, when segment lengths above K occur df = df.fillna(0) # split values above w and below (including) w # for the values below w summ up all values above w # into on entry at w + 5 summed, above_w = sum_and_scatter(df, w) summed["Expected Prob Line"] = summed["Expected Probability"].where(summed["Segment Length"] <= w) # plot empiric distributions try: fontscale = snakemake.params.fontscale except AttributeError: fontscale = 1.8 sns.set( font="DejaVu Sans", style=sns.axes_style("whitegrid", {'grid.linestyle': '--'}), font_scale=fontscale, ) g = sns.FacetGrid( summed, row="hf", col="canonicity", hue="canonicity", height=5, aspect=1.8, margin_titles=True, ) g1 = g.map(plt.bar, "Segment Length", "prob") g.fig.suptitle(f"Segment Length Distributions for $w={w}$, $q={q}$", y=1.01) # fix broken z-order # save lower layer (layer 1, barplot) # so that later layers can be put above backgroundartists = [] for ax in g1.axes.flat: # ax.set_ylim(10**(-4), 1) for li in ax.lines + ax.collections: li.set_zorder(1) backgroundartists.append(li) beyond_w_bar = [rect for rect in ax.get_children() if isinstance(rect, Rect)][-2] # take the color of the bar andmake it darker (col_r, col_g, col_b, col_a) = beyond_w_bar.get_fc() col_h, col_l, col_s = colorsys.rgb_to_hls(col_r, col_g, col_b) col_r, col_g, col_b = colorsys.hls_to_rgb(col_h, col_l-0.2, col_s) beyond_w_bar.set_color((col_r, col_g, col_b, col_a)) # plot predicted points and manually place them on a higher layer than the bars g2 = g.map(sns.scatterplot, "Segment Length", "Expected Probability", color="black", s=50) for ax in g2.axes.flat: for li in ax.lines + ax.collections: if li not in backgroundartists: li.set_zorder(5) g.map( sns.lineplot, "Segment Length", "Expected Prob Line", color="black", alpha=0.7, ) # Adjust ticks so that the summed values at the dummy offset are labeled # correctly. currently the dummy value is at w + 5 for ax in g2.axes.flat: labels = [item.get_text() if item.get_text()!=f"{w+5}" else ">w" for item in ax.get_xticklabels()] ax.set_xticklabels(labels) ylabel = ax.get_ylabel() ax.set_ylabel(ylabel if ylabel != "Expected Prob Line" else "Probability") g.set(yscale="log") plt.savefig(snakemake.output.landscape_pdf, bbox_inches='tight') plt.clf() g = sns.FacetGrid(above_w, row="hf", col="canonicity", height=5, aspect=2) g1 = g.map(plt.bar, "Segment Length", "prob",) g.set(yscale="log") plt.savefig("above_w_violins.pdf", bbox_inches='tight')
def main(): print('png_to_copper_list') for _filename in filename_in: print('Loading bitmap : ' + _filename) ## Loads the PNG image png_buffer = png.Reader(filename=_filename) b = png_buffer.read() # print(b) ## Get size & depth w = b[0] h = b[1] print('w = ' + str(w) + ', h = ' + str(h)) print('bitdepth = ' + str(b[3]['bitdepth'])) if b[3]['greyscale']: print('!!!Error, cannot process a greyscale image :(') return 0 if b[3]['bitdepth'] > 8: print('!!!Error, cannot process a true color image :(') return 0 original_palette = b[3]['palette'] png_out_buffer = [] prev_optimized_line_palette = [] buffer_in = list(b[2]) ## For each line of the image for j in range(0, h): line_stat = {} optimized_line_palette = [] ## Calculate the occurence of each color index ## used in the current pixel row for line_offset in range(-1, 1): if j + line_offset >= 0 and j + line_offset < len(buffer_in): for p in buffer_in[j + line_offset]: if str(p) in line_stat: line_stat[str(p)] += 1 else: line_stat[str(p)] = 1 ## Occurence weighted by the saturation of the color for color_index_by_occurence in line_stat: _rgb_color = original_palette[int(color_index_by_occurence)] w_factor = (colorsys.rgb_to_hls(_rgb_color[0], _rgb_color[1], _rgb_color[2])[2] * 2.0) + 1.0 line_stat[color_index_by_occurence] = int( w_factor * line_stat[color_index_by_occurence]) # print('Found ' + str(len(line_stat)) + ' colors in line ' + str(j) + '.') original_line_palette = [] for color_index_by_occurence in sorted(line_stat, key=line_stat.get): original_line_palette.append( original_palette[int(color_index_by_occurence)]) ## If there's less than 32 colors on the same row ## the hardware can handle it natively, there's no need ## to reduce the palette. if len(original_line_palette) <= g_max_color_per_line: optimized_line_palette = original_line_palette optimized_line_palette.extend( [(0, 0, 0)] * (g_max_color_per_line - len(original_line_palette))) else: ## If there's more than 32 colors on the same row ## the hardware cannot handle it, so the palette ## must be reduced. # original_line_palette = sort_palette_by_luminance(original_line_palette) optimized_line_palette = [] found_a_color = True while len( optimized_line_palette) < g_max_color_per_line and len( original_line_palette ) > 0 and found_a_color is True: found_a_color = False for _color in original_line_palette: if _color[0] > 127 or _color[1] > 127 or _color[ 2] > 127: if len(optimized_line_palette ) >= g_max_color_per_line: break optimized_line_palette.append(_color) original_line_palette.remove(_color) found_a_color = True found_a_color = True while len( optimized_line_palette) < g_max_color_per_line and len( original_line_palette ) > 0 and found_a_color is True: found_a_color = False for _color in original_line_palette: if _color[0] > 64 or _color[1] > 64 or _color[2] > 64: if len(optimized_line_palette ) >= g_max_color_per_line: break optimized_line_palette.append(_color) original_line_palette.remove(_color) found_a_color = True # print('Temporary line palette is ' + str(len(optimized_line_palette)) + ' colors.') optimized_line_palette = sort_palette_by_luminance( optimized_line_palette) ## Mix the line palette with the previous line palette ## So that the copper will only have to change 16 colors per line if len(optimized_line_palette) > 0: _col_start = 0 if j % 2 == 0: _col_start = 1 if len(prev_optimized_line_palette) > 0: for _idx in range(_col_start, 32, 2): if _idx < len(optimized_line_palette) and _idx < len( prev_optimized_line_palette): # print('copy ' + str(prev_optimized_line_palette[_idx]) + ' to ' + str(optimized_line_palette[_idx])) optimized_line_palette[ _idx] = prev_optimized_line_palette[_idx] # prev_optimized_line_palette = list(optimized_line_palette) _updated_color_count = 0 for _idx in range(0, len(prev_optimized_line_palette)): if _idx < len(optimized_line_palette) and _idx < len( prev_optimized_line_palette): if optimized_line_palette[ _idx] == prev_optimized_line_palette[_idx]: _updated_color_count += 1 # print(str(_updated_color_count) + ' colors updated from previous line.') ## Make sure the colors belong to an OCS palette. _tmp_palette = [] for _color in optimized_line_palette: _tmp_palette.append(quantize_color_as_OCS(_color)) optimized_line_palette = _tmp_palette prev_optimized_line_palette = list(optimized_line_palette) ## Creates the EHB 32 complimentary colors. _tmp_palette = list(optimized_line_palette) for _color in _tmp_palette: optimized_line_palette.append(color_compute_EHB_value(_color)) # print('Final line palette is ' + str(len(optimized_line_palette)) + ' colors.') ## Remap the current line ## Using the optimized palette OPT_INDEXED_OUTPUT = False OPT_DUMP_PAL = False _filename_out = _filename.replace('.png', '_out.png') print('_filename_out = ' + _filename_out) line_out_buffer = [] if OPT_INDEXED_OUTPUT: print('Saving as indexed colors.') for p in buffer_in[j]: current_pixel_color = original_palette[p] if current_pixel_color in optimized_line_palette or len( optimized_line_palette) < 1: ## We found the exact color we were looking for line_out_buffer.append(current_pixel_color[0]) line_out_buffer.append(current_pixel_color[1]) line_out_buffer.append(current_pixel_color[2]) else: _color_match = color_best_match(current_pixel_color, optimized_line_palette) line_out_buffer.append(_color_match[0]) line_out_buffer.append(_color_match[1]) line_out_buffer.append(_color_match[2]) png_out_buffer.append(line_out_buffer) if len(png_out_buffer) > 0: png_out_buffer.append(line_out_buffer) f = open(_filename_out, 'wb') w = png.Writer(w, h, palette=optimized_line_palette, bitdepth=8) w.write(f, png_out_buffer) f.close() if not OPT_INDEXED_OUTPUT: print('Saving as true color.') _dump_pal_count = 0 for p in buffer_in[j]: if OPT_DUMP_PAL and _dump_pal_count < len( optimized_line_palette): line_out_buffer.append( optimized_line_palette[_dump_pal_count][0]) line_out_buffer.append( optimized_line_palette[_dump_pal_count][1]) line_out_buffer.append( optimized_line_palette[_dump_pal_count][2]) else: current_pixel_color = original_palette[p] if current_pixel_color in optimized_line_palette or len( optimized_line_palette) < 1: ## We found the exact color we were looking for line_out_buffer.append(current_pixel_color[0]) line_out_buffer.append(current_pixel_color[1]) line_out_buffer.append(current_pixel_color[2]) else: _color_match = color_best_match( current_pixel_color, optimized_line_palette) line_out_buffer.append(_color_match[0]) line_out_buffer.append(_color_match[1]) line_out_buffer.append(_color_match[2]) _dump_pal_count += 1 png_out_buffer.append(line_out_buffer) if len(png_out_buffer) > 0: f = open(_filename_out, 'wb') w = png.Writer(w, h) w.write(f, png_out_buffer) f.close() # print(original_line_palette) return 1
def sort_palette_by_luminance(colors): return sorted( colors, key=lambda c: colorsys.rgb_to_hls(1.0 - c[0] / 255.0, 1.0 - c[ 1] / 255.0, 1.0 - c[2] / 255.0)[1]) ##[::-1]
def run(*args): logger = logging.getLogger(__name__) logger.setLevel(logging.INFO) sheet = cssutils.parseFile('static/css/base.css') selector_coloring = {} for rule in sheet: if hasattr(rule, 'selectorText'): selector = rule.selectorText.lstrip('.') color = rule.style.getPropertyValue('color') if color and re.match('#[0-9A-Za-z]', color): color = color.lstrip('#') if len(color) == 3: color = ''.join(a + b for a, b in zip(color, color)) color = '#' + color assert selector not in selector_coloring or selector_coloring.get( selector) == color selector_coloring[selector] = color for resource in Resource.objects.all(): if not resource.ratings: continue to_save = False prev_rgb = None hsl = None for rating in resource.ratings: cls = f'coder-{rating["color"]}' if 'rgb' in rating: rating.pop('rgb') if 'hsv' in rating: rating.pop('hsv') hex_rgb = selector_coloring[cls] if rating.get('hex_rgb') != hex_rgb: rating['hex_rgb'] = hex_rgb to_save = True rgb = [int(hex_rgb[i:i + 2], 16) / 255 for i in range(1, 6, 2)] H, L, S = [round(x, 2) for x in colorsys.rgb_to_hls(*rgb)] if prev_rgb == hex_rgb: H, S, L = hsl L *= 0.75 hsl = [H, S, L] if rating.get('hsl') != hsl: rating['hsl'] = hsl to_save = True prev_rgb = hex_rgb limit = None for rating in reversed(resource.ratings[:-1]): if limit is None or rating['color'] != limit['color']: limit = rating value = limit['high'] + 1 if rating.get('next') != value: rating['next'] = value to_save = True limit = None for rating in resource.ratings[:-1]: if limit is None or rating['color'] != limit['color']: limit = rating value = limit['low'] if rating.get('prev') != value: rating['prev'] = value to_save = True if to_save: pprint(resource.ratings) resource.save()
def l(self): h, l, s = colorsys.rgb_to_hls(self.color[0], self.color[1], self.color[2]) return l
def color_shift(color, hue_shift): (r, g, b) = get_rgb(color) (h, l, s) = colorsys.rgb_to_hls(r / 255.0, g / 255.0, b / 255.0) (r_new, g_new, b_new) = colorsys.hls_to_rgb(h + hue_shift / 360.0, l, s) return get_hex(int(r_new * 255), int(g_new * 255), int(b_new * 255))
def brighten(rgb, how_much=0.0): hls = list(colorsys.rgb_to_hls(*rgb)) hls[1] = hls[1] + how_much * (1.0 - hls[1]) return colorsys.hls_to_rgb(*hls)
def adjust_color_lightness(color, p): r, g, b = hex_to_rgb(color) h, l, s = rgb_to_hls(r / 255, g / 255, b / 255) l = max(min(l * p, 1.0), 0.0) color = rgb_to_hex(*tuple([int(c * 255) for c in hls_to_rgb(h, l, s)])) return color
def hsl(self): """ :rtype: tuple """ h, l, s = colorsys.rgb_to_hls(r=self.red, g=self.green, b=self.blue) return h, s, l
def rgb_to_hsl(r, g, b): hsl = colorsys.rgb_to_hls(r / 255.0, g / 255.0, b / 255.0) hsl255 = [int(each * 255) for each in hsl] hsl255 = [hsl255[0], hsl255[2], hsl255[1]] return hsl255
def adjust_color_lightness(r, g, b, factor): h, l, s = rgb_to_hls(r / 255.0, g / 255.0, b / 255.0) l = max(min(l * factor, 1.0), 0.0) r, g, b = hls_to_rgb(h, l, s) return int(r * 255), int(g * 255), int(b * 255)
def lightness(color, lightness=.94): rgb = np.array([color.r, color.g, color.b]) / 255 h, _, s = rgb_to_hls(*rgb) rgb = np.array(hls_to_rgb(h, lightness, s)) * 255 return RGB(*rgb)
def get_hsl(rgb) -> tuple: c = [x / 255.0 for x in rgb[:3]] h, l, s = colorsys.rgb_to_hls(*c) return h * 360, s * 100, l * 100
def hls_channels(self): return rgb_to_hls(*(c / 255 for c in self.rgb_channels()))
def draw_errorbars(self): if self.n_data_sets == 1: bin_height = [self.bin_content] bin_err = [self.bin_err] if self.histtype != 'marker': vis_object = [self.vis_object] else: vis_object = self.vis_object elif self.stacked: bin_height = [self.bin_content[-1]] bin_err = [self.bin_err] vis_object = [self.vis_object] else: bin_height = self.bin_content bin_err = self.bin_err vis_object = self.vis_object if not self.stacked: n_data_sets_eff = self.n_data_sets else: n_data_sets_eff = 1 for i in range(n_data_sets_eff): if self.err_dict['err_color'] == 'auto' and not self.stacked: if self.histtype == 'marker': # err_color = colors.to_rgba(vis_object[i]._get_rgba_face()) err_color = colors.to_rgba( vis_object[i].get_markerfacecolor(), vis_object[i]._alpha) elif self.histtype in ['stepfilled', 'bar']: err_color = colors.to_rgba( vis_object[i][0].get_facecolor()) elif self.histtype == 'step': err_color = colors.to_rgba( vis_object[i][0].get_edgecolor()) hls_tmp = colorsys.rgb_to_hls(*err_color[:-1]) err_color = list(colorsys.hls_to_rgb(hls_tmp[0], hls_tmp[1]*0.7, hls_tmp[2])) + \ [err_color[-1]] elif self.err_dict['err_color'] == 'auto' and self.stacked: err_color = next(self.ax._get_lines.prop_cycler)['color'] else: err_color = self.err_dict['err_color'] if self.histtype == 'marker': if self.err_dict['err_x']: xerr = self.widths * 0.5 else: xerr = None _, caps, _ = self.ax.errorbar(self.bin_centers, bin_height[i], linestyle='', marker='', yerr=bin_err[i], xerr=xerr, linewidth=2, color=err_color) else: if self.err_dict['err_style'] == 'line': self.ax.errorbar(self.bin_centers, bin_height[i], linestyle='', marker='', yerr=bin_err[i], linewidth=2, color=err_color) elif self.err_dict['err_style'] == 'band': if self.err_dict['err_type'] == 'poisson': fill_between_steps(self.ax, self.bin_edges, bin_height[i] + bin_err[i][1], bin_height[i] - bin_err[i][0], step_where='pre', linewidth=0, color=err_color, alpha=self.hist_dict['alpha'] * 0.8, zorder=10) else: fill_between_steps(self.ax, self.bin_edges, bin_height[i] + bin_err[i], bin_height[i] - bin_err[i], step_where='pre', linewidth=0, color=err_color, alpha=self.hist_dict['alpha'] * 0.8, zorder=10) if self.stacked: poly_patch = self.vis_object[-1][0].get_xy() self.ax.add_patch( Polygon(poly_patch[:(len(poly_patch) + 1) // 2], closed=False, facecolor='none', edgecolor='k', linewidth=1, alpha=0.5, zorder=0))
def hsl(self): rgba = self.rgba h, l, s = colorsys.rgb_to_hls(*rgba[:3]) return h, s, l
def take_screenshot(camera, category, directory, protoDirectory, protoName, options, background, colorThreshold, shadowColor=None): """Take the screenshot.""" # Convert Camera image to PIL image. image = camera.getImage() pilImage = Image.frombytes('RGBA', (camera.getWidth(), camera.getHeight()), image, 'raw', 'BGRA') pilImage = autocrop( pilImage) # cropped at an early stage to save lot of CPU resources. pixels = pilImage.getdata() # Remove the background. background = [ float(pixels[0][0]) / 255.0, float(pixels[0][1]) / 255.0, float(pixels[0][2]) / 255.0 ] newPixels = [] hls_background_color = colorsys.rgb_to_hls(background[RED], background[GREEN], background[BLUE]) for pixel in pixels: hls_pixel = colorsys.rgb_to_hls( float(pixel[RED]) / 255.0, float(pixel[GREEN]) / 255.0, float(pixel[BLUE]) / 255.0) if (abs(hls_pixel[HUE] - hls_background_color[HUE]) < colorThreshold and abs(hls_pixel[LIGHTNESS] - hls_background_color[LIGHTNESS]) < colorThreshold and abs(hls_pixel[SATURATION] - hls_background_color[SATURATION]) < colorThreshold): # Background newPixels.append((0, 0, 0, 0)) elif (shadowColor is not None and shadowColor[RED] == pixel[RED] and shadowColor[GREEN] == pixel[GREEN] and shadowColor[BLUE] == pixel[BLUE]): # Shadows newPixels.append((125, 125, 125, 120)) else: # Object newPixels.append(pixel) pilImage.putdata(newPixels) # Uncomment to show the result image: # pilImage.show() # Save model.png (cropped) and icon.png (scaled down) pilImage.save(os.path.join(directory, 'model.png')) pilImage.thumbnail((128, 128), Image.ANTIALIAS) iconImage = Image.new('RGBA', (128, 128)) iconImage.paste( pilImage, (int( (128 - pilImage.size[0]) / 2), int( (128 - pilImage.size[1]) / 2), int( (128 - pilImage.size[0]) / 2) + pilImage.size[0], int((128 - pilImage.size[1]) / 2) + pilImage.size[1])) iconImage.save(os.path.join(directory, 'icon.png')) if not options.disableIconCopy: # copy icons in the appropriate directory iconsFolder = os.environ[ 'WEBOTS_HOME'] + os.sep + protoDirectory + os.sep + 'icons' iconPath = iconsFolder + os.sep + protoName + '.png' if not os.path.exists(iconsFolder): os.makedirs(iconsFolder) if os.path.exists(iconPath): os.remove(iconPath) shutil.copy2(directory + os.sep + 'icon.png', iconPath) categoryFolder = os.path.basename(os.path.dirname(protoDirectory)) # copy the models in the docs directory modelFolder = os.path.join(os.environ['WEBOTS_HOME'], 'docs', 'guide', 'images', category, categoryFolder, protoName) modelPath = os.path.join(modelFolder, 'model.png') if category == categoryFolder: modelFolder = os.path.join(os.environ['WEBOTS_HOME'], 'docs', 'guide', 'images', category) modelPath = os.path.join(modelFolder, protoName + '.png') elif category == 'robots': modelFolder = os.path.join(os.environ['WEBOTS_HOME'], 'docs', 'guide', 'images', category, categoryFolder) modelPath = os.path.join(modelFolder, protoName + '.png') if not os.path.exists(modelFolder): os.makedirs(modelFolder) if os.path.exists(modelPath): os.remove(modelPath) shutil.copy2(directory + os.sep + 'model.png', modelPath)
def hsl(self): return colorsys.rgb_to_hls(*map(lambda c: c / 255, self._value))
def color(hex_color: str, scale_l: float = 1.0) -> Tuple[float, float, float]: rgb = matplotlib.colors.ColorConverter.to_rgb(hex_color) h, l, s = colorsys.rgb_to_hls(*rgb) return colorsys.hls_to_rgb(h, min(1, l * scale_l), s=s)
def downgrade(self, system: ColorSystem) -> "Color": """Downgrade a color system to a system with fewer colors.""" if self.type == ColorType.DEFAULT or self.type == system: return self # Convert to 8-bit color from truecolor color if system == ColorSystem.EIGHT_BIT and self.system == ColorSystem.TRUECOLOR: assert self.triplet is not None red, green, blue = self.triplet.normalized _h, l, s = rgb_to_hls(red, green, blue) # If saturation is under 10% assume it is grayscale if s < 0.1: gray = round(l * 25.0) if gray == 0: color_number = 16 elif gray == 25: color_number = 231 else: color_number = 231 + gray return Color(self.name, ColorType.EIGHT_BIT, number=color_number) color_number = (16 + 36 * round(red * 5.0) + 6 * round(green * 5.0) + round(blue * 5.0)) return Color(self.name, ColorType.EIGHT_BIT, number=color_number) # Convert to standard from truecolor or 8-bit elif system == ColorSystem.STANDARD: if self.system == ColorSystem.TRUECOLOR: assert self.triplet is not None triplet = self.triplet else: # self.system == ColorSystem.EIGHT_BIT assert self.number is not None triplet = ColorTriplet(*EIGHT_BIT_PALETTE[self.number]) color_number = STANDARD_PALETTE.match(triplet) return Color(self.name, ColorType.STANDARD, number=color_number) elif system == ColorSystem.WINDOWS: if self.system == ColorSystem.TRUECOLOR: assert self.triplet is not None triplet = self.triplet else: # self.system == ColorSystem.EIGHT_BIT assert self.number is not None if self.number < 8: return Color(self.name, ColorType.WINDOWS, number=self.number) elif self.number < 16: return Color(self.name, ColorType.WINDOWS, number=self.number - 8) triplet = ColorTriplet(*EIGHT_BIT_PALETTE[self.number]) color_number = WINDOWS_PALETTE.match(triplet) return Color(self.name, ColorType.WINDOWS, number=color_number) return self
def __rgb2hls_aPixel(self, r, g, b): # https://docs.python.org/2/library/colorsys.html r, g, b = r / 255.0, g / 255.0, b / 255.0 h, l, s = colorsys.rgb_to_hls(r, g, b) return h, l, s
def hls_mod_add(source, h=0, l=0, s=0): c = colorsys.rgb_to_hls(source[0] / 255, source[1] / 255, source[2] / 255) colour = colorsys.hls_to_rgb(c[0] + h, min(max(c[1] + l, 0), 1), min(max(c[2] + l, 0), 1)) return [int(colour[0] * 255), int(colour[1] * 255), int(colour[2] * 255), source[3]]
def rgb_to_hls(r, g, b): return colorsys.rgb_to_hls(r / 255, g / 255, b / 255)
def scale_lightness(rgb, scale_l): # convert rgb to hls h, l, s = colorsys.rgb_to_hls(*rgb) # manipulate h, l, s values and return as rgb return colorsys.hls_to_rgb(h, min(1, l * scale_l), s=s)
def get_hue(self): hex_color = self['color'].lstrip('#') rgb = tuple(int(hex_color[i:i + 2], 16) for i in (0, 2, 4)) hls = colorsys.rgb_to_hls(rgb[0], rgb[1], rgb[2]) return math.trunc(hls[0] * 360) * 182 # adjust for 0-65535 range.
def with_l(self, newval): newval = Color.clamp(newval) h, l, s = colorsys.rgb_to_hls(self.color[0], self.color[1], self.color[2]) r, g, b = colorsys.hls_to_rgb(h, newval, s) return Color(r, g, b, self.color[3])