├── img.png ├── requirements.txt ├── readme.md └── main.py /img.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Aryvyo/ascii-player/HEAD/img.png -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | Pillow 2 | colorama 3 | opencv-python 4 | blessed 5 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # ASCII EVERYTHING!!! 2 | 3 | simple script that converts images and videos to ASCII for your viewing, right in your terminal of choice! 4 | 5 | Supports colour where there is 24-bit colour support, and runs at about 30fps, however your mileage may vary depending on terminal, hardware etc 6 | 7 | I didn't tell you this but if you comment out the `time.sleep()` you could probably get 60fps, just saying... 8 | 9 | ## Installation 10 | 11 | This should work on most versions of Python 3, and most modern terminals 12 | Just run 13 | 14 | ` pip install -r requirements.txt ` 15 | 16 | 17 | ## Usage 18 | 19 | ` main.py [file] [-args] ` 20 | 21 | ## Arguments 22 | 23 | `-c` runs the script with colour support, can be buggy with buffering sometimes 24 | 25 | `-f` uses an alternative, larger set of ASCII characters 26 | 27 | 28 | ## 29 | 30 | feel free to fork, star, do whatever! This was a fun 3 hour project 31 | 32 | sample image is courtesy of [qdiffusion](discord.gg/KJZ3T3fCpyp) , go check it out!!! 33 | -------------------------------------------------------------------------------- /main.py: -------------------------------------------------------------------------------- 1 | from PIL import Image 2 | import os 3 | from colorama import init 4 | import cv2 5 | import time 6 | from blessed import Terminal 7 | import sys 8 | 9 | term = Terminal() 10 | 11 | init() 12 | 13 | strcharset = "@#$%&*()0!=-.," 14 | 15 | size = os.get_terminal_size() 16 | 17 | imgs = [] 18 | 19 | isColored = False 20 | 21 | 22 | def pix_to_code(i, img): 23 | x = i % size.columns-1 24 | y = i // size.columns-1 25 | 26 | code = img.getpixel((x, y)) 27 | return f"\033[38;2;{code[0]};{code[1]};{code[2]}m" 28 | 29 | 30 | def printImg(image): 31 | img = image.resize((size.columns, size.lines), Image.Resampling.LANCZOS) 32 | 33 | gimg = img.convert('L') 34 | 35 | img = img.quantize(colors=32) 36 | img = img.convert('RGB') 37 | 38 | pixels = list(gimg.getdata()) 39 | 40 | string = "" 41 | lastcolor = None 42 | 43 | # splitting these up because its kinda braindead to be checking for color 44 | # every pixel idk what i was thinking 45 | if isColored: 46 | for i in range(len(pixels)): 47 | 48 | if i % size.columns-1 == 0: 49 | string += "\n" 50 | ind = int(pixels[i] / 255 * (len(strcharset) - 1)) 51 | # now we have the pixel brightness mapped to a char, lets colour it! 52 | # this is why we have img and gimg 53 | # string += pix_to_code(i, img) + strcharset[ind] + "\033[0;39m" 54 | # string += strcharset[ind] 55 | color = f"{pix_to_code(i, img)}" 56 | if color != lastcolor: 57 | string += "\033[0;39m" + color + strcharset[ind] 58 | lastcolor = color 59 | else: 60 | string += strcharset[ind] 61 | else: 62 | for i in range(len(pixels)): 63 | 64 | if i % size.columns-1 == 0: 65 | string += "\n" 66 | ind = int(pixels[i] / 255 * (len(strcharset) - 1)) 67 | 68 | string += strcharset[ind] 69 | 70 | with term.hidden_cursor(): 71 | sys.stdout.write(term.home) 72 | sys.stdout.write(string) 73 | sys.stdout.flush() 74 | 75 | 76 | def openVideo(file): 77 | vid = cv2.VideoCapture(file) 78 | 79 | while vid.isOpened(): 80 | ret, img = vid.read() 81 | 82 | if ret: 83 | 84 | conv = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) 85 | 86 | pilImg = Image.fromarray(conv) 87 | 88 | imgs.append(pilImg) 89 | 90 | else: 91 | break 92 | 93 | vid.release() 94 | 95 | 96 | print(sys.argv) 97 | if len(sys.argv) > 1: 98 | 99 | if sys.argv[1].split(".")[2] in ["mp4", "avi", "mov", "gif"]: 100 | openVideo(sys.argv[1]) 101 | else: 102 | imgs.append(Image.open(sys.argv[1])) 103 | 104 | if len(sys.argv) >= 2: 105 | for i in sys.argv[2:]: 106 | match i: 107 | case "-c": 108 | isColored = True 109 | case "-f": 110 | strcharset = "$@B%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/\|()1{}[]?-_+~<>i!lI;:,^`'." 111 | 112 | for img in imgs: 113 | printImg(img) 114 | # each print takes about 0.0166 s, so if we wanna run at 30fps... 115 | time.sleep(0.01666667) 116 | print("\033[0;39m") 117 | else: 118 | print("No file provided. Please provide a file as an argument.") 119 | --------------------------------------------------------------------------------