Skip to content

Instantly share code, notes, and snippets.

@bahorn
Last active October 27, 2023 15:04
Show Gist options
  • Save bahorn/a22a9730744d99f35f156d563336bdd8 to your computer and use it in GitHub Desktop.
Save bahorn/a22a9730744d99f35f156d563336bdd8 to your computer and use it in GitHub Desktop.
Converts images to emojis.... Also has support for mp4s if you want to watch them in 16 color emoji for some reason.
#!/usr/bin/env python3
import argparse
import cv2
import emojipic
import sys
import time
from PIL import *
def clearscreen(n):
print('\033[1A\033[K'*n, end='')
def main(filename, resize):
vc = cv2.VideoCapture(filename)
tpf = 1.0/vc.get(cv2.CAP_PROP_FPS)
ei = emojipic.EmojiImage()
if vc.isOpened():
rval = True
while rval:
start = time.time()
rval, frame = vc.read()
if rval:
ei.fromarray(frame)
res, height = ei.make(resize)
print(res, end='')
clearscreen(height)
# determine if we need to sleep. Not really that accurate, but i'm
# lazy and this is good enough.
diff = time.time()-start
if diff < tpf:
time.sleep(tpf-diff)
vc.release()
if __name__ == "__main__":
parser = argparse.ArgumentParser(
description='Displays Emoji Animations in your terminal')
parser.add_argument('filename', type=str, help='MP4 to display')
parser.add_argument('--resize', type=int, default=32,
help='How many characters to scale this to')
args = parser.parse_args()
main(args.filename, args.resize)
#!/usr/bin/env python3
import math
import argparse
from PIL import Image
class EmojiImage:
# These are the default colors that I picked out based on the websafe
# colors list available here:
# https://en.wikipedia.org/wiki/Web_colors#HTML_color_names
# Colors are represented as 32bit values of the form RGBA.
colors = [
(0x00000000, '⬛'), # Black
(0xffffff00, '⬜'), # White
(0xff000000, '🍎'), # Red
(0x80000000, 'πŸŒ‡'), # Maroon
(0x00ff0000, 'πŸ€'), # Lime
(0x00800000, '🐸'), # Green
(0x0000ff00, 'πŸ†•'), # Blue
(0xff7f0000, 'πŸ†š'), # Orange
(0xffff0000, '😢'), # Yellow
(0x80800000, '🐻'), # Olive
(0x80008000, '😈'), # Purple
(0x80808000, '🐭'), # Gray
(0xc0c0c000, 'πŸ‘½'), # Silver
(0x00808000, 'πŸ—½'), # Teal
(0x00008000, 'πŸŒƒ'), # Navy
(0xff00ff00, '🐽'), # Fuchsia
(0x00ffff00, '🐳'), # Aqua
]
def __init__(self, colors=None):
if colors is not None:
self.colors = colors
# We provide this method as we may want to use this class with in memory
# objects instead of files.
def open(self, filename):
self.img = Image.open(filename)
self.img = self.img.convert('RGBA')
def fromarray(self, array):
self.img = Image.fromarray(array)
self.img = self.img.convert('RGBA')
def make(self, resize=64):
img = self.img.copy()
img.thumbnail((resize, resize))
width, height = img.size
# Go through and build our output string up pixel by pixel
output = ""
for y in range(height):
line = ""
for x in range(width):
r, g, b, a = img.getpixel((x, y))
selection = self._distcolor(r, g, b, a)
line += selection
output += line + '\n'
return (output, height)
def _distcolor(self, r1, g1, b1, a1):
best = {'value': None, 'symbol': ' '}
for color, symbol in self.colors:
r2, g2, b2, a2 = color.to_bytes(4, byteorder='big')
dist = math.sqrt(
(r1-r2)**2+(g1-g2)**2+(b1-b2)**2+(a1-a2)**2
)
if best['value'] is None or dist < best['value']:
best = {'value': dist, 'symbol': symbol}
return best['symbol']
if __name__ == "__main__":
parser = argparse.ArgumentParser(
description='Converts Images into Emojis.')
parser.add_argument('filename', type=str, help='File to process')
parser.add_argument('--resize', type=int, default=64,
help='What the largest dimension is scaled to.')
args = parser.parse_args()
ei = EmojiImage()
ei.open(args.filename)
print(ei.make(args.resize)[0])
@bahorn
Copy link
Author

bahorn commented Jul 6, 2019

You can find a video of the animation script running Bad Apple here: https://www.youtube.com/watch?v=v8r94cRrpXE

@bahorn
Copy link
Author

bahorn commented Jul 6, 2019

I've moved this to the following repo: https://github.com/bahorn/emojipic

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment