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)




[row,col]which means[y,x]ary[1:51, 1:100] = True[y,x]then it gives me correct image. When I run with[x,y]then it gives me also correct image but rotated 90 degrees. You have to do something else and it makes problem. OR problem is in different place.img.show()to display it.