Dimansel
Dimansel

Reputation: 451

PIL's Image.frombuffer creates wrong image

I'm trying to create an image from 1d numpy array of integers so that changes to this array reflects in the image. It seems that Image.frombuffer perfectly fits my needs. There's my attempts:

from PIL import Image
import numpy as np

data = np.full(100, 255, dtype = np.int32)
img = Image.frombuffer('RGB', (10, 10), data)
print(list(img.getdata()))

I expected to see a list of 100 tuples (0, 0, 255). But what I'm actually getting is (0, 0, 255), (0, 0, 0), (0, 0, 0), (0, 255, 0), (0, 0, 0), (0, 0, 0), (255, 0, 0), (0, 0, 0), (0, 0, 255), (0, 0, 0), (255, 0, 0), ...

What is the reason of that behavior?

Upvotes: 0

Views: 1565

Answers (1)

Warren Weckesser
Warren Weckesser

Reputation: 114976

'RGB' uses three bytes per pixel. The buffer that you provided is an array with data type numpy.int32, which uses four bytes per element. So you have a mismatch.

One way to handle it is to use mode 'RGBA':

img = Image.frombuffer('RGBA', (10, 10), data)

Whether or not that is a good solution depends on what you are going to do with the image.

Also note that whether you get (255, 0, 0, 0) or (0, 0, 0, 255) for the RGBA pixels depends on the endianess of the integers in data.

For an RGB image, here's an alternative:

data = np.zeros(300, dtype=np.uint8)
# Set the blue channel to 255.
data[2::3] = 255
img = Image.frombuffer('RGB', (10, 10), data)

Without more context for the problem, I don't know if that is useful for you.

Upvotes: 1

Related Questions