-
Notifications
You must be signed in to change notification settings - Fork 0
/
img_to_ascii.py
93 lines (67 loc) · 2.54 KB
/
img_to_ascii.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
import os
from collections import Counter
from io import BytesIO
from pprint import pprint
import requests
from PIL import Image
def img_to_ascii(location, symbols, max_width=100):
"""
location: str
filepath or url to image
max_width: int
an int that decides how many characters are allowed
in the width and shrinks the image accordingly
returns a list of rows of characters like this:
[
[' ', '░','▒', '▓', '█'],
[' ', '░','▒', '▓', '█'],
[' ', '░','▒', '▓', '█'],
]
"""
# reading image
# if the location exists on the system, use it. else, try to find it online.
if os.path.exists(location):
img = Image.open(location)
else:
response = requests.get(location)
img = Image.open(BytesIO(response.content))
width, height = img.size
aspect_ratio = max_width/width
# resizing image based on compression factor. -2 because of new line characters
img = img.resize((int(width*aspect_ratio-2), int(((height*aspect_ratio)-2)*.45)))
width, height = img.size
# converting to black and white
img_bw = img.convert('L')
# img_bw.show()
# sorting the image into rows of pixels
pixels = list(img_bw.getdata())
rows = [pixels[h*width:(h+1)*width] for h in range(height)]
ascii_img = []
for row in rows:
# getting the symbol for the light value from symbols dict
row_values = [int((value/255)*(len(symbols)-1)) for value in row]
ascii_img.append([symbols[v] for v in row_values])
return ascii_img
if __name__ == "__main__":
import argparse
from time import sleep
parser = argparse.ArgumentParser()
parser.add_argument('location', help="filepath or url to an image")
parser.add_argument('-w', '--width', help="How many characters wide the output will be. (including new line characters)")
parser.add_argument('-b', '--blocks', help="makes the characterset use unicode shade blocks", action='store_true')
args = parser.parse_args()
if args.blocks:
characters = [' ', '░','▒', '▓', '█']
else:
characters = [ ' ', '.', ':', '-', '=', '+', '*', '#', '%', '@' ]
if args.width:
max_width = int(args.width)
else:
max_width = 100
ascii_img = img_to_ascii(args.location, characters, max_width=max_width)
# joining all the symbols together to be printed
for row in ascii_img:
line = ''.join(row)
# print(line, file=f)
print(line)
sleep(0.01)