Question

Python PIL library has Image.getdata() method, which return raw image data, writing:

list(im.convert("1").getdata())

will return an array of bits. Each bit corresponds to one image pixel - pixel can only be black or white because of "1" mode.

I would like to have an array which size is 8 times smaller. Each array element contains one byte.

My questions are:

  • 1. Can I get such an array of bytes directly from PIL?
  • 2. If not, how to convert array of bits returned by PIL to smaller array of bytes?
Was it helpful?

Solution

I don't know a thing about PIL and I haven't used Python for some time, but here is my take at this bits to bytes conversion problem.

import itertools
# assuming that `bits` is your array of bits (0 or 1)
# ordered from LSB to MSB in consecutive bytes they represent
# e.g. bits = [0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1] will give you bytes = [128,255]
bytes = [sum([byte[b] << b for b in range(0,8)])
            for byte in zip(*(iter(bits),) * 8)
        ]
# warning! if len(bits) % 8 != 0, then these last bits will be lost

This code should be mostly self-explanatory.

OTHER TIPS

PIL's ImagingCore can easily be converted to bytes:

from PIL import Image


img = Image.open("python.jpg", "r")
data = img.convert("1").getdata()
bytes = bytearray(data)

This gives you a bytearray() list of bytes which can then be manipulated or written to a file. You could write this to a file by doing:

with open("filename", "w") as f:
    f.write(b"".join(map(bytes, data)))

I hope this helps!

It's probably worth noting too that Python in fact does not have a data type for bits. And that list(data) returns a list of int(s) and not "bits" as you thought?

Example:

>>> list(data)[:10]
[255, 255, 255, 255, 255, 255, 255, 255, 255, 255]
>>> set(list(data))
set([0, 255])
>>> set(map(type, list(data)))
set([<type 'int'>])

So in reality you are not saving any data by doing this.

See: http://docs.python.org/2/library/stdtypes.html for Python data types and operations. You can perform "bit" operations, but there is no "bit" data type.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top