# Color calculation routines import giepy as gp def color_distance(widget, color1, color2): # Calculates the distance in u'v' space between two colors # Widget must be some Tkinter widget # color must be in some format that Tkinter understands def get_upvp(color): colortup = widget.winfo_rgb(color) ciexyz = web_cie_to_rgb(colortup, xyz_to_rgb=False) sum = ciexyz[0] + ciexyz[1] + ciexyz[2] try: ciex = ciexyz[0]/sum ciey = ciexyz[1]/sum except ZeroDivisionError: ciex = ciey = 0 cieup, cievp = ciexy_to_upvp(ciex, ciey) return (cieup, cievp) upvp1 = get_upvp(color1) upvp2 = get_upvp(color2) distance = gp.distance(upvp1, upvp2) return distance def web_cie_to_rgb(color_tuple, whitepoint=(0.333, 0.333), xyz_to_rgb=True): # If xyz to rgb is True, converts CIEx,y,z data to RGB values. If false, the other way around. # NTSC Primaries CIE_x_r = 0.670 CIE_y_r = 0.330 CIE_x_g = 0.210 CIE_y_g = 0.710 CIE_x_b = 0.140 CIE_y_b = 0.080 # White point CIE_x_w = whitepoint[0] CIE_y_w = whitepoint[1] CIE_D = CIE_x_r*(CIE_y_g - CIE_y_b) + CIE_x_g*(CIE_y_b - CIE_y_r) + CIE_x_b*(CIE_y_r - CIE_y_g) CIE_C_rD = (1.0/CIE_y_w) * \ (CIE_x_w*(CIE_y_g - CIE_y_b) - CIE_y_w*(CIE_x_g - CIE_x_b) + CIE_x_g*CIE_y_b - CIE_x_b*CIE_y_g) CIE_C_gD = (1./CIE_y_w) * \ (CIE_x_w*(CIE_y_b - CIE_y_r) - CIE_y_w*(CIE_x_b - CIE_x_r) - CIE_x_r*CIE_y_b + CIE_x_b*CIE_y_r) CIE_C_bD = (1./CIE_y_w) * \ (CIE_x_w*(CIE_y_r - CIE_y_g) - CIE_y_w*(CIE_x_r - CIE_x_g) + CIE_x_r*CIE_y_g - CIE_x_g*CIE_y_r) CIE_rf = CIE_y_r * CIE_C_rD / CIE_D CIE_gf = CIE_y_g * CIE_C_gD / CIE_D CIE_bf = CIE_y_b * CIE_C_bD / CIE_D xyz2rgbmat = \ [[(CIE_y_g - CIE_y_b - CIE_x_b*CIE_y_g + CIE_y_b*CIE_x_g)/CIE_C_rD, \ (CIE_x_b - CIE_x_g - CIE_x_b*CIE_y_g + CIE_x_g*CIE_y_b)/CIE_C_rD, \ (CIE_x_g*CIE_y_b - CIE_x_b*CIE_y_g)/CIE_C_rD], \ [(CIE_y_b - CIE_y_r - CIE_y_b*CIE_x_r + CIE_y_r*CIE_x_b)/CIE_C_gD, \ (CIE_x_r - CIE_x_b - CIE_x_r*CIE_y_b + CIE_x_b*CIE_y_r)/CIE_C_gD, \ (CIE_x_b*CIE_y_r - CIE_x_r*CIE_y_b)/CIE_C_gD], \ [(CIE_y_r - CIE_y_g - CIE_y_r*CIE_x_g + CIE_y_g*CIE_x_r)/CIE_C_bD, \ (CIE_x_g - CIE_x_r - CIE_x_g*CIE_y_r + CIE_x_r*CIE_y_g)/CIE_C_bD, \ (CIE_x_r*CIE_y_g - CIE_x_g*CIE_y_r)/CIE_C_bD]] \ rgb2xyzmat = \ [[CIE_x_r*CIE_C_rD/CIE_D, CIE_x_g*CIE_C_gD/CIE_D, CIE_x_b*CIE_C_bD/CIE_D], [CIE_y_r*CIE_C_rD/CIE_D, CIE_y_g*CIE_C_gD/CIE_D, CIE_y_b*CIE_C_bD/CIE_D], [(1.-CIE_x_r-CIE_y_r)*CIE_C_rD/CIE_D, (1.-CIE_x_g-CIE_y_g)*CIE_C_gD/CIE_D, (1.-CIE_x_b-CIE_y_b)*CIE_C_bD/CIE_D]] color = [] if xyz_to_rgb: for i in range(0, 3): color.append(xyz2rgbmat[i][0]*color_tuple[0] + xyz2rgbmat[i][1]*color_tuple[1] + xyz2rgbmat[i][2]*color_tuple[2]) if color[-1] < 0.0: color[-1] = 0.0 else: for i in range(0, 3): color.append(rgb2xyzmat[i][0]*color_tuple[0] + rgb2xyzmat[i][1]*color_tuple[1] + rgb2xyzmat[i][2]*color_tuple[2]) return color def ciexy_to_upvp(x, y): # Converts cie(x,y) to cie(u'v'), returns a two-tuple of CIEu', CIEv'. Note that u'v' are from the CIELUV color space (1976) denom = -2*x + 12*y + 3 try: up = 4*x / denom vp = 9*y / denom except ArithmeticError: up = vp = 0 return up, vp