Reputation: 1443
This turned out to be a very specific bug in a pre-7.0 version of PIL. I'm leaving it here because I've seen other hit the same issue and there isn't a good overview of what you see. There is no programming error here - the solution is "upgrade PIL"
I'm converting a numpy boolean array (ie, a mask) to a PIL
image, and seeing a very odd behaviour.
# using PIL pixel access - works as expected
img = Image.new('1', (100, 100)) # '1' for 1-bit image mode
img_pixels = img.load()
for x in range(1, 99):
for y in range(1, 50):
img_pixels[x,y] = True
img
# Numpy array, turning into a PIL image.
ary = np.zeros((100,100), dtype=np.bool)
for x in range(1, 99):
for y in range(1, 50):
ary[x,y] = True
Image.fromarray(ary)
If I inspect the values of ary
it appears the True
values are appropriately set.
So why are these images different?
Edit:
If I reverse x and y for the numpy version I get this. It's clear that something else is going on because if it was just rows and columns reversed I should get the same shape but vertically aligned.
ary = np.zeros((100,100), dtype=np.bool)
for x in range(1, 99):
for y in range(1, 50):
ary[y,x] = True # note that rows and columns are reversed
Image.fromarray(ary)
Upvotes: 2
Views: 1611
Reputation: 1443
This turned out to be a bug in an earlier version of PIL that was fixed by at least version 7.0
With
the behaviour is as expected. Thanks to @furas for his help testing.
Upvotes: 0
Reputation: 12417
PIL has reverse x
and y
locations. To fix it, exchange x
and y
in your code:
ary = np.zeros((100,100), dtype=np.bool)
for x in range(1, 99):
for y in range(1, 50):
ary[y,x] = True
Image.fromarray(ary)
Upvotes: 1