Meet
Meet

Reputation: 35

Converting "1"s and "0"s to its binary equivalent to make a JPG

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

Answers (2)

Steve Jessop
Steve Jessop

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

Jon Clements
Jon Clements

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

Related Questions