Bartosz Woźniak
Bartosz Woźniak

Reputation: 2135

Creating an image from single bits in Python 3

I have created an array of bits by using this:

Data = []
Bytes = numpy.fromfile(filename, dtype = "uint8")
Bits = numpy.unpackbits(Bytes)
for b in Bits:
    Data.append(b)

"filename" ends with ".png".

Later on, I do some stuff with these bits. I want to save an image with another(or the same) set of bits. How do I do it? The best option would be using: saveToPNG(Data)

Upvotes: 1

Views: 2477

Answers (1)

PM 2Ring
PM 2Ring

Reputation: 55469

You can save those bits as a PNG file by simply reversing the steps you've used.

BTW, there's no need to create the Data list: you can access the bits in the Bits array with normal Python functions & operators as well as with Numpy. But if you really do want those bits in a plain Python list then there's no need for that slow for ... append loop: just pass the array to the list constructor.

I've changed your variable names to make them conform to the PEP-8 style guide.

import numpy as np

# File names
in_name = 'square.png'
out_name = 'square_out.png'

# Read data and convert to a list of bits
in_bytes = np.fromfile(in_name, dtype = "uint8")
in_bits = np.unpackbits(in_bytes)
data = list(in_bits)

# Convert the list of bits back to bytes and save
out_bits = np.array(data)
print(np.all(out_bits == in_bits))
out_bytes = np.packbits(out_bits)
print(np.all(out_bytes == in_bytes))
out_bytes.tofile(out_name)

However, I don't know why you want to do this. If you want access to the image data in the PNG file then you need to decode it properly. A simple way to do that is to use PIL (Pillow) to load the image file into a PIL Image object; Numpy can make an array from a PIL Image. You can then use standard Numpy tools to analyze or manipulate the raw image data, and then pass it back to PIL to save it as a PNG (or various other image file formats). See the final code block in this answer for an example.

Upvotes: 1

Related Questions