-
Notifications
You must be signed in to change notification settings - Fork 0
/
img2braille.py
executable file
·136 lines (121 loc) · 5.08 KB
/
img2braille.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
129
130
131
132
133
134
135
136
#!/usr/bin/python
# vim:fileencoding=utf-8
import Image
"""img2braille module takes an imgae and converts it into braille text"""
def img2bin(img,sub_w =2, sub_h = 4):
"""Converts image data to a [x,y]list of 0s and 1s.
First it corrects the size of image data to multiple of braille char
width and height. Then black pixels will be set to 1, all other
pixels will be set to 0"""
img_w, img_h = img.size
fix_w = img_w
fix_h = img_h
#Correct the size of image
if img_w % sub_w: fix_w += sub_w - img_w % sub_w
if img_h % sub_h: fix_h += sub_h - img_h % sub_h
#Generate an empty output [X][Y] list of lists
output = [[0 for y in range(fix_h)] for x in range(fix_w)]
#Populate list with data from img
img_data = list(img.getdata())
for x in range(img_w):
for y in range(img_h):
index = img_w * y + x
output[x][y] = int(not bool(img_data[index]))
return output
def mapBraille(index):
"""Returns unicode Braille letter with index index"""
result = unichr(10240 + index)
return result
def bin2index(b_img, sub_w = 2, sub_h = 4):
"""Returns [x][y] list of integer values. b_img must have correct size!"""
result = []
b_img_w = len(b_img)
b_img_h = len(b_img[0])
new_w = b_img_w / sub_w
new_h = b_img_h / sub_h
output = [[0 for y in range(new_h)] for x in range(new_w)]
for y in range(new_h):
for x in range(new_w):
#For each position in selection get value
block = []
for sub_x in range(sub_w):
for sub_y in range(sub_h):
j = x * sub_w + sub_x
k = y * sub_h + sub_y
#Add to index = ?*2^n, 0 if empty
block.append(b_img[j][k])
output[x][y] = block2index(block)
return output
def block2index(block):
"""Converts one pixel block (2x4, but flattened by columns) to
its index(position of braille char).0 dots = 0; 8 dots = ff = 255
## <-- one braille character of 8 pixels
##
## 03 <-- order of bits in one char(positions)
## 14 this char comes as "01263457"
25 |° | <--this would be represented in binary as "01110101"
67 | °| this char comes as a list "1,0,1,1,0,1,1,0"
|°°| pos 0 = dot x 2^0 pos 4 = dot x 2^4
|° | pos 1 = empty x 2^1 pos 5 = dot x 2^5
pos 2 = dot x 2^2 pos 6 = dot x 2^6
pos 3 = empty x 2^3 pos 7 = empty x 2^7
= 1*1 + 0*2 + 1*4 + 0*8 + 1*16 + 1*32 + 1*64 + 0*128
= 117 = 117th unicode braille cahracter"""
index = 0
if block[0]: index += 1
if block[1]: index += 2
if block[2]: index += 4
if block[3]: index += 64
if block[4]: index += 8
if block[5]: index += 16
if block[6]: index += 32
if block[7]: index += 128
return index
def index2str(matrix, line_end = "\n"):
"""Returns string with braille, based on [x,y] matrix
of indexes."""
m_w = len(matrix)
m_h = len(matrix[0])
result = ""
for y in range(m_h):
for x in range(m_w):
result += mapBraille(matrix[x][y])
result += line_end
return result
def getBraille(in_file, encoding = "utf-8"):
"""Returns braille string, based on image in_file"""
try:
image = Image.open(in_file)
bw_image = image.convert("1") #Convert to BW(Black or White)
res_img2bin = img2bin(bw_image,2,4)
res_bin2index = bin2index(res_img2bin,2,4)
return index2str(res_bin2index,"\n").encode(encoding).strip()
except:
print("-ERROR- Problem opening image file:"+`in_file`)
def makeBraille(in_file,out_file = "braille_out.txt"):
"""Writes braille string based on image in_file to file out_file"""
braille = getBraille(in_file)
if not braille: print("\tNo braille, no write!");return False
try:
with open(out_file,"w") as file:
file.write(braille+"\n")
return "-SUCCESS- File "+`out_file`+" written to disk."
except:
error = ("-ERROR- Problem storing saving to file: "+`out_file`)
return False, error
def printHelp(scriptname = "img2braille.py"):
"""Print out help when not wrong arguments and other situations."""
helptext = "Script takes two arguments, argument one is "\
" input image filename, second argument is output filename.\n"\
"EXAMPLE use: "+scriptname+" image.gif text.txt"
print(helptext)
#Main program if run from command line
if __name__ == "__main__":
"""First argument is source image, second argument is output file"""
import sys
def_filename_out = "img2braille_default_output.txt"
if len(sys.argv) == 0: print("How did you get here?")
elif len(sys.argv) == 1: printHelp(sys.argv[0])
elif len(sys.argv) == 2: print(getBraille(sys.argv[1]))
elif len(sys.argv) == 3: makeBraille(sys.argv[1], sys.argv[2])
else: print("Error - too many arguments");printHelp(sys.argv[0])