This is a crude and very slow solution to show images on the Terminal from within the Linux command line using a custom escape code and a simple Python program.
// Usage
path/to/primg.py -[options] path/to/image.jpg Options: -w horizontal size (default 300) -h vertical size (default 200) -s max. 100x100 pixel -l max. 600x400 pixel
// primg.py (requires the pillow library)
#!/bin/python3
from sys import argv
from PIL import Image
screen_x = 300
screen_y = 200
# get arguments
def get_args():
global screen_x
global screen_y
for i in range(1, len(argv)):
if argv[i] == "-w":
w = int(argv[i+1])
if w <= 600 and w > 0:
screen_x = w
elif argv[i] == "-h":
h = int(argv[i+1])
if h <= 400 and h > 0:
screen_y = h
elif argv[i] == "-s":
screen_x = 100
screen_y = 100
elif argv[i] == "-l":
screen_x = 600
screen_y = 400
return argv[-1]
# print pixel data to stdout
def rgb_to_stdout(image):
# img = image.convert(mode="RGBA")
img_x, img_y = img.size
print("{0}[{1};{2}z".format(chr(27), img_x, img_y), end="")
for y in range(0, img_y):
for x in range(0, img_x):
r, g, b = img.getpixel((x, y))
r = r // 8
if r == 10:
r = 11
g = g // 4
if g == 10:
g = 11
b = b // 8
if b == 10:
b = 11
print("{0}{1}{2}".format(chr(r), chr(g), chr(b)), end="")
# rotate image if necessary
def check_rotation(img):
x, y = img.size
if ((screen_x > screen_y) and (y > x)) or ((screen_x < screen_y) and (y < x)):
return img.rotate(90, expand=True)
else:
return img
# scale image
def rescale(img):
x, y = img.size
scale_x = x / screen_x
scale_y = y / screen_y
if scale_x > scale_y:
return img.resize((screen_x, int(y / scale_x)))
else:
return img.resize((int(x / scale_y), screen_y))
# program entry
path = get_args()
img = Image.open(path, "r")
img = check_rotation(img)
img = rescale(img)
rgb_to_stdout(img)
// Details
Three weeks ago the idea struck me, that I could try to send pixel values over UART from the NanoPi to the Pico and write them directly to the DDRAM of the RA8875. This solution involves a custom escape code (ESC [ (size_x ); (size_y) z) and printing the pixel RGB565 values as characters to stdout. The terminal expects exactly three times the number of pixels as characters after the escape code and keeps writing the values to the DDRAM of the RA8875 until all pixels are received. Printing values over 127 as character to stdout results in an UTF-8 encoding. Because of this, the RGB values are converted to 565 bit format before using the chr() function. After some trial and error I figured out, that print(chr(10)) didn't work, so I simply change the channel value to 11 if it would be 10.
Discussions
Become a Hackaday.io Member
Create an account to leave a comment. Already have an account? Log In.