-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathThe PNG Musician.py
128 lines (98 loc) · 6.8 KB
/
The PNG Musician.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
import os
import cv2
import numpy as np
from os import listdir
from tqdm import trange
import subprocess
import msvcrt
def parse_stegano_or(arr: np.array):
arr = np.reshape(arr, (1, W * H * D))
sp = np.where(arr != 0)[1][0]
bits = W * H * D - sp
mp3 = []
for b in trange(0, bits, 4, ncols=100, unit=' bytes'):
mp3.append((arr[0, sp+b+0] << 6) | (arr[0, sp+b+1] << 4) | (arr[0, sp+b+2] << 2) | (arr[0, sp+b+3] << 0))
return bytes(mp3)
def print_ascii_image(img: np.array, norm=False):
LEVELS = [' ', '░░', '▒▒', '▓▓', '██']
if norm:
img = np.array(np.array(img / img.max(), dtype=np.float) * 4, dtype=np.uint8)
else:
img //= 63
borderW = img.shape[1] * 2
print(" ╔" + "╦" * borderW + "╗")
for row in img:
print(end=' ╠')
for pixel in row:
print(LEVELS[pixel], end='')
print('╣')
print(" ╚" + "╩" * borderW + "╝")
if __name__ == '__main__':
while True:
SECTION_SEPERATOR = '\n' + '-' * 200 + '\n'
LOGO = """
████████╗██╗ ██╗███████╗ ██████╗ ███╗ ██╗ ██████╗ ███╗ ███╗██╗ ██╗███████╗██╗ ██████╗██╗ █████╗ ███╗ ██╗
╚══██╔══╝██║ ██║██╔════╝ ██╔══██╗████╗ ██║██╔════╝ ████╗ ████║██║ ██║██╔════╝██║██╔════╝██║██╔══██╗████╗ ██║
██║ ███████║█████╗ ██████╔╝██╔██╗ ██║██║ ███╗ ██╔████╔██║██║ ██║███████╗██║██║ ██║███████║██╔██╗ ██║
██║ ██╔══██║██╔══╝ ██╔═══╝ ██║╚██╗██║██║ ██║ ██║╚██╔╝██║██║ ██║╚════██║██║██║ ██║██╔══██║██║╚██╗██║
██║ ██║ ██║███████╗ ██║ ██║ ╚████║╚██████╔╝ ██║ ╚═╝ ██║╚██████╔╝███████║██║╚██████╗██║██║ ██║██║ ╚████║
╚═╝ ╚═╝ ╚═╝╚══════╝ ╚═╝ ╚═╝ ╚═══╝ ╚═════╝ ╚═╝ ╚═╝ ╚═════╝ ╚══════╝╚═╝ ╚═════╝╚═╝╚═╝ ╚═╝╚═╝ ╚═══╝
█▀▄ █ █ █▀▀ █▀█ █▀▀ █▀█ █▀▄ █▀▄ █▀▀ █ █ █▀█ █▀▀ █ █ █▀█ █▀▄
█▀▄ █ ▀▀█ █▀█ █ █ █▀█ █▀▄ █ █ █▀▀ ▀▄▀ █▀█ █ █▀█ █▀█ █▀▄
▀▀ ▀ ▀▀▀ ▀ ▀ ▀▀▀ ▀ ▀ ▀ ▀ ▀▀ ▀▀▀ ▀ ▀ ▀ ▀▀▀ ▀ ▀ ▀ ▀ ▀ ▀
""" + SECTION_SEPERATOR
print(LOGO)
print("Hey There!\nI'm THE PNG MUSICIAN!")
print("I convert PNG Images to MP3 Audio and play them!")
print("\nWell that's not exactly how I work, but it's one way to put it :P")
print("\nAnyways, maximize this window for the best experience ;)")
print(SECTION_SEPERATOR)
try:
file_list = listdir('SRC')
png_file_list = []
for filename in file_list:
if filename[-4:] == '.png':
png_file_list.append(filename)
print("I found %d PNG files!\nWhich one do you want me to play?" % len(png_file_list))
for png_file in png_file_list:
print(f'\t{png_file_list.index(png_file)+1:2d}) {png_file:s}')
file_index = -1
while True:
try:
file_index = int(input('\nEnter an image number: ').strip())
if 0 < file_index <= len(png_file_list):
file_index -= 1
break
else:
raise ValueError
except Exception:
print("Hmmm, that's not quite what I expected. How about you give it another try!")
SONG_NAME = png_file_list[file_index]
print(SECTION_SEPERATOR)
print("Reading Image...")
STEGANO_IMAGE = cv2.imread(fr'SRC\{SONG_NAME:s}', cv2.IMREAD_COLOR)
H, W, D = STEGANO_IMAGE.shape
print("Creating Music from the Image...")
MP3_DATA = parse_stegano_or(STEGANO_IMAGE & 0x3)
print("Writing Music to out.mp3...")
with open('out.mp3', 'wb') as mp3_file:
mp3_file.write(MP3_DATA)
print(SECTION_SEPERATOR)
print("{:^200s}".format(f"Currently Playing {SONG_NAME}\n"))
ascii_image_w = (len(SECTION_SEPERATOR) - 6) // 2
ascii_image_h = ascii_image_w * 9 // 16
print_ascii_image(cv2.cvtColor(cv2.resize(STEGANO_IMAGE, (ascii_image_w, ascii_image_h)), cv2.COLOR_BGR2GRAY))
print('')
player_subprocess = subprocess.Popen(['bin/mpg123', '-q', 'out.mp3'])
print("{:^200s}".format('Press ENTER to stop playing the song'), end='')
while player_subprocess.poll() is None:
if msvcrt.kbhit():
if msvcrt.getch() == b'\r':
break
print("\r{:^200s}".format('Finished Playing!'))
player_subprocess.kill()
except FileNotFoundError:
print("Looks like you have lost the 'bin' or 'SRC' folder!\nUnfortunately, I cannot work without those...")
print(SECTION_SEPERATOR)
input("Press ENTER to start over")
os.system('cls')