Created
January 23, 2021 14:38
-
-
Save jaysonlarose/fc86aa38360910669e7762c5b49c7923 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
# vim: set fileencoding=utf-8 : | |
from __future__ import print_function | |
import sys, PIL.Image, numpy, fcntl, termios, struct, os, fabulous, fabulous.color, fabulous.compatibility | |
def get_terminal_size(): | |
def ioctl_GWINSZ(fd): | |
try: | |
cr = struct.unpack("hh", fcntl.ioctl(fd, termios.TIOCGWINSZ, '1234')) | |
except: | |
return None | |
return cr | |
cr = ioctl_GWINSZ(0) or ioctl_GWINSZ(1) or ioctl_GWINSZ(2) | |
if not cr: | |
try: | |
fd = os.open(os.ctermid(), os.O_RDONLY) | |
cr = ioctl_GWINSZ(fd) | |
os.close(fd) | |
except: | |
pass | |
if not cr: | |
try: | |
cr = (env['LINES'], env['COLUMNS']) | |
except: | |
cr = (25, 80) | |
return int(cr[1]), int(cr[0]) | |
def resize_aspect(orig_width, orig_height, width=None, height=None, factor=None): | |
if width is not None: | |
factor = float(width) / float(orig_width) | |
height = int(orig_height * factor) | |
elif height is not None: | |
factor = float(height) / float(orig_height) | |
width = int(orig_width * factor) | |
else: | |
width = int(orig_width * factor) | |
height = int(orig_height * factor) | |
return width, height, factor | |
def splitlen_array(data, length): | |
return [ data[x:x+length] for x in [ x * length for x in range(int(len(data) / length)) ] ] | |
_magic_aspect = 1.0 / 2.0 | |
if __name__ == '__main__': | |
import argparse | |
parser = argparse.ArgumentParser() | |
parser.add_argument("image_file") | |
parser.add_argument("--fit-height", action="store", dest="fit_height", type=int, default=None, help="Constrain output dimensions to terminal height minus this many rows") | |
parser.add_argument("--pixel-aspect", action="store", dest="pixel_aspect", type=float, default=_magic_aspect, help="Pixel squareness adjustment") | |
parser.add_argument("--halfblock", action="store_true", dest="halfblock", default=False, help="Double your vertical resolution with \u2580") | |
args = parser.parse_args() | |
img = PIL.Image.open(args.image_file) | |
cols, rows = get_terminal_size() | |
# Calculate resize dimensions | |
# newdims — resized image dimensions, with square pixels | |
# newdims_magic — resized image dimensions after adjusting pixel aspect ratio | |
newdims_magic = None | |
if args.fit_height is not None: | |
newdims = resize_aspect(img.width, img.height, height=rows - args.fit_height) | |
newdims_magic = (int(newdims[0] / args.pixel_aspect), newdims[1]) | |
if newdims_magic is None or newdims_magic[0] > cols: | |
newdims = resize_aspect(img.width, img.height, width=cols) | |
newdims_magic = (newdims[0], int(newdims[1] * args.pixel_aspect)) | |
if args.halfblock: | |
newdims_magic = (newdims_magic[0], newdims_magic[1] * 2) | |
# Perform resize | |
resized_img = img.resize((newdims_magic[0], newdims_magic[1]), PIL.Image.BICUBIC) | |
# Convert to RGB if necessary | |
if resized_img.mode != 'RGB': | |
resized_img = resized_img.convert("RGB") | |
# Convert to numpy array | |
arr = numpy.array(bytearray(resized_img.tobytes()), dtype=numpy.uint8).reshape(newdims_magic[1], newdims_magic[0], -1) | |
# Print it out | |
if not args.halfblock: | |
for row in arr: | |
rowrep = b'' | |
for char in row: | |
rowrep += fabulous.color.fgtrue("#{:02x}{:02x}{:02x}".format(*char), u"\u2588").as_utf8 | |
if sys.version_info.major >= 3: | |
rowrep = rowrep.decode() | |
print(rowrep) | |
else: | |
for rowpair in splitlen_array(arr, 2): | |
rowrep = b'' | |
for top, bot in zip(*rowpair): | |
rowrep += fabulous.color.bgtrue("#{:02x}{:02x}{:02x}".format(*bot), fabulous.color.fgtrue("#{:02x}{:02x}{:02x}".format(*top), u"\u2580")).as_utf8 | |
if sys.version_info.major >= 3: | |
rowrep = rowrep.decode() | |
print(rowrep) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment