Skip to content

Commit f3ca268

Browse files
Merge pull request #1724 from aryanrai2001/Custom-CharRamps-For-PhotoToASCII
Add Character Sequence Selection in Photo To ASCII
2 parents d903ac0 + c752886 commit f3ca268

File tree

1 file changed

+54
-12
lines changed

1 file changed

+54
-12
lines changed

Photo To Ascii/photo_to_ascii.py

Lines changed: 54 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,61 +1,103 @@
11
from PIL import Image, ImageEnhance
22

33
# ASCII characters used to build the output text
4-
CHARS = "00011111..."
4+
char_ramp = []
5+
6+
# Choose character sequence for mapping
7+
def set_char_ramp():
8+
global char_ramp
9+
print("Choose a Character Sequence!")
10+
print("1 - Basic")
11+
print("2 - Standard (Short)")
12+
print("3 - Standard (Long)")
13+
print("4 - Unicode Blocks")
14+
print("5 - Unicode Shades")
15+
print("6 - Enter Custom Sequence")
16+
choice = input("Input: ")
17+
18+
try:
19+
choice = int(choice)
20+
except Exception:
21+
print("Invalid Input!")
22+
exit()
23+
24+
if choice == 1:
25+
char_ramp = list("00011111...")
26+
elif choice == 2:
27+
char_ramp = list("@%#*+=-:. ")
28+
elif choice == 3:
29+
char_ramp = list("$@B%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/\\|()1}{[]?-_+~<>i!lI;:,\"^`'. ")
30+
elif choice == 4:
31+
char_ramp = ["█", "▉", "▊", "▋", "▌", "▍", "▎", "▏"]
32+
elif choice == 5:
33+
char_ramp = ["█", "▓", "▒", "░", " "]
34+
elif choice == 6:
35+
custom_ramp = input("Enter your Character Sequence from High density to Low: ")
36+
if len(custom_ramp) == 0:
37+
print("Invalid Input!")
38+
exit()
39+
char_ramp = list(custom_ramp)
40+
else:
41+
print("Invalid Input!")
42+
exit()
43+
544

645
# Convert pixels to a string of ASCII characters
746
def pixels_to_ascii(image, contrast_factor):
847
image = image.convert("L")
948
enhancer = ImageEnhance.Contrast(image)
1049
image = enhancer.enhance(contrast_factor)
1150
pixels = image.getdata()
12-
characters = " ".join([CHARS[int((pixel/256)*len(CHARS))] for pixel in pixels])
51+
characters = " ".join([char_ramp[int((pixel/256)*len(char_ramp))] for pixel in pixels])
1352
return(characters)
1453

54+
# Driver function
1555
def photoascii():
1656
# Attempt to open image file from user-input
1757
path = input("Enter a valid pathname to an image:\n")
1858
try:
1959
image = Image.open(path)
2060
except Exception:
2161
print("Invalid Path!")
22-
return
62+
exit()
2363

2464
contrast_factor = input("Enter contrast factor (1 = Original Contrast) [Note: Enter negative value to invert output] : ")
2565
try:
2666
contrast_factor = float(contrast_factor)
2767
except Exception:
2868
print("Invalid Input!")
29-
return
30-
69+
exit()
70+
71+
set_char_ramp()
72+
3173
if contrast_factor < 0:
32-
global CHARS
33-
CHARS = CHARS[::-1]
74+
global char_ramp
75+
char_ramp.reverse()
3476
contrast_factor = -contrast_factor
35-
77+
3678
# Fetch the name of the image file
3779
dot_index = path.rfind('.')
3880
slash_index = path.rfind('\\')
3981
if slash_index == -1:
4082
slash_index = path.rfind('/')
4183
image_name = path[slash_index+1:dot_index] + "_" + path[dot_index+1:]
42-
84+
4385
# Resize image
4486
new_width = 100
4587
width, height = image.size
4688
ratio = height/width
4789
new_height = int(new_width * ratio)
4890
resized_image = image.resize((new_width, new_height))
49-
91+
5092
# Convert image to ASCII
5193
new_image_data = pixels_to_ascii(resized_image, contrast_factor)
5294
pixel_count = len(new_image_data)
5395
scanline_width = new_width * 2;
5496
ascii_image = "\n".join([new_image_data[index:(index+scanline_width)]
5597
for index in range(0, pixel_count, scanline_width)])
56-
98+
5799
# Save result to text file
58-
with open(path[:slash_index] + "/{}_ASCII.txt".format(image_name), "w") as f:
100+
with open(path[:slash_index] + "/{}_ASCII.txt".format(image_name), "w", encoding='utf8') as f:
59101
f.write(ascii_image)
60102

61103

0 commit comments

Comments
 (0)