#!/usr/bin/python import math def huemod (hue): if hue is None: return None while hue < 0: hue = hue + 6 while hue >= 6: hue = hue - 6 return hue def hueadd (h1, h2): if h1 is None or h2 is None: return None return huemod(h1+h2) def rgb2xyz(rgb): (r,g,b) = rgb x = 0.412453 * r + 0.357580 * g + 0.180423 * b y = 0.212671 * r + 0.715160 * g + 0.072169 * b z = 0.019334 * r + 0.119193 * g + 0.950227 * b return (x,y,z) def xyz2rgb(xyz): (x,y,z) = xyz r = 3.240479 * x - 1.537150 * y - 0.498535 * z g = -0.969256 * x + 1.875992 * y + 0.041556 * z b = 0.055648 * x - 0.204043 * y + 1.057311 * z return (r,g,b) def xyz2yuv(xyz): (X,Y,Z) = xyz d = X+15*Y+3*Z if (d<=0.0): d=1.0 return (Y, 4*X/d, 9*Y/d) def yuv2xyz(yuv): (Y,u,v) = yuv if (v > 0): d = 9*Y/v else: d = 0 X = 0.25*d*u Z = (d-X-15*Y)/3 return (X,Y,Z) white = xyz2yuv(rgb2xyz((1,1,1))) def xyz2luv(xyz): (Y,u,v) = xyz2yuv(xyz) if (Y > 0.008856): l_ = 116*math.pow((Y/white[0]),(1/3.))-16 else: l_ = 903.29*Y u_ = 13*l_*(u-white[1]) v_ = 13*l_*(v-white[2]) return (l_,u_,v_) def luv2lhc(luv): (l,u,v) = luv if (l > 0): h = huemod(math.atan2(v,u)/math.pi*3) c = math.sqrt(u*u+v*v)/l else: h = 0.0 c = 0.0 return (l,h,c) def lhc2luv(lhc): (l,h,c) = lhc u = math.cos((h)/3*math.pi)*c*l v = math.sin((h)/3*math.pi)*c*l return (l,u,v) def luv2xyz(luv): (l_,u_,v_) = luv if (l_>8): Y = (math.pow((l_+16)/116.0,3.0))*white[0] else: Y = l_/903.29; if l_ < 1: l_ = 1 u = u_/(13*l_)+white[1] v = v_/(13*l_)+white[2] return yuv2xyz((Y,u,v)) def rotatehue(lhc,rot): return lhc[0],huemod(lhc[1]+rot),lhc[2] def rgb2lhc(rgb): return luv2lhc(xyz2luv(rgb2xyz(rgb))) def lhc2rgb(lhc): return xyz2rgb(luv2xyz(lhc2luv(lhc))) def rotate(rgb,rot): return lhc2rgb(rotatehue(rgb2lhc(rgb),rot)) def dim(rgb,factor): lhc = rgb2lhc(rgb) return lhc2rgb(((lhc[0]*factor),lhc[1],lhc[2])) def saturate(rgb,factor): lhc = rgb2lhc(rgb) return lhc2rgb((lhc[0],lhc[1],(lhc[2]*factor))) def rgb2luv(rgb): return xyz2luv(rgb2xyz(rgb)) def luv2rgb(luv): return xyz2rgb(luv2xyz(luv)) def outofgamut(rgb): r,g,b = rgb if r < -0.5/255 or r > 1+0.5/255: return 1 if g < -0.5/255 or g > 1+0.5/255: return 1 if b < -0.5/255 or b > 1+0.5/255: return 1 return None def s255(x): x = int(x*255+0.5) if x < 0: x = 0 if x > 255: x = 255 return x def rgb2hex (rgb): r,g,b = rgb r = s255(r) g = s255(g) b = s255(b) return "%02x%02x%02x" % (r,g,b) def index2lhc (index): if indexlhc.has_key(index): return indexlhc[index] lhc = rgb2lhc(index) indexlhc[index] = lhc return lhc def huediff (h1, h2): d1 = abs(h1-h2) d2 = abs(h1-h2+6) d3 = abs(h1-h2-6) return min(d1,d2,d3) def rgbblend(rgb1,rgb2,pct): rgb = (rgb1[0] * (1-pct) + rgb2[0] * pct, rgb1[1] * (1-pct) + rgb2[1] * pct, rgb1[2] * (1-pct) + rgb2[2] * pct) return rgb huedata = [('red', (1.0,0.0,0.0)), ('orange', (1.0,0.5,0.0)), ('yellow', (1.0,1.0,0.0)), ('spring', (0.5,1.0,0.0)), ('green', (0.0,1.0,0.0)), ('teal', (0.0,1.0,0.5)), ('cyan', (0.0,1.0,1.0)), ('azure', (0.0,0.5,1.0)), ('blue', (0.0,0.0,1.0)), ('violet', (0.5,0.0,1.0)), ('magenta',(1.0,0.0,1.0)), ('pink', (1.0,0.0,0.5))] hues = [] for h in huedata: hue = rgb2lhc(h[1])[1] hues.append((h[0],hue)) def colorname (lhc): (val,hue,sat) = lhc return huename(hue) def huename (hue): if hue is None: return "gray" best1, best2 = None, None for h in hues: hd = huediff(hue, h[1]) if best1 is None or best1[0] > hd: best2 = best1 best1 = (hd,h[0]) if (best2 is None or best2[0] > hd) and best1[0] < hd: best2 = (hd,h[0]) if best2[0] < 2*best1[0]: return best1[1] + '-' + best2[1] return best1[1] def hex2rgb(s): try: if s[0:0] == '#': s = s[1:] rgb = map(lambda s: string.atoi(s,16), (s[0:2], s[2:4], s[4:6])) return (rgb[0]/255.0, rgb[1]/255.0, rgb[2]/255.0) except: for h in huedata: if h[0] == s: return h[1] return None