-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcompress.py
More file actions
168 lines (140 loc) · 4.92 KB
/
Copy pathcompress.py
File metadata and controls
168 lines (140 loc) · 4.92 KB
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
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
# BitArt Compressor/Decompressor
# By: Bardia Barahman
import re
import os
class Compression:
"""
This class contains the functions to encode/decode the bitmap images
"""
def encode_img(self, fileName):
"""
Function to encode the .txt file. Reads image from fileName and
compresses it into an encoded.txt file
"""
f = open(fileName, 'r')
lst = []
for x in f:
numSpaces = x.count(' ')
newStr = self.compress_string(x)
lst.append((numSpaces, newStr))
#write encoding bitmap into a new fileName
f = open("encoded.txt", "w+")
for i in range(len(lst)):
f.write(str(lst[i]))
f.close()
def compress_string(self, string):
"""
Helper function to eliminate consecutive repeated characters,
consecutive repeated spaces, and newline characters from a string
"""
compressed = ''
numSpaces = string.count(' ')
#Adding the first nonspace character
compressed += string[numSpaces]
count = 1
#Iterating through loop, skipping last char
for i in range(numSpaces, len(string)-1):
if (string[i] == string[i+1]):
count += 1
else:
if (count > 1):
compressed += str(count)
compressed += string[i+1]
count = 1
if(count>1):
compressed += str(count)
#convert to list to delete newline character at end
lst = list(compressed)
if (lst[-1] == '\n'):
del lst[-1]
str1 = "".join(lst)
return str1
def decode_img(self, fileName):
"""
Function to decode the .txt file
"""
e = open(fileName, 'r')
data = e.readline()
lst = self.get_tuples(data)
d = open('decoded.txt', "w+")
for x in lst:
#Writing the # of blank spaces into file
spaces = int(x[0]) *str(' ')
d.write(spaces)
#Writing the deocoded string followed by newline back into file
decode = self.decompress_string(x[1])
d.write(decode.strip('\'\"'))
d.write('\n')
def decompress_string(self, string):
"""
Helper function to recreate original string from compressed version
"""
decompressed = ''
for i in range(len(string)):
#accounting for two repeated digits
if (self.is_number(string[i-1])):
if (not self.is_number(string[i])):
decompressed += string[i]
else:
continue
else:
if (self.is_number(string[i])):
#check if its a two digit number
repeated = self.get_repeated(string[i:])
#subtracting one to account for number that was already counted
decompressed += string[i-1]* (int(repeated) - 1)
else:
decompressed += string[i]
return decompressed
def is_number(self, string):
"""
Check if a string is a number.
"""
try:
int(string)
return True
except ValueError:
return False
def get_repeated(self, string):
"""
Takes a string and returns the first occurence of how many times
a character is repeated, returned as a string
"""
regex = "[0-9]+"
output = re.search(regex, string)
return output.group()
def get_tuples(self, string):
"""
Takes a string from an encoded file and returns a list of tuples
"""
regex = "\((\d*),\s([^\)]*)\)?"
output = re.findall(regex, string)
return list(output)
#Main Function
if __name__ == '__main__':
obj = Compression()
while True:
data = input("Would you like to encode or decode your image? (e/d)\n")
if data not in ('e', 'E', 'd', 'D'):
print("\nSorry, please enter a valid option.")
print("------------\n")
continue
else:
break
bitImg = 'data.txt'
if data in ('e', 'E'):
try:
orig_size = int(os.stat(bitImg).st_size)
obj.encode_img(bitImg)
new_size = int(os.stat('encoded.txt').st_size)
reduced = ((orig_size-new_size)/orig_size)*100
print("\nSuccess! Encoded image located in 'encoded.txt'.")
print("Reduced file size by "+str(round(reduced, 2))+"%")
except:
print("\nUnable to encode image. Please make sure there exists a valid 'data.txt' file.")
if data in ('d', 'D'):
try:
obj.decode_img('encoded.txt')
print("\nSuccessfully decoded image. Located under 'decoded.txt' in this directory.")
except:
print("\nError, unable to decode image.")