|
|
@@ -0,0 +1,381 @@ |
|
|
#! /usr/bin/env python |
|
|
|
|
|
""" Convert values between RGB hex codes and xterm-256 color codes. |
|
|
|
|
|
Nice long listing of all 256 colors and their codes. Useful for |
|
|
developing console color themes, or even script output schemes. |
|
|
|
|
|
Resources: |
|
|
* http://en.wikipedia.org/wiki/8-bit_color |
|
|
* http://en.wikipedia.org/wiki/ANSI_escape_code |
|
|
* /usr/share/X11/rgb.txt |
|
|
|
|
|
I'm not sure where this script was inspired from. I think I must have |
|
|
written it from scratch, though it's been several years now. |
|
|
""" |
|
|
|
|
|
__author__ = 'Micah Elliott http://MicahElliott.com' |
|
|
__version__ = '0.1' |
|
|
__copyright__ = 'Copyright (C) 2011 Micah Elliott. All rights reserved.' |
|
|
__license__ = 'WTFPL http://sam.zoy.org/wtfpl/' |
|
|
|
|
|
#--------------------------------------------------------------------- |
|
|
|
|
|
import sys |
|
|
|
|
|
CLUT = [ # color look-up table |
|
|
# 8-bit, RGB hex |
|
|
|
|
|
# Primary 3-bit (8 colors). Unique representation! |
|
|
('00', '000000'), |
|
|
('01', '800000'), |
|
|
('02', '008000'), |
|
|
('03', '808000'), |
|
|
('04', '000080'), |
|
|
('05', '800080'), |
|
|
('06', '008080'), |
|
|
('07', 'c0c0c0'), |
|
|
|
|
|
# Equivalent "bright" versions of original 8 colors. |
|
|
('08', '808080'), |
|
|
('09', 'ff0000'), |
|
|
('10', '00ff00'), |
|
|
('11', 'ffff00'), |
|
|
('12', '0000ff'), |
|
|
('13', 'ff00ff'), |
|
|
('14', '00ffff'), |
|
|
('15', 'ffffff'), |
|
|
|
|
|
# Strictly ascending. |
|
|
('16', '000000'), |
|
|
('17', '00005f'), |
|
|
('18', '000087'), |
|
|
('19', '0000af'), |
|
|
('20', '0000d7'), |
|
|
('21', '0000ff'), |
|
|
('22', '005f00'), |
|
|
('23', '005f5f'), |
|
|
('24', '005f87'), |
|
|
('25', '005faf'), |
|
|
('26', '005fd7'), |
|
|
('27', '005fff'), |
|
|
('28', '008700'), |
|
|
('29', '00875f'), |
|
|
('30', '008787'), |
|
|
('31', '0087af'), |
|
|
('32', '0087d7'), |
|
|
('33', '0087ff'), |
|
|
('34', '00af00'), |
|
|
('35', '00af5f'), |
|
|
('36', '00af87'), |
|
|
('37', '00afaf'), |
|
|
('38', '00afd7'), |
|
|
('39', '00afff'), |
|
|
('40', '00d700'), |
|
|
('41', '00d75f'), |
|
|
('42', '00d787'), |
|
|
('43', '00d7af'), |
|
|
('44', '00d7d7'), |
|
|
('45', '00d7ff'), |
|
|
('46', '00ff00'), |
|
|
('47', '00ff5f'), |
|
|
('48', '00ff87'), |
|
|
('49', '00ffaf'), |
|
|
('50', '00ffd7'), |
|
|
('51', '00ffff'), |
|
|
('52', '5f0000'), |
|
|
('53', '5f005f'), |
|
|
('54', '5f0087'), |
|
|
('55', '5f00af'), |
|
|
('56', '5f00d7'), |
|
|
('57', '5f00ff'), |
|
|
('58', '5f5f00'), |
|
|
('59', '5f5f5f'), |
|
|
('60', '5f5f87'), |
|
|
('61', '5f5faf'), |
|
|
('62', '5f5fd7'), |
|
|
('63', '5f5fff'), |
|
|
('64', '5f8700'), |
|
|
('65', '5f875f'), |
|
|
('66', '5f8787'), |
|
|
('67', '5f87af'), |
|
|
('68', '5f87d7'), |
|
|
('69', '5f87ff'), |
|
|
('70', '5faf00'), |
|
|
('71', '5faf5f'), |
|
|
('72', '5faf87'), |
|
|
('73', '5fafaf'), |
|
|
('74', '5fafd7'), |
|
|
('75', '5fafff'), |
|
|
('76', '5fd700'), |
|
|
('77', '5fd75f'), |
|
|
('78', '5fd787'), |
|
|
('79', '5fd7af'), |
|
|
('80', '5fd7d7'), |
|
|
('81', '5fd7ff'), |
|
|
('82', '5fff00'), |
|
|
('83', '5fff5f'), |
|
|
('84', '5fff87'), |
|
|
('85', '5fffaf'), |
|
|
('86', '5fffd7'), |
|
|
('87', '5fffff'), |
|
|
('88', '870000'), |
|
|
('89', '87005f'), |
|
|
('90', '870087'), |
|
|
('91', '8700af'), |
|
|
('92', '8700d7'), |
|
|
('93', '8700ff'), |
|
|
('94', '875f00'), |
|
|
('95', '875f5f'), |
|
|
('96', '875f87'), |
|
|
('97', '875faf'), |
|
|
('98', '875fd7'), |
|
|
('99', '875fff'), |
|
|
('100', '878700'), |
|
|
('101', '87875f'), |
|
|
('102', '878787'), |
|
|
('103', '8787af'), |
|
|
('104', '8787d7'), |
|
|
('105', '8787ff'), |
|
|
('106', '87af00'), |
|
|
('107', '87af5f'), |
|
|
('108', '87af87'), |
|
|
('109', '87afaf'), |
|
|
('110', '87afd7'), |
|
|
('111', '87afff'), |
|
|
('112', '87d700'), |
|
|
('113', '87d75f'), |
|
|
('114', '87d787'), |
|
|
('115', '87d7af'), |
|
|
('116', '87d7d7'), |
|
|
('117', '87d7ff'), |
|
|
('118', '87ff00'), |
|
|
('119', '87ff5f'), |
|
|
('120', '87ff87'), |
|
|
('121', '87ffaf'), |
|
|
('122', '87ffd7'), |
|
|
('123', '87ffff'), |
|
|
('124', 'af0000'), |
|
|
('125', 'af005f'), |
|
|
('126', 'af0087'), |
|
|
('127', 'af00af'), |
|
|
('128', 'af00d7'), |
|
|
('129', 'af00ff'), |
|
|
('130', 'af5f00'), |
|
|
('131', 'af5f5f'), |
|
|
('132', 'af5f87'), |
|
|
('133', 'af5faf'), |
|
|
('134', 'af5fd7'), |
|
|
('135', 'af5fff'), |
|
|
('136', 'af8700'), |
|
|
('137', 'af875f'), |
|
|
('138', 'af8787'), |
|
|
('139', 'af87af'), |
|
|
('140', 'af87d7'), |
|
|
('141', 'af87ff'), |
|
|
('142', 'afaf00'), |
|
|
('143', 'afaf5f'), |
|
|
('144', 'afaf87'), |
|
|
('145', 'afafaf'), |
|
|
('146', 'afafd7'), |
|
|
('147', 'afafff'), |
|
|
('148', 'afd700'), |
|
|
('149', 'afd75f'), |
|
|
('150', 'afd787'), |
|
|
('151', 'afd7af'), |
|
|
('152', 'afd7d7'), |
|
|
('153', 'afd7ff'), |
|
|
('154', 'afff00'), |
|
|
('155', 'afff5f'), |
|
|
('156', 'afff87'), |
|
|
('157', 'afffaf'), |
|
|
('158', 'afffd7'), |
|
|
('159', 'afffff'), |
|
|
('160', 'd70000'), |
|
|
('161', 'd7005f'), |
|
|
('162', 'd70087'), |
|
|
('163', 'd700af'), |
|
|
('164', 'd700d7'), |
|
|
('165', 'd700ff'), |
|
|
('166', 'd75f00'), |
|
|
('167', 'd75f5f'), |
|
|
('168', 'd75f87'), |
|
|
('169', 'd75faf'), |
|
|
('170', 'd75fd7'), |
|
|
('171', 'd75fff'), |
|
|
('172', 'd78700'), |
|
|
('173', 'd7875f'), |
|
|
('174', 'd78787'), |
|
|
('175', 'd787af'), |
|
|
('176', 'd787d7'), |
|
|
('177', 'd787ff'), |
|
|
('178', 'd7af00'), |
|
|
('179', 'd7af5f'), |
|
|
('180', 'd7af87'), |
|
|
('181', 'd7afaf'), |
|
|
('182', 'd7afd7'), |
|
|
('183', 'd7afff'), |
|
|
('184', 'd7d700'), |
|
|
('185', 'd7d75f'), |
|
|
('186', 'd7d787'), |
|
|
('187', 'd7d7af'), |
|
|
('188', 'd7d7d7'), |
|
|
('189', 'd7d7ff'), |
|
|
('190', 'd7ff00'), |
|
|
('191', 'd7ff5f'), |
|
|
('192', 'd7ff87'), |
|
|
('193', 'd7ffaf'), |
|
|
('194', 'd7ffd7'), |
|
|
('195', 'd7ffff'), |
|
|
('196', 'ff0000'), |
|
|
('197', 'ff005f'), |
|
|
('198', 'ff0087'), |
|
|
('199', 'ff00af'), |
|
|
('200', 'ff00d7'), |
|
|
('201', 'ff00ff'), |
|
|
('202', 'ff5f00'), |
|
|
('203', 'ff5f5f'), |
|
|
('204', 'ff5f87'), |
|
|
('205', 'ff5faf'), |
|
|
('206', 'ff5fd7'), |
|
|
('207', 'ff5fff'), |
|
|
('208', 'ff8700'), |
|
|
('209', 'ff875f'), |
|
|
('210', 'ff8787'), |
|
|
('211', 'ff87af'), |
|
|
('212', 'ff87d7'), |
|
|
('213', 'ff87ff'), |
|
|
('214', 'ffaf00'), |
|
|
('215', 'ffaf5f'), |
|
|
('216', 'ffaf87'), |
|
|
('217', 'ffafaf'), |
|
|
('218', 'ffafd7'), |
|
|
('219', 'ffafff'), |
|
|
('220', 'ffd700'), |
|
|
('221', 'ffd75f'), |
|
|
('222', 'ffd787'), |
|
|
('223', 'ffd7af'), |
|
|
('224', 'ffd7d7'), |
|
|
('225', 'ffd7ff'), |
|
|
('226', 'ffff00'), |
|
|
('227', 'ffff5f'), |
|
|
('228', 'ffff87'), |
|
|
('229', 'ffffaf'), |
|
|
('230', 'ffffd7'), |
|
|
('231', 'ffffff'), |
|
|
|
|
|
# Gray-scale range. |
|
|
('232', '080808'), |
|
|
('233', '121212'), |
|
|
('234', '1c1c1c'), |
|
|
('235', '262626'), |
|
|
('236', '303030'), |
|
|
('237', '3a3a3a'), |
|
|
('238', '444444'), |
|
|
('239', '4e4e4e'), |
|
|
('240', '585858'), |
|
|
('241', '626262'), |
|
|
('242', '6c6c6c'), |
|
|
('243', '767676'), |
|
|
('244', '808080'), |
|
|
('245', '8a8a8a'), |
|
|
('246', '949494'), |
|
|
('247', '9e9e9e'), |
|
|
('248', 'a8a8a8'), |
|
|
('249', 'b2b2b2'), |
|
|
('250', 'bcbcbc'), |
|
|
('251', 'c6c6c6'), |
|
|
('252', 'd0d0d0'), |
|
|
('253', 'dadada'), |
|
|
('254', 'e4e4e4'), |
|
|
('255', 'eeeeee'), |
|
|
] |
|
|
|
|
|
def _str2hex(hexstr): |
|
|
return int(hexstr, 16) |
|
|
|
|
|
def _strip_hash(rgb): |
|
|
# Strip leading `#` if exists. |
|
|
if rgb.startswith('#'): |
|
|
rgb = rgb.lstrip('#') |
|
|
return rgb |
|
|
|
|
|
def _create_dicts(): |
|
|
short2rgb_dict = dict(CLUT) |
|
|
rgb2short_dict = {} |
|
|
for k, v in short2rgb_dict.items(): |
|
|
rgb2short_dict[v] = k |
|
|
return rgb2short_dict, short2rgb_dict |
|
|
|
|
|
def short2rgb(short): |
|
|
return SHORT2RGB_DICT[short] |
|
|
|
|
|
def print_all(): |
|
|
""" Print all 256 xterm color codes. |
|
|
""" |
|
|
for short, rgb in CLUT: |
|
|
sys.stdout.write('\033[48;5;%sm%s:%s' % (short, short, rgb)) |
|
|
sys.stdout.write("\033[0m ") |
|
|
sys.stdout.write('\033[38;5;%sm%s:%s' % (short, short, rgb)) |
|
|
sys.stdout.write("\033[0m\n") |
|
|
print "Printed all codes." |
|
|
print "You can translate a hex or 0-255 code by providing a argument." |
|
|
|
|
|
def rgb2short(rgb): |
|
|
""" Find the closest xterm-256 approximation to the given RGB value. |
|
|
@param rgb: Hex code representing an RGB value, eg, 'abcdef' |
|
|
@returns: String between 0 and 255, compatible with xterm. |
|
|
>>> rgb2short('123456') |
|
|
'233' |
|
|
>>> rgb2short('0') |
|
|
'16' |
|
|
>>> rgb2short('ffffff') |
|
|
'231' |
|
|
>>> rgb2short('DEAD') |
|
|
'45' |
|
|
>>> rgb2short('dead') |
|
|
'45' |
|
|
>>> rgb2short('#dead') |
|
|
'45' |
|
|
""" |
|
|
rgb = _strip_hash(rgb) |
|
|
closest = None |
|
|
##print '***', rgb |
|
|
# Convert string rep of hex into actual hex. |
|
|
rgb = _str2hex(rgb) |
|
|
vals_list = SHORT2RGB_DICT.values() |
|
|
vals_list.sort() |
|
|
i = 0 |
|
|
while i < len(vals_list) - 1: |
|
|
s, b = _str2hex(vals_list[i]), _str2hex(vals_list[i+1]) # smaller, bigger |
|
|
##print 'test:', hex(s) , hex(rgb) , hex(b) |
|
|
# Find closest match to input. |
|
|
if s <= rgb < b: |
|
|
s1 = abs(s - rgb) |
|
|
b1 = abs(b - rgb) |
|
|
if s1 < b1: closest = s |
|
|
else: closest = b |
|
|
break |
|
|
i += 1 |
|
|
if closest is None: |
|
|
##print "Oops, didn't find match!" |
|
|
return RGB2SHORT_DICT['ffffff'] |
|
|
return RGB2SHORT_DICT[ '%06.x' % closest ] |
|
|
|
|
|
RGB2SHORT_DICT, SHORT2RGB_DICT = _create_dicts() |
|
|
|
|
|
#--------------------------------------------------------------------- |
|
|
|
|
|
if __name__ == '__main__': |
|
|
import doctest |
|
|
doctest.testmod() |
|
|
if len(sys.argv) == 1: |
|
|
print_all() |
|
|
raise SystemExit |
|
|
arg = sys.argv[1] |
|
|
if len(arg) < 4 and int(arg) < 256: |
|
|
print 'xterm color %s -> RGB exact %s' % ( |
|
|
arg, short2rgb(arg) ) |
|
|
else: |
|
|
print 'RGB %s -> xterm color approx %s' % ( |
|
|
arg, rgb2short(arg) ) |