├── Assets ├── Song.mp3 └── Video.mp4 ├── Code.py ├── README.md └── requirements.txt /Assets/Song.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RiothDev/Bad-Apple/8f50a19f9ef3b3e172f3c7735c99170087ed427a/Assets/Song.mp3 -------------------------------------------------------------------------------- /Assets/Video.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RiothDev/Bad-Apple/8f50a19f9ef3b3e172f3c7735c99170087ed427a/Assets/Video.mp4 -------------------------------------------------------------------------------- /Code.py: -------------------------------------------------------------------------------- 1 | import os, cv2, fpstimer, sys, screeninfo, math, sys, traceback, colorama 2 | os.environ['PYGAME_HIDE_SUPPORT_PROMPT'] = "hide" 3 | 4 | import pygame 5 | from PIL import Image 6 | 7 | ASCII_CHARS = ["1", "2", "3", "4", "5", "6", "7", "8", "9", ".", ","] 8 | ASCII_IMAGES = [] 9 | TITLE = """ 10 | ██████╗░░█████╗░██████╗░  ░█████╗░██████╗░██████╗░██╗░░░░░███████╗  ██████╗░██╗░░░██╗ 11 | ██╔══██╗██╔══██╗██╔══██╗  ██╔══██╗██╔══██╗██╔══██╗██║░░░░░██╔════╝  ██╔══██╗╚██╗░██╔╝ 12 | ██████╦╝███████║██║░░██║  ███████║██████╔╝██████╔╝██║░░░░░█████╗░░  ██████╦╝░╚████╔╝░ 13 | ██╔══██╗██╔══██║██║░░██║  ██╔══██║██╔═══╝░██╔═══╝░██║░░░░░██╔══╝░░  ██╔══██╗░░╚██╔╝░░ 14 | ██████╦╝██║░░██║██████╔╝  ██║░░██║██║░░░░░██║░░░░░███████╗███████╗  ██████╦╝░░░██║░░░ 15 | ╚═════╝░╚═╝░░╚═╝╚═════╝░  ╚═╝░░╚═╝╚═╝░░░░░╚═╝░░░░░╚══════╝╚══════╝  ╚═════╝░░░░╚═╝░░░ 16 | 17 | ██████╗░██╗░█████╗░████████╗██╗░░██╗██████╗░███████╗██╗░░░██╗ 18 | ██╔══██╗██║██╔══██╗╚══██╔══╝██║░░██║██╔══██╗██╔════╝██║░░░██║ 19 | ██████╔╝██║██║░░██║░░░██║░░░███████║██║░░██║█████╗░░╚██╗░██╔╝ 20 | ██╔══██╗██║██║░░██║░░░██║░░░██╔══██║██║░░██║██╔══╝░░░╚████╔╝░ 21 | ██║░░██║██║╚█████╔╝░░░██║░░░██║░░██║██████╔╝███████╗░░╚██╔╝░░ 22 | ╚═╝░░╚═╝╚═╝░╚════╝░░░░╚═╝░░░╚═╝░░╚═╝╚═════╝░╚══════╝░░░╚═╝░░░ 23 | """ 24 | 25 | class sizes: 26 | def __init__(self, width, height): 27 | self.Width = int(width) 28 | self.Height = int(height) 29 | 30 | frame_count = 1 31 | 32 | cap = None 33 | 34 | def main(): 35 | os.system("title Bad apple") 36 | 37 | print(colorama.Fore.CYAN + TITLE + colorama.Fore.RESET) 38 | 39 | def get_size() -> int: 40 | screen_sizes = [m for m in screeninfo.get_monitors()] 41 | monitor = 1 42 | 43 | if len(screen_sizes) > 1: monitor = input(colorama.Fore.BLUE + "> Monitor (1 - {}) : ".format(len(screen_sizes)) + colorama.Fore.CYAN) 44 | 45 | return math.floor(screen_sizes[(int(monitor) - 1)].height / 5.5), math.floor(screen_sizes[(int(monitor) - 1)].width / 10) 46 | 47 | ask_size = input(colorama.Fore.BLUE + "> Use screen sizes? (Y / N) : " + colorama.Fore.CYAN) 48 | 49 | if ask_size.lower() == "y": 50 | monitor_height, monitor_width = get_size() 51 | else: 52 | monitor_height, monitor_width = int(input(colorama.Fore.BLUE + "> Height (190) : " + colorama.Fore.CYAN)), int(input(colorama.Fore.BLUE + "> Width (160) : " + colorama.Fore.CYAN)) 53 | 54 | def play_music(song) -> None: 55 | pygame.mixer.init() 56 | pygame.mixer.music.load(f"Assets/{song}") 57 | pygame.mixer.music.set_volume(1) 58 | pygame.mixer.music.play() 59 | 60 | def play_video(total_frames) -> None: 61 | print(colorama.Fore.YELLOW + "Starting..." + colorama.Fore.RESET) 62 | os.system("cls") 63 | 64 | timer = fpstimer.FPSTimer(30) 65 | play_music("Song.mp3") 66 | 67 | for frame in range(0, total_frames): 68 | try: 69 | #sys.stdout.write("\n\n\n\n") 70 | sys.stdout.write("\r" + ASCII_IMAGES[frame]) 71 | sys.stdout.flush() 72 | 73 | except Exception as error: 74 | print(error) 75 | 76 | timer.sleep() 77 | 78 | def load_frames(total_frames) -> None: 79 | global frame_count 80 | global ASCII_IMAGES 81 | global cap 82 | 83 | print(colorama.Fore.YELLOW + "Loading frames..." + colorama.Fore.RESET) 84 | r, frm = cap.read() 85 | 86 | while r and frame_count <= total_frames: 87 | r, frm = cap.read() 88 | frame_count += 1 89 | 90 | try: 91 | img = Image.fromarray(frm) 92 | ASCII_img = transform(img) 93 | ASCII_IMAGES.append(ASCII_img) 94 | 95 | except Exception as error: 96 | continue 97 | 98 | cap.release() 99 | play_video(frame_count) 100 | 101 | def get_frames(path) -> None: 102 | check_cap = cv2.VideoCapture(path) 103 | total_frames = int(check_cap.get(cv2.CAP_PROP_FRAME_COUNT)) 104 | 105 | check_cap.release() 106 | 107 | fpp = total_frames - 1 108 | load_frames(fpp) 109 | 110 | def load_video(vid) -> None: 111 | global cap 112 | cap = cv2.VideoCapture(f"Assets/{vid}") 113 | get_frames(f"Assets/{vid}") 114 | 115 | def transform(img) -> str: 116 | global main_sizes 117 | 118 | old_width, old_height = img.size 119 | old_sizes = sizes(old_width, old_height) 120 | 121 | ratio = (old_sizes.Height / float(old_sizes.Width * 2.5)) 122 | 123 | new_sizes = sizes(monitor_width, math.floor((ratio * monitor_height))) 124 | #print(math.floor((ratio * float(monitorSizes.height / 5.6)))) 125 | 126 | img = img.resize((new_sizes.Width, new_sizes.Height)) 127 | img = img.convert("L") 128 | 129 | pixels = img.getdata() 130 | 131 | new_pixels = "".join([ASCII_CHARS[pixel // 25] for pixel in pixels]) 132 | pixels_len = len(new_pixels) 133 | 134 | ASCII_Image = [new_pixels[index:(index + new_sizes.Width)] for index in range(0, pixels_len, new_sizes.Width)] 135 | ASCII_Image = "\n".join(x for x in ASCII_Image) 136 | 137 | return ASCII_Image 138 | 139 | load_video("Video.mp4") 140 | 141 | if __name__ == "__main__": 142 | try: 143 | main() 144 | except Exception as error: 145 | print(traceback.format_exc()) 146 | input("") 147 | sys.exit(-1) 148 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Bad apple 2 | 3 | A practice project that I did in python with the simple intention of understanding more about ASCII art 4 | 5 | > pip install -r requirements.txt 6 | 7 | **❗ This code was designed to work only on my PC, so it may not work correctly on your PC and you will have to modify a couple of things to be able to use it correctly, sorry...** 8 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | fpstimer 2 | opencv-python 3 | Pillow 4 | screeninfo 5 | pygame --pre 6 | colorama 7 | --------------------------------------------------------------------------------