Added 24bit color for pixel printing
[rainbowstream.git] / rainbowstream / c_image.py
CommitLineData
0418d443 1from PIL import Image
60431c3b 2from os.path import join, dirname, getmtime, exists, expanduser
816e305f 3from .config import *
13e6b275 4from .py3patch import *
60431c3b 5
991c30af
O
6import ctypes
7import sys
8import os
9
60431c3b 10
11def call_c():
531f5682
O
12 """
13 Call the C program for converting RGB to Ansi colors
14 """
60431c3b 15 library = expanduser('~/.image.so')
16 sauce = join(dirname(__file__), 'image.c')
17 if not exists(library) or getmtime(sauce) > getmtime(library):
4a885ebf 18 build = "cc -fPIC -shared -o %s %s" % (library, sauce)
bb68c687 19 os.system(build + " >/dev/null 2>&1")
991c30af 20 image_c = ctypes.cdll.LoadLibrary(library)
60431c3b 21 image_c.init()
22 return image_c.rgb_to_ansi
23
24rgb2short = call_c()
991c30af
O
25
26
45ff44d2 27def pixel_print(pixel):
531f5682
O
28 """
29 Print a pixel with given Ansi color
30 """
45ff44d2 31 r, g, b = pixel[:3]
e9c756ae
JH
32
33 if c['24BIT'] is True:
34 sys.stdout.write('\033[48;2;%d;%d;%dm \033[0m'
35 % (r, g, b))
36 else:
37 ansicolor = rgb2short(r, g, b)
38 sys.stdout.write('\033[48;5;%sm \033[0m' % (ansicolor))
991c30af
O
39
40
69b6ab70 41def block_print(higher, lower):
a3cf675b
JH
42 """
43 Print two pixels arranged above each other with Ansi color.
44 Abuses Unicode to print two pixels in the space of one terminal block.
45 """
69b6ab70
JH
46 r0, g0, b0 = lower[:3]
47 r1, g1, b1 = higher[:3]
48
49 if c['24BIT'] is True:
50 sys.stdout.write('\033[38;2;%d;%d;%dm\033[48;2;%d;%d;%dm▄\033[0m'
51 % (r1, g1, b1, r0, g0, b0))
52 else:
53 i0 = rgb2short(r0, g0, b0)
54 i1 = rgb2short(r1, g1, b1)
55 sys.stdout.write('\033[38;5;%sm\033[48;5;%sm▄\033[0m' % (i1, i0))
a3cf675b
JH
56
57
422dd385 58def image_to_display(path, start=None, length=None):
531f5682
O
59 """
60 Display an image
61 """
4592d231 62 rows, columns = os.popen('stty size', 'r').read().split()
63 if not start:
632c6fa5 64 start = c['IMAGE_SHIFT']
4592d231 65 if not length:
66 length = int(columns) - 2 * start
991c30af 67 i = Image.open(path)
60431c3b 68 i = i.convert('RGBA')
991c30af 69 w, h = i.size
60431c3b 70 i.load()
4592d231 71 width = min(w, length)
60431c3b 72 height = int(float(h) * (float(width) / float(w)))
45ff44d2
JH
73 if c['HIGHER_RESOLUTION'] is False:
74 height //= 2
f5677fb1 75 i = i.resize((width, height), Image.ANTIALIAS)
632c6fa5 76 height = min(height, c['IMAGE_MAX_HEIGHT'])
60431c3b 77
45ff44d2
JH
78 if c['HIGHER_RESOLUTION'] is True:
79 for real_y in xrange(height // 2):
80 sys.stdout.write(' ' * start)
81 for x in xrange(width):
82 y = real_y * 2
83 p0 = i.getpixel((x, y))
84 p1 = i.getpixel((x, y+1))
85 block_print(p1, p0)
86 sys.stdout.write('\n')
87 else:
88 for y in xrange(height):
89 sys.stdout.write(' ' * start)
90 for x in xrange(width):
91 p = i.getpixel((x, y))
92 pixel_print(p)
93 sys.stdout.write('\n')
60431c3b 94
531f5682
O
95
96"""
97For direct using purpose
98"""
60431c3b 99if __name__ == '__main__':
100 image_to_display(sys.argv[1])