Skip to content

Instantly share code, notes, and snippets.

@karlrwjohnson
Created June 12, 2019 03:37
Show Gist options
  • Save karlrwjohnson/71615d8dcfc9d026402c8eaa09c2079e to your computer and use it in GitHub Desktop.
Save karlrwjohnson/71615d8dcfc9d026402c8eaa09c2079e to your computer and use it in GitHub Desktop.
#!/usr/bin/env python3.6
BOX_CHARS = list(' ▘▝▀▖▌▞▛▗▚▐▜▄▙▟█')
BOX_PIXEL_ORDER = ((0,0), (1,0), (0,1), (1,1))
from argparse import ArgumentParser
from PIL import Image
from subprocess import Popen, PIPE
parser = ArgumentParser('Image to block character converter')
parser.add_argument('filename', help='File to convert to text')
args = parser.parse_args()
im = Image.open(args.filename)
out, errs = Popen(['tput', 'cols'], stdout=PIPE).communicate()
text_cols = int(out)
out, errs = Popen(['tput', 'lines'], stdout=PIPE).communicate()
text_rows = int(out)
img_width = text_cols * 2
img_height = text_rows * 2
factor = min([img_width / im.width / 2, img_height / im.height])
thumb = im.resize((int(im.width * factor * 2), int(im.height * factor)))
thumb_px = thumb.load()
class PixelGetter:
def __init__(self, pixelAccess):
self._pixelAccess = pixelAccess
def __getitem__(self, xy):
try:
r,g,b,*rest = self._pixelAccess[xy]
if (r + g + b) / 3 > 127:
return 1
else:
return 0
except IndexError:
return 0
def binaryOr(itr):
ret = 0
for i in itr:
ret |= i
return ret
getter = PixelGetter(thumb_px)
print('\n'.join(
''.join(
BOX_CHARS[binaryOr(
getter[(x+x1, y+y1)] << i
for i, (x1, y1) in enumerate(BOX_PIXEL_ORDER)
)]
for x in range(0, thumb.width, 2)
)
for y in range(0, thumb.height, 2)
))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment