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