Added a flag to enable 24bit color output in images.
[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
60431c3b 27def pixel_print(ansicolor):
531f5682
O
28 """
29 Print a pixel with given Ansi color
30 """
60431c3b 31 sys.stdout.write('\033[48;5;%sm \033[0m' % (ansicolor))
991c30af
O
32
33
69b6ab70 34def block_print(higher, lower):
a3cf675b
JH
35 """
36 Print two pixels arranged above each other with Ansi color.
37 Abuses Unicode to print two pixels in the space of one terminal block.
38 """
69b6ab70
JH
39 r0, g0, b0 = lower[:3]
40 r1, g1, b1 = higher[:3]
41
42 if c['24BIT'] is True:
43 sys.stdout.write('\033[38;2;%d;%d;%dm\033[48;2;%d;%d;%dm▄\033[0m'
44 % (r1, g1, b1, r0, g0, b0))
45 else:
46 i0 = rgb2short(r0, g0, b0)
47 i1 = rgb2short(r1, g1, b1)
48 sys.stdout.write('\033[38;5;%sm\033[48;5;%sm▄\033[0m' % (i1, i0))
a3cf675b
JH
49
50
422dd385 51def image_to_display(path, start=None, length=None):
531f5682
O
52 """
53 Display an image
54 """
4592d231 55 rows, columns = os.popen('stty size', 'r').read().split()
56 if not start:
632c6fa5 57 start = c['IMAGE_SHIFT']
4592d231 58 if not length:
59 length = int(columns) - 2 * start
991c30af 60 i = Image.open(path)
60431c3b 61 i = i.convert('RGBA')
991c30af 62 w, h = i.size
60431c3b 63 i.load()
4592d231 64 width = min(w, length)
60431c3b 65 height = int(float(h) * (float(width) / float(w)))
f5677fb1 66 i = i.resize((width, height), Image.ANTIALIAS)
632c6fa5 67 height = min(height, c['IMAGE_MAX_HEIGHT'])
60431c3b 68
a3cf675b 69 for real_y in xrange(height // 2):
c3bab4ef 70 sys.stdout.write(' ' * start)
13e6b275 71 for x in xrange(width):
a3cf675b
JH
72 y = real_y * 2
73 p0 = i.getpixel((x, y))
74 p1 = i.getpixel((x, y+1))
69b6ab70 75 block_print(p1, p0)
c3bab4ef 76 sys.stdout.write('\n')
60431c3b 77
531f5682
O
78
79"""
80For direct using purpose
81"""
60431c3b 82if __name__ == '__main__':
83 image_to_display(sys.argv[1])