Skip to content

Instantly share code, notes, and snippets.

@bcho
Created July 27, 2012 13:18
Show Gist options
  • Select an option

  • Save bcho/3187883 to your computer and use it in GitHub Desktop.

Select an option

Save bcho/3187883 to your computer and use it in GitHub Desktop.
#coding: utf-8
# these code are from [ColorMeta](https://github.com/bcho/colormeta)
from PIL import Image
def rgb2xyz(r, g, b):
# RGB to CIE XYZ REC 709
# http://www.easyrgb.com/index.php?X=MATH&H=02#text2
def _rgb(c):
percentage = c / 255.0
if percentage > 0.04045:
return ((percentage + 0.055) / 1.055) ** 2.4 * 100
else:
return percentage / 12.92 * 100
R = _rgb(r)
G = _rgb(g)
B = _rgb(b)
x = R * 0.4124 + G * 0.3576 + B * 0.1805
y = R * 0.2126 + G * 0.7152 + B * 0.0722
z = R * 0.0193 + G * 0.1192 + B * 0.9505
return (x, y, z)
def xyz2lab(x, y, z):
# CIE XYZ REC 709 to CIE L*ab
# http://www.easyrgb.com/index.php?X=MATH&H=07#text7
ref = (96.4221, 100.000, 82.5221)
def _xyz(c, ref_c):
percentage = c / ref_c
if percentage > 216 / 24389.0:
return percentage ** (1 / 3.0)
else:
return ((24389 / 27.0) * percentage + 16) / 116.0
X = _xyz(x, ref[0])
Y = _xyz(y, ref[1])
Z = _xyz(z, ref[2])
L = (116 * Y) - 16
a = 500 * (X - Y)
b = 200 * (Y - Z)
return (L, a, b)
def rgb2lab(r, g, b):
x, y, z = rgb2xyz(r, g, b)
return xyz2lab(x, y, z)
def deltaE(a, b):
# Delta E CIE76
# http://en.wikipedia.org/wiki/Color_difference#Delta_E
# JND = 2.3
delta_e = 0
for pair in zip(a, b):
delta_e += (pair[0] - pair[1]) ** 2
return delta_e ** 0.5
def _open_image(filename):
return Image.open(filename)
def _save_image(image, filename):
image.save(filename)
return
def _color_quantization(image, color_count):
try:
return image.convert('P', palette=Image.ADAPTIVE,
colors=color_count)
except:
image = image.convert('RGB')
return image.convert('P', palette=Image.ADAPTIVE,
colors=color_count)
def _to_hex(num):
return "#%02x%02x%02x" % num
def _get_palette(image, color):
l = image.getpalette()[0:color * 3]
return [tuple(l[i:i + 3]) for i in range(0, len(l), 3)]
def _get_hex_palette(image, color):
return [_to_hex(i) for i in _get_palette(image, color)]
def _get_colors(image, color_count, diff, count):
def __compare(sample, control_group):
def is_notice(a, b):
lab_a = rgb2lab(a[0], a[1], a[2])
lab_b = rgb2lab(b[0], b[1], b[2])
return deltaE(lab_a, lab_b) < diff
for color in control_group:
if is_notice(sample, color):
return False
return True
def __pop(l):
while l:
yield [l.pop(0) for i in xrange(3)]
payload = image.getpalette()[0:count * 3]
ret = []
for i in __pop(payload):
if not __compare(i, ret):
continue
else:
ret.append(tuple(i))
if len(ret) == color_count:
break
return ret
image = _open_image('colorful.png')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment