clean up
[rainbowstream.git] / rainbowstream / pure_image.py
CommitLineData
0418d443 1from PIL import Image
026caf17 2from functools import partial
1c50e2d1 3
60431c3b 4import sys,os
1c50e2d1
O
5
6CLUT = [ # color look-up table
7# 8-bit, RGB hex
8
9 # Primary 3-bit (8 colors). Unique representation!
10 ('00', '000000'),
11 ('01', '800000'),
12 ('02', '008000'),
13 ('03', '808000'),
14 ('04', '000080'),
15 ('05', '800080'),
16 ('06', '008080'),
17 ('07', 'c0c0c0'),
18
19 # Equivalent "bright" versions of original 8 colors.
20 ('08', '808080'),
21 ('09', 'ff0000'),
22 ('10', '00ff00'),
23 ('11', 'ffff00'),
24 ('12', '0000ff'),
25 ('13', 'ff00ff'),
26 ('14', '00ffff'),
27 ('15', 'ffffff'),
28
29 # Strictly ascending.
30 ('16', '000000'),
31 ('17', '00005f'),
32 ('18', '000087'),
33 ('19', '0000af'),
34 ('20', '0000d7'),
35 ('21', '0000ff'),
36 ('22', '005f00'),
37 ('23', '005f5f'),
38 ('24', '005f87'),
39 ('25', '005faf'),
40 ('26', '005fd7'),
41 ('27', '005fff'),
42 ('28', '008700'),
43 ('29', '00875f'),
44 ('30', '008787'),
45 ('31', '0087af'),
46 ('32', '0087d7'),
47 ('33', '0087ff'),
48 ('34', '00af00'),
49 ('35', '00af5f'),
50 ('36', '00af87'),
51 ('37', '00afaf'),
52 ('38', '00afd7'),
53 ('39', '00afff'),
54 ('40', '00d700'),
55 ('41', '00d75f'),
56 ('42', '00d787'),
57 ('43', '00d7af'),
58 ('44', '00d7d7'),
59 ('45', '00d7ff'),
60 ('46', '00ff00'),
61 ('47', '00ff5f'),
62 ('48', '00ff87'),
63 ('49', '00ffaf'),
64 ('50', '00ffd7'),
65 ('51', '00ffff'),
66 ('52', '5f0000'),
67 ('53', '5f005f'),
68 ('54', '5f0087'),
69 ('55', '5f00af'),
70 ('56', '5f00d7'),
71 ('57', '5f00ff'),
72 ('58', '5f5f00'),
73 ('59', '5f5f5f'),
74 ('60', '5f5f87'),
75 ('61', '5f5faf'),
76 ('62', '5f5fd7'),
77 ('63', '5f5fff'),
78 ('64', '5f8700'),
79 ('65', '5f875f'),
80 ('66', '5f8787'),
81 ('67', '5f87af'),
82 ('68', '5f87d7'),
83 ('69', '5f87ff'),
84 ('70', '5faf00'),
85 ('71', '5faf5f'),
86 ('72', '5faf87'),
87 ('73', '5fafaf'),
88 ('74', '5fafd7'),
89 ('75', '5fafff'),
90 ('76', '5fd700'),
91 ('77', '5fd75f'),
92 ('78', '5fd787'),
93 ('79', '5fd7af'),
94 ('80', '5fd7d7'),
95 ('81', '5fd7ff'),
96 ('82', '5fff00'),
97 ('83', '5fff5f'),
98 ('84', '5fff87'),
99 ('85', '5fffaf'),
100 ('86', '5fffd7'),
101 ('87', '5fffff'),
102 ('88', '870000'),
103 ('89', '87005f'),
104 ('90', '870087'),
105 ('91', '8700af'),
106 ('92', '8700d7'),
107 ('93', '8700ff'),
108 ('94', '875f00'),
109 ('95', '875f5f'),
110 ('96', '875f87'),
111 ('97', '875faf'),
112 ('98', '875fd7'),
113 ('99', '875fff'),
114 ('100', '878700'),
115 ('101', '87875f'),
116 ('102', '878787'),
117 ('103', '8787af'),
118 ('104', '8787d7'),
119 ('105', '8787ff'),
120 ('106', '87af00'),
121 ('107', '87af5f'),
122 ('108', '87af87'),
123 ('109', '87afaf'),
124 ('110', '87afd7'),
125 ('111', '87afff'),
126 ('112', '87d700'),
127 ('113', '87d75f'),
128 ('114', '87d787'),
129 ('115', '87d7af'),
130 ('116', '87d7d7'),
131 ('117', '87d7ff'),
132 ('118', '87ff00'),
133 ('119', '87ff5f'),
134 ('120', '87ff87'),
135 ('121', '87ffaf'),
136 ('122', '87ffd7'),
137 ('123', '87ffff'),
138 ('124', 'af0000'),
139 ('125', 'af005f'),
140 ('126', 'af0087'),
141 ('127', 'af00af'),
142 ('128', 'af00d7'),
143 ('129', 'af00ff'),
144 ('130', 'af5f00'),
145 ('131', 'af5f5f'),
146 ('132', 'af5f87'),
147 ('133', 'af5faf'),
148 ('134', 'af5fd7'),
149 ('135', 'af5fff'),
150 ('136', 'af8700'),
151 ('137', 'af875f'),
152 ('138', 'af8787'),
153 ('139', 'af87af'),
154 ('140', 'af87d7'),
155 ('141', 'af87ff'),
156 ('142', 'afaf00'),
157 ('143', 'afaf5f'),
158 ('144', 'afaf87'),
159 ('145', 'afafaf'),
160 ('146', 'afafd7'),
161 ('147', 'afafff'),
162 ('148', 'afd700'),
163 ('149', 'afd75f'),
164 ('150', 'afd787'),
165 ('151', 'afd7af'),
166 ('152', 'afd7d7'),
167 ('153', 'afd7ff'),
168 ('154', 'afff00'),
169 ('155', 'afff5f'),
170 ('156', 'afff87'),
171 ('157', 'afffaf'),
172 ('158', 'afffd7'),
173 ('159', 'afffff'),
174 ('160', 'd70000'),
175 ('161', 'd7005f'),
176 ('162', 'd70087'),
177 ('163', 'd700af'),
178 ('164', 'd700d7'),
179 ('165', 'd700ff'),
180 ('166', 'd75f00'),
181 ('167', 'd75f5f'),
182 ('168', 'd75f87'),
183 ('169', 'd75faf'),
184 ('170', 'd75fd7'),
185 ('171', 'd75fff'),
186 ('172', 'd78700'),
187 ('173', 'd7875f'),
188 ('174', 'd78787'),
189 ('175', 'd787af'),
190 ('176', 'd787d7'),
191 ('177', 'd787ff'),
192 ('178', 'd7af00'),
193 ('179', 'd7af5f'),
194 ('180', 'd7af87'),
195 ('181', 'd7afaf'),
196 ('182', 'd7afd7'),
197 ('183', 'd7afff'),
198 ('184', 'd7d700'),
199 ('185', 'd7d75f'),
200 ('186', 'd7d787'),
201 ('187', 'd7d7af'),
202 ('188', 'd7d7d7'),
203 ('189', 'd7d7ff'),
204 ('190', 'd7ff00'),
205 ('191', 'd7ff5f'),
206 ('192', 'd7ff87'),
207 ('193', 'd7ffaf'),
208 ('194', 'd7ffd7'),
209 ('195', 'd7ffff'),
210 ('196', 'ff0000'),
211 ('197', 'ff005f'),
212 ('198', 'ff0087'),
213 ('199', 'ff00af'),
214 ('200', 'ff00d7'),
215 ('201', 'ff00ff'),
216 ('202', 'ff5f00'),
217 ('203', 'ff5f5f'),
218 ('204', 'ff5f87'),
219 ('205', 'ff5faf'),
220 ('206', 'ff5fd7'),
221 ('207', 'ff5fff'),
222 ('208', 'ff8700'),
223 ('209', 'ff875f'),
224 ('210', 'ff8787'),
225 ('211', 'ff87af'),
226 ('212', 'ff87d7'),
227 ('213', 'ff87ff'),
228 ('214', 'ffaf00'),
229 ('215', 'ffaf5f'),
230 ('216', 'ffaf87'),
231 ('217', 'ffafaf'),
232 ('218', 'ffafd7'),
233 ('219', 'ffafff'),
234 ('220', 'ffd700'),
235 ('221', 'ffd75f'),
236 ('222', 'ffd787'),
237 ('223', 'ffd7af'),
238 ('224', 'ffd7d7'),
239 ('225', 'ffd7ff'),
240 ('226', 'ffff00'),
241 ('227', 'ffff5f'),
242 ('228', 'ffff87'),
243 ('229', 'ffffaf'),
244 ('230', 'ffffd7'),
245 ('231', 'ffffff'),
246
247 # Gray-scale range.
248 ('232', '080808'),
249 ('233', '121212'),
250 ('234', '1c1c1c'),
251 ('235', '262626'),
252 ('236', '303030'),
253 ('237', '3a3a3a'),
254 ('238', '444444'),
255 ('239', '4e4e4e'),
256 ('240', '585858'),
257 ('241', '626262'),
258 ('242', '6c6c6c'),
259 ('243', '767676'),
260 ('244', '808080'),
261 ('245', '8a8a8a'),
262 ('246', '949494'),
263 ('247', '9e9e9e'),
264 ('248', 'a8a8a8'),
265 ('249', 'b2b2b2'),
266 ('250', 'bcbcbc'),
267 ('251', 'c6c6c6'),
268 ('252', 'd0d0d0'),
269 ('253', 'dadada'),
270 ('254', 'e4e4e4'),
271 ('255', 'eeeeee'),
272]
273
1c50e2d1
O
274def _create_dicts():
275 short2rgb_dict = dict(CLUT)
276 rgb2short_dict = {}
277 for k, v in short2rgb_dict.items():
278 rgb2short_dict[v] = k
279 return rgb2short_dict, short2rgb_dict
280
60431c3b 281RGB2SHORT_DICT, SHORT2RGB_DICT = _create_dicts()
282
283
1c50e2d1
O
284def short2rgb(short):
285 return SHORT2RGB_DICT[short]
286
60431c3b 287
2b502606 288def pixel_print(ansicolor):
289 sys.stdout.write('\033[48;5;%sm \033[0m' % (ansicolor))
290
60431c3b 291
25e5e7f4 292def hex_to_rgb(value):
293 value = value.lstrip('#')
294 lv = len(value)
295 return tuple(int(value[i:i+lv/3], 16) for i in range(0, lv, lv/3))
296
60431c3b 297
25e5e7f4 298def rgb_to_hex(rgb):
60431c3b 299 return '%02x%02x%02x' % rgb
25e5e7f4 300
026caf17 301
60431c3b 302def rgb2short(r, g, b):
026caf17 303 dist = lambda s,d: (s[0]-d[0])**2+(s[1]-d[1])**2+(s[2]-d[2])**2
2b502606 304 ary = [hex_to_rgb(hex) for hex in RGB2SHORT_DICT]
026caf17 305 m = min(ary, key=partial(dist, (r,g,b)))
60431c3b 306 return RGB2SHORT_DICT[rgb_to_hex(m)]
1c50e2d1 307
2b502606 308def image_to_display(path):
25e5e7f4 309 i = Image.open(path)
2b502606 310 i = i.convert('RGBA')
311 w,h = i.size
312 i.load()
313 rows, columns = os.popen('stty size', 'r').read().split()
314 width = min(w, int(columns)-2*6)
315 height = int(float(h) * (float(width) / float(w)))
316 height //= 2
317 i = i.resize((width, height), Image.BICUBIC)
60431c3b 318 height = min(height,30)
2b502606 319
320 for y in xrange(height):
321 print ' '*6 ,
322 for x in xrange(width):
323 p = i.getpixel((x,y))
324 r, g, b = p[:3]
60431c3b 325 pixel_print(rgb2short(r,g,b))
2b502606 326 print ''
25e5e7f4 327
1c50e2d1 328if __name__ == '__main__':
60431c3b 329 image_to_display(sys.argv[1])
026caf17 330