fa76f20ab3c519836bb0d67618b75db9bba928cf
1 from PIL
import Image
,ImageFilter
3 from functools
import partial
5 """ Convert values between RGB hex codes and xterm-256 color codes.
7 Nice long listing of all 256 colors and their codes. Useful for
8 developing console color themes, or even script output schemes.
11 * http://en.wikipedia.org/wiki/8-bit_color
12 * http://en.wikipedia.org/wiki/ANSI_escape_code
13 * /usr/share/X11/rgb.txt
15 I'm not sure where this script was inspired from. I think I must have
16 written it from scratch, though it's been several years now.
19 __author__
= 'Micah Elliott http://MicahElliott.com'
21 __copyright__
= 'Copyright (C) 2011 Micah Elliott. All rights reserved.'
22 __license__
= 'WTFPL http://sam.zoy.org/wtfpl/'
24 #---------------------------------------------------------------------
28 CLUT
= [ # color look-up table
31 # Primary 3-bit (8 colors). Unique representation!
41 # Equivalent "bright" versions of original 8 colors.
300 def _strip_hash(rgb
):
301 # Strip leading `#` if exists.
302 if rgb
.startswith('#'):
303 rgb
= rgb
.lstrip('#')
307 short2rgb_dict
= dict(CLUT
)
309 for k
, v
in short2rgb_dict
.items():
310 rgb2short_dict
[v
] = k
311 return rgb2short_dict
, short2rgb_dict
313 def short2rgb(short
):
314 return SHORT2RGB_DICT
[short
]
316 def pixel_print(ansicolor
):
317 sys
.stdout
.write('\033[48;5;%sm \033[0m' % (ansicolor
))
319 def hex_to_rgb(value
):
320 value
= value
.lstrip('#')
322 return tuple(int(value
[i
:i
+lv
/3], 16) for i
in range(0, lv
, lv
/3))
325 return '#%02x%02x%02x' % rgb
327 def binary_search(ary
,(r
,g
,b
)):
329 if len(ary
) == 1 : return ary
[0]
331 left
= binary_search(ary
[:mid
],(r
,g
,b
))
332 right
= binary_search(ary
[mid
:],(r
,g
,b
))
333 ld
= (left
[0]-r
)**2 + (left
[1]-g
)**2 + (left
[2]-b
)**2
334 rd
= (right
[0]-r
)**2 + (right
[1]-g
)**2 + (right
[2]-b
)**2
342 """ Find the closest xterm-256 approximation to the given RGB value.
343 @param rgb: Hex code representing an RGB value, eg, 'abcdef'
344 @returns: String between 0 and 255, compatible with xterm.
346 rgb
= _strip_hash(rgb
)
350 dist
= lambda s
,d
: (s
[0]-d
[0])**2+(s
[1]-d
[1])**2+(s
[2]-d
[2])**2
351 ary
= [hex_to_rgb(hex) for hex in RGB2SHORT_DICT
]
352 m
= binary_search(ary
,(r
,g
,b
))
353 m
= min(ary
, key
=partial(dist
, (r
,g
,b
)))
354 return RGB2SHORT_DICT
[_strip_hash(rgb_to_hex(m
))]
357 # incs = (0x00, 0x5f, 0x87, 0xaf, 0xd7, 0xff)
358 # parts = [ int(h, 16) for h in re.split(r'(..)(..)(..)', rgb)[1:4] ]
362 # while i < len(incs)-1:
363 # s, b = incs[i], incs[i+1] # smaller, bigger
367 # if s1 < b1: closest = s
369 # res.append(closest)
373 # res = ''.join([ ('%02.x' % i) for i in res ])
374 # equiv = RGB2SHORT_DICT[ res ]
375 # #print '***', res, equiv
378 RGB2SHORT_DICT
, SHORT2RGB_DICT
= _create_dicts()
380 def image_to_display(path
):
382 i
= i
.convert('RGBA')
385 rows
, columns
= os
.popen('stty size', 'r').read().split()
386 width
= min(w
, int(columns
)-2*6)
387 height
= int(float(h
) * (float(width
) / float(w
)))
389 i
= i
.resize((width
, height
), Image
.BICUBIC
)
391 for y
in xrange(height
):
393 for x
in xrange(width
):
394 p
= i
.getpixel((x
,y
))
396 hex = rgb_to_hex((r
,g
,b
))
397 pixel_print(rgb2short(hex))
400 #---------------------------------------------------------------------
402 if __name__
== '__main__':
404 image_to_display(path
)