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