Last active
October 12, 2023 14:59
-
-
Save salt-die/576220194d14ea69894cd129a91fba34 to your computer and use it in GitHub Desktop.
rick rolling in ascii!
This file contains hidden or 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
import curses | |
from itertools import product | |
from time import time, sleep | |
import cv2 | |
import numpy as np | |
path = "never_gonna.mp4" | |
ASCII_MAP = np.array(list(' .,:;<+*LtCa4U80dQM@')) | |
SCALE = len(ASCII_MAP) / 255 | |
VALUES = [255 // 5 * i for i in range(6)] | |
COLOR_MAP = np.array([min(range(6), key=lambda index: abs(VALUES[index] - color)) for color in range(256)]) | |
BASE_6 = np.array([36, 6, 1]) | |
def init_curses(screen): | |
curses.noecho() | |
curses.cbreak() | |
screen.nodelay(1) | |
curses.curs_set(0) | |
curses.start_color() | |
for x, y, z in product(range(6), repeat=3): | |
curses.init_color(x * 6 ** 2 + y * 6 + z + 17, *(round(1000 / 255 * VALUES[i]) for i in (z, y, x))) | |
for i in range(6 ** 3): | |
curses.init_pair(i + 1, i + 17, 0) | |
screen.clear() | |
def main(screen): | |
init_curses(screen) | |
curses_pairs = np.array([curses.color_pair(i) for i in range(1, 6 ** 3 + 1)]) | |
h, w = screen.getmaxyx() | |
dim = w - 1, h | |
movie = cv2.VideoCapture(path) | |
start = time() | |
while screen.getch() != ord('q'): | |
read_flag, frame = movie.read() | |
if not read_flag: | |
break | |
color = cv2.resize(frame, dim) | |
grayscale = ASCII_MAP[ (SCALE * cv2.cvtColor(color, cv2.COLOR_BGR2GRAY)).astype(int) ] | |
pairs = curses_pairs[(BASE_6 * COLOR_MAP[color]).sum(axis=-1)] | |
it = np.nditer((grayscale, pairs), ["multi_index"]) | |
for char, pair in it: | |
y, x = it.multi_index | |
screen.addstr(y, x, str(char), pair) | |
delta = movie.get(cv2.CAP_PROP_POS_MSEC) / 1000 - (time() - start) | |
if delta > 0: | |
sleep(delta) | |
screen.refresh() | |
movie.release() | |
if __name__ == '__main__': | |
curses.wrapper(main) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
you are evil 🤣