def recolorHue(hex, kind): lch = convert_color(sRGBColor(0,0,0).new_from_rgb_hex(hex), LCHabColor) bestDist = 200 bestPair = [] # print(lch.lch_l, lch.lch_c) for pair in LCs.get(kind): l = pair[0] c = pair[1] dist = abs(lch.lch_l - l) + (abs(lch.lch_c - c) / 3) # print(dist, pair) if dist < bestDist: bestDist = dist bestPair = pair if bestPair: nc = convert_color(LCHabColor(bestPair[0], bestPair[1], lch.lch_h), sRGBColor) # print(nc.clamped_rgb_r, nc.clamped_rgb_g, nc.clamped_rgb_b) if bestPair[1] == 100 and bestPair[0] > 0: re = convert_color(nc, LCHabColor) reC = 100 - re.lch_c reL = bestPair[0] while reC > 25 and reL < 100 and reL < bestPair[0] + 20: reL += 5 re = convert_color(nc, LCHabColor) reC = 100 - re.lch_c print(bestPair[1], 'vs', int(re.lch_c), ': intensified') nc = convert_color(LCHabColor(reL, 100, lch.lch_h), sRGBColor) return sRGBColor(nc.clamped_rgb_r, nc.clamped_rgb_g, nc.clamped_rgb_b).get_rgb_hex(), int(bestPair[0]), int(bestPair[1]), int(lch.lch_h)
def lch_to_rgb(l, c, h): lchab = LCHabColor(*(l, c, h)) srgb = convert_color(lchab, sRGBColor) r = srgb.clamped_rgb_r g = srgb.clamped_rgb_g b = srgb.clamped_rgb_b return r, g, b
def colorAdjust(layout, ctype=0, origin='rgb(0,0,0)'): result = [] for item in layout: (word, count), font_size, (x, y), (width, height), orientation, color = item [r, g, b] = origin.replace('rgb(', '').replace(')', '').split(',') rgbObj = AdobeRGBColor(r, g, b) l, c, h = convert_color(rgbObj, LCHabColor).get_value_tuple() if ctype == 0: # base l = random.randint(4300, 4700) c = random.randint(2300, 2500) h = random.randint(0, 2500) if ctype == 1: # inner l = random.randint(3000, 3500) c += random.randint(-30, 0) h += random.randint(-60, 60) if ctype == 2: # outer l = random.randint(3000, 5000) c += random.randint(-10, 30) h += random.randint(-30, 30) nr, ng, nb = convert_color(LCHabColor(l, c, h), AdobeRGBColor).get_value_tuple() color = f'rgb({int(nr)},{int(ng)},{int(nb)})' result.append(((word, count), font_size, (x, y), (width, height), orientation, color)) return result
def lch_to_rgb(self, p): """Convert the color values from Lch to RGB.""" rgbs = [] for lightness, hue in zip(p.lightness_by_hue, p.stick_hues): lch = LCHabColor(lightness, p.chroma, hue) rgb = convert_color(lch, sRGBColor).get_value_tuple() rgbs.append(rgb) return np.array(rgbs)
def lch_palette(n, l=0.7, h=0, s=0.7): lch_colors = [ LCHabColor(l * 100, s * 100, ((h * 360) + hue) % 360) for hue in np.linspace(0, 360, n + 1)[:-1] ] srgb_colors = [convert_color(lch, sRGBColor) for lch in lch_colors] return [(srgb.clamped_rgb_r, srgb.clamped_rgb_g, srgb.clamped_rgb_b) for srgb in srgb_colors]
def example_lchab_to_lchuv(): """ This function shows very complex chain of conversions in action. While this requires no additional effort from the user, debugging mode will show you all of the work that goes on behind the scenes. LCHab to LCHuv involves four different calculations, making this the conversion requiring the most steps. """ print "=== Complex Example: LCHab->LCHuv ===" # Instantiate an LCHab color object with the given values. lchab = LCHabColor(0.903, 16.447, 352.252) # Show a string representation. print lchab # Convert to LCHuv. lchuv = lchab.convert_to('lchuv', debug=False) print lchuv print "=== End Example ===\n"
def test_conversion_to_rgb_zero_div(self): """ The formula I grabbed for LCHuv to XYZ had a zero division error in it if the L coord was 0. Also check against LCHab in case. """ lchab = LCHabColor(0.0, 0.0, 0.0) rgb = convert_color(lchab, sRGBColor) self.assertColorMatch(rgb, sRGBColor(0.0, 0.0, 0.0))
def test_to_rgb_domain_error(self): """ Tests for a bug resulting in a domain error with LCH->Adobe RGB. See: https://github.com/gtaylor/python-colormath/issues/49 """ lchab = LCHabColor(40.0, 104.0, 40.0) rgb = convert_color(lchab, AdobeRGBColor)
def create_img(variable, value, width, height, output): img = Image.new('RGB', (width, height), "black") # create a new black image pixels = img.load() # create the pixel map for i in range(img.size[0]): # for every col: for j in range(img.size[1]): # for every row: if variable == 76 or variable == 108: t_color = convert_color( LCHabColor(value, -(j * height / 125) + height, i * 360 / width), sRGBColor) elif variable == 67 or variable == 99: t_color = convert_color( LCHabColor(-(j * height / 100) + height, value, i * 360 / width), sRGBColor) elif variable == 72 or variable == 104: t_color = convert_color( LCHabColor(-(j * height / 100) + height, i * width / 125, value), sRGBColor) else: print( "Invalid variable, please input one of: L, l, C, c, H, h") quit(0) if t_color.clamped_rgb_r != t_color.rgb_r \ or t_color.clamped_rgb_g != t_color.rgb_g \ or t_color.clamped_rgb_b != t_color.rgb_b: r = t_color.clamped_rgb_r * 255 if (i + j) % 3 != 0 else 255 g = t_color.clamped_rgb_g * 255 if (i + j) % 3 != 0 else 255 b = t_color.clamped_rgb_b * 255 if (i + j) % 3 != 0 else 255 else: r = t_color.clamped_rgb_r * 255 g = t_color.clamped_rgb_g * 255 b = t_color.clamped_rgb_b * 255 pixels[i, j] = (int(r), int(g), int(b)) img.save(output + ".png")
def alter_lch(hex_color, value, component='L', relative=True): rgb_color = RGBColor() rgb_color.set_from_rgb_hex(hex_color) lch_color = rgb_color.convert_to('lchab') lch_lst = list(lch_color.get_value_tuple()) comp_idx = ('L', 'C', 'H').index(component) lch_lst[comp_idx] = lch_lst[comp_idx] + value if relative else value L, C, H = lch_lst lch_res = LCHabColor(L, C, H) return lch_to_hex(lch_res)
def create_img(radius, lum, output): img = Image.new('RGBA', (radius*2, radius*2), "black") # create a new black image pixels = img.load() # create the pixel map for i in range(img.size[0]): # for every col: for j in range(img.size[1]): # For every row: i_0 = i-radius # set x origin j_0 = j-radius # set y origin r = pow(i_0*i_0 + j_0*j_0, 0.5) # distance from origin if r <= radius: # within defined radius if i_0 > 0: # draws left hemisphere t_color = convert_color( LCHabColor(lum, r/radius*125, math.atan(j_0 / i_0) * 180 / math.pi), sRGBColor) elif i_0 < 0: # draws right hemisphere t_color = convert_color( LCHabColor(lum, r/radius*125, math.atan(j_0 / i_0) * 180 / math.pi + 180), sRGBColor) else: # Handles x/0 t_color = convert_color( LCHabColor(lum, r/radius*125, 90 if j_0 >= 0 else 270), sRGBColor) if t_color.clamped_rgb_r != t_color.rgb_r \ or t_color.clamped_rgb_g != t_color.rgb_g \ or t_color.clamped_rgb_b != t_color.rgb_b: r = t_color.clamped_rgb_r * 255 if (i+j) % 3 != 0 else 255 g = t_color.clamped_rgb_g * 255 if (i+j) % 3 != 0 else 255 b = t_color.clamped_rgb_b * 255 if (i+j) % 3 != 0 else 255 else: r = t_color.clamped_rgb_r * 255 g = t_color.clamped_rgb_g * 255 b = t_color.clamped_rgb_b * 255 pixels[i, j] = (int(r), int(g), int(b), 255) else: # Outside of radius make image transparent pixels[i, j] = (0,0,0,0) img.save(output + ".png")
def colormap_lch(n, lum=(35, 65), chroma=75, start=0, end=300): if isinstance(lum, list) or isinstance(lum, tuple): lum = cycle(lum) else: lum = cycle([lum]) rgbs = [] for hue, lumn in zip(np.linspace(start, end, n), lum): rgb = convert_color(LCHabColor(lumn, chroma, hue), sRGBColor).get_value_tuple() rgbs.append('#{:02x}{:02x}{:02x}'.format(*map(int, np.array(rgb).clip(0, 1) * 255.0))) return rgbs
def color_from_hash(key): key = str(key) l = (mmh3.hash(key + key[::-1]) + 2147483648) / 4294967296 c = (mmh3.hash(key[::-1] + key) + 2147483648) / 4294967296 h = (mmh3.hash(key) + 2147483648) / 4294967296 l = (l * 0.6 + 0.3) * 100 c = (c * 0.75 + 0.25) * 100 h = h * 360 lch = LCHabColor(l, c, h) rgb: sRGBColor = convert_color(lch, sRGBColor) return rgb.clamped_rgb_r, rgb.clamped_rgb_g, rgb.clamped_rgb_b
def recolorToPalette(hex, kind): lch = convert_color(sRGBColor(0,0,0).new_from_rgb_hex(hex), LCHabColor) bestDist = 1000 bestColor = LCHabColor(0,0,0) for col in LCHs.get(kind): dist = abs(lch.lch_l - col.lch_l) + abs(lch.lch_c - col.lch_c) + abs(lch.lch_h - col.lch_h) if dist < bestDist: bestDist = dist bestColor = col if bestColor: nc = convert_color(bestColor, sRGBColor) return sRGBColor(nc.clamped_rgb_r, nc.clamped_rgb_g, nc.clamped_rgb_b).get_rgb_hex(), bestColor.lch_l, bestColor.lch_c, bestColor.lch_h
def lch_to_rgb(self, p): """Convert the color values from Lch to RGB.""" rgbs = [] for lightness, hue in zip(p.lightnesses, p.hues): lch = LCHabColor(lightness, p.chroma, hue) rgb = convert_color(lch, sRGBColor).get_value_tuple() rgbs.append(rgb) rgbs = np.array(rgbs) rgbs = rgbs * 2 - 1 rgbs = [tuple(x) for x in rgbs] return np.array(rgbs)
def Lab_to_LCHab(cobj, *args, **kwargs): """ Convert from CIE Lab to LCH(ab). """ lch_l = cobj.lab_l lch_c = math.sqrt( math.pow(float(cobj.lab_a), 2) + math.pow(float(cobj.lab_b), 2)) lch_h = math.atan2(float(cobj.lab_b), float(cobj.lab_a)) if lch_h > 0: lch_h = (lch_h / math.pi) * 180 else: lch_h = 360 - (math.fabs(lch_h) / math.pi) * 180 return LCHabColor( lch_l, lch_c, lch_h, observer=cobj.observer, illuminant=cobj.illuminant)
class Color: def __init__(self, lch_tuple): self.m_lch = LCHabColor(*lch_tuple) def lch(self): return "Lch({:.0f},{:.0f},{:.0f})".format(*(self.m_lch.get_value_tuple())) def rgb(self): rgb = convert_color(self.m_lch, sRGBColor) if (rgb.rgb_r != rgb.clamped_rgb_r or rgb.rgb_g != rgb.clamped_rgb_g or rgb.rgb_b != rgb.clamped_rgb_b): raise Exception("Colour {} is outside sRGB".format(self.lch())) return rgb.get_rgb_hex() def rgb_error(self): return delta_e_cie2000(convert_color(self.m_lch, LabColor), convert_color(sRGBColor.new_from_rgb_hex(self.rgb()), LabColor))
def example_lchab_to_lchuv(): """ This function shows very complex chain of conversions in action. LCHab to LCHuv involves four different calculations, making this the conversion requiring the most steps. """ print("=== Complex Example: LCHab->LCHuv ===") # Instantiate an LCHab color object with the given values. lchab = LCHabColor(0.903, 16.447, 352.252) # Show a string representation. print(lchab) # Convert to LCHuv. lchuv = convert_color(lchab, LCHuvColor) print(lchuv) print("=== End Example ===\n")
class Color: """A color in the CIE lch color space.""" def __init__(self, lch_tuple): self.m_lch = LCHabColor(*lch_tuple) def lch(self): return "Lch({:.0f},{:.0f},{:.0f})".format(*(self.m_lch.get_value_tuple())) def rgb(self): rgb = convert_color(self.m_lch, sRGBColor) if (rgb.rgb_r != rgb.clamped_rgb_r or rgb.rgb_g != rgb.clamped_rgb_g or rgb.rgb_b != rgb.clamped_rgb_b): raise Exception("Colour {} is outside sRGB".format(self.lch())) return rgb.get_rgb_hex() def rgb_error(self): return delta_e_cie2000(convert_color(self.m_lch, LabColor), convert_color(sRGBColor.new_from_rgb_hex(self.rgb()), LabColor))
def get_lch_rgb(n=5, l_min=70, c_min=30, h_min=0, l_max=None, c_max=None, h_max=None, clamped_tuples=False): if not c_max: c_max = c_min if not h_max: h_max = h_min + 360 - (360 / n) if not l_max: l_max = l_min L = np.linspace(l_min, l_max, n) c = np.linspace(c_min, c_max, n) h = np.linspace(h_min, h_max, n) Lch = np.vstack((L, c, h)).T Lch_colors = [ LCHabColor(Lch[i, 0], Lch[i, 1], Lch[i, 2]) for i in range(Lch.shape[0]) ] rgb_colors = [ convert_color(Lch_color, AdobeRGBColor, target_illuminant="D50") for Lch_color in Lch_colors ] if clamped_tuples: clamped_rgb_tuples = [(color.clamped_rgb_r, color.clamped_rgb_g, color.clamped_rgb_b) for color in rgb_colors] return clamped_rgb_tuples return rgb_colors
def lchab(l, c, h): return convert_color(LCHabColor(l, c, h), sRGBColor, target_illuminant="d65")
def c_conv(i): l = l_lo + i * step rgb = convert_color(LCHabColor(l, c, h), sRGBColor) return (rgb.clamped_rgb_r, rgb.clamped_rgb_g, rgb.clamped_rgb_b)
def __init__(self, lch_tuple): self.m_lch = LCHabColor(*lch_tuple)
def tohex(l,c,h): rgb = convert_color(LCHabColor(l,c,h),sRGBColor) clamp = sRGBColor(rgb.clamped_rgb_r, rgb.clamped_rgb_g, rgb.clamped_rgb_b) return clamp.get_rgb_hex()
def lch_to_rgb(lightness, chroma, hue): "Convert Lightness/Chroma/Hue color representation to RGB" psych = LCHabColor(lightness, chroma, hue * 360) rgb = convert_color(psych, sRGBColor) return rgb.clamped_rgb_r, rgb.clamped_rgb_g, rgb.clamped_rgb_b
def test_conversion_to_lchab(self): lch = convert_color(self.color, LCHabColor) self.assertColorMatch(lch, LCHabColor(1.807, 4.532, 214.191))
def generatePalette(lightness, chroma, minHueDist, t): edges = [] continuities = [] colors = [] countSinceEdge = 0 prevPossible = True for hue in range(361): c = LCHabColor(lightness, chroma, hue) rgb = convert_color(c, sRGBColor) cc = convert_color(sRGBColor(rgb.clamped_rgb_r, rgb.clamped_rgb_g, rgb.clamped_rgb_b), LCHabColor) if not outOfGamut(rgb) and LCHtolerance(c, cc, t): # print(hue) if prevPossible == False: edges.append([c, 1]) countSinceEdge = 0 prevPossible = c else: if prevPossible != False and hue != 0: edges.append([prevPossible, 0]) countSinceEdge = 0 prevPossible = False countSinceEdge += 1 for i in range(len(edges)): e = edges[i] nextI = i + 1 if nextI == len(edges): nextI = 0 prevI = i - 1 if prevI == -1: prevI = len(edges) - 1 nextE = edges[nextI] prevE = edges[prevI] print(int(e[0].lch_h), e[1]) if e[1] == 1 and nextE[1] == 0: continuities.append([int(e[0].lch_h), int(nextE[0].lch_h)]) elif i == 0 and e[1] == 0 and prevE[1] == 0: # if the continuity happens to begin right at hue 0 continuities.append([0, int(e[0].lch_h)]) elif i == len(edges) - 1 and e[1] == 1 and nextE[1] == 1: # if the continuity happens to end right at hue 360 continuities.append([int(e[0].lch_h), 360]) if len(edges) == 0: continuities = [[0, 360]] for cont in continuities: a = cont[0] b = cont[1] length = b - a if b < a: bb = 360 + b length = bb - a capacity = 1 + floor(length / minHueDist) # print(a, b, length, capacity) if capacity == 1: hue = ((length / 2) + a) % 360 colors.append(LCHabColor(lightness, chroma, hue)) else: colors.append(LCHabColor(lightness, chroma, a)) if capacity > 2: maximum = b if b < a: maximum = a + b for hue in range(a + minHueDist, maximum, minHueDist): hue = hue % 360 colors.append(LCHabColor(lightness, chroma, hue)) colors.append(LCHabColor(lightness, chroma, b)) # hexes = [] for c in colors: hex = convert_color(c, sRGBColor).get_rgb_hex() print(int(c.lch_h), hex) # hexes.append(hex) return colors
def setUp(self): self.color = LCHabColor(1.807, 4.532, 214.191)
from colormath.color_objects import sRGBColor, LCHabColor from colormath.color_conversions import convert_color greys = [ (0, l, 0) for l in range(0, 100 + 5, 5) ] # Greys are hue 0, not hue 360. Also include 100% lightness which is not part of print atlas pastels = [(h, l, 5) for h in range(30, 360 + 30, 30) for l in range(5, 100, 5)] colours = [(h, l, c) for h in range(10, 360 + 10, 10) for l in [15, 25, 35, 45, 55, 65, 75, 85, 90] for c in range(10, 100, 10)] def InGamut(c): return not (c.rgb_r <= 0 or c.rgb_r >= 1 or c.rgb_g <= 0 or c.rgb_g >= 1 or c.rgb_b <= 0 or c.rgb_b >= 1) print( '''# This file has the RGB values for HLC colours from the freecolour.org system. # As an expression of the CIELa*b* and colour coversions, it's a mathematical model, free of copyright. # Colours are calculated by generate-colours.py global: freecolour:''') for colour in greys + pastels + colours: srgb = convert_color(LCHabColor(colour[1], colour[2], colour[0]), sRGBColor) if InGamut(srgb): print(" H%03d_L%02d_C%03d: '%s'" % (colour[0], colour[1], colour[2], srgb.get_rgb_hex()))
def lch_to_rgb(self, L, C, h): """Convert the color values from Lch to (-1, 1) RGB.""" lch = LCHabColor(L, C, h) rgb = convert_color(lch, sRGBColor).get_value_tuple() psychopy_rgb = np.array(rgb) * 2 - 1 return psychopy_rgb