Python 2.6: Creating image from array

2019-08-05 04:42发布

Python rookie here! So, I have a data file which stores a list of bytes, representing pixel values in an image. I know that the image is 3-by-3 pixels. Here's my code so far:

# Part 1: read the data
data = []
file = open("test.dat", "rb")
for i in range(0, 9)
    byte = file.read(1)
    data[i] = byte
file.close()

# Part2: create the image
image = PIL.Image.frombytes('L', (3, 3), data)
image.save('image.bmp')

I have a couple of questions:

In part 1, is this the best way to read a binary file and store the data in an array?

In part 2, I get the error "TypeError: must be string or read-only buffer, not list.

Any help on either of these?

Thank you!

1条回答
放荡不羁爱自由
2楼-- · 2019-08-05 05:03

Part 1

If you know that you need exactly nine bytes of data, that looks like a fine way to do it, though it would probably be cleaner/clearer to use a context manager and skip the explicit loop:

with open('test.dat', 'rb') as infile:
    data = list(infile.read(9)) # read nine bytes and convert to a list

Part 2

According to the documentation, the data you must pass to PIL.Image.frombytes is:

data – A byte buffer containing raw data for the given mode.

A list isn't a byte buffer, so you're probably wasting your time converting the input to a list. My guess is that if you pass it the byte string directly, you'll get what you're looking for. This is what I'd try:

with open('test.dat', 'rb') as infile:
    data = infile.read(9) # Don't convert the bytestring to a list
image = PIL.Image.frombytes('L', (3, 3), data) # pass in the bytestring
image.save('image.bmp')

Hopefully that helps; obviously I can't test it over here since I don't know what the content of your file is.

Of course, if you really need the bytes as a list for some other reason (doubtful--you can iterate over a string just as well as a list), you can always either convert them to a list when you need it (datalist = list(data)) or join them into a string when you make the call to PIL:

image = PIL.Image.frombytes('L', (3, 3), ''.join(datalist))

Part 3

This is sort of an aside, but it's likely to be relevant: do you know what version of PIL you're using? If you're using the actual, original Python Imaging Library, you may also be running into some of the many problems with that library--it's super buggy and unsupported since about 2009.

If you are, I highly recommend getting rid of it and grabbing the Pillow fork instead, which is the live, functional version. You don't have to change any code (it still installs a module called PIL), but the Pillow library is superior to the original PIL by leaps and bounds.

查看更多
登录 后发表回答