Reputation: 35
I want to re-convert a binary equivalent file which contains "1"s and "0"s back to its JPG format (or convert it back to binary)
i.e i have a file which contains all 1's and 0's which i converted from a jpg image using the following function
def convert_binary(inpath, outpath):
byte2str = ["{:08b}".format(i) for i in range(256)]
with open(inpath, "rb") as fin:
with open(outpath, "w") as fout:
data = fin.read(1024)
while data:
for b in map(ord, data):
fout.write(byte2str[b])
data = fin.read(1024)
convert_binary("image.jpg", "binary_file.txt")
thanks to Tim Peters
I now want to convert this back (1's and 0's) back to its original image, any help would be grateful.
P.S: I am really sorry for such trivial questions, i am a biotechnology major and python programming is not my forte. I am experimenting with an app for my thesis and have got stuck.
Upvotes: 0
Views: 892
Reputation: 279245
You can reverse x = byte2str[b]
with int(x,2)
and you can reverse ord
with chr
. Your .txt
file contains 8 characters for each byte of the original jpg. So your code should look like:
data = fin.read(1024)
while data:
for i in range(0, len(data), 8):
fout.write(chr(int(data[i:i+8], 2)))
data = fin.read(1024)
Unfortunately read
isn't guaranteed to return exactly the number of bytes you ask for, it's allowed to return fewer. So we need to complicate things:
data = fin.read(1024)
while data:
if len(data) % 8 != 0:
# partial read
endidx = len(data) - len(data) % 8
leftover = data[endidx:]
data = data[:endidx]
if len(data) == 0:
raise ValueError('invalid file, length is not a multiple of 8')
for i in range(0, len(data), 8):
fout.write(chr(int(data[i:i+8], 2)))
data = leftover + fin.read(1024)
There are much better ways to represent a binary file as text though, for example base64 encoding.
Upvotes: 0
Reputation: 142136
Along the same vein as Steve's answer:
with open('input', 'rb', 1024) as fin, open('output', 'wb') as fout:
fout.writelines(chr(int(chunk, 2)) for chunk in iter(lambda: fin.read(8), ''))
Upvotes: 1