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