diff --git a/PIL/Image.py b/PIL/Image.py index 839700a0fb3..7c95b18f161 100644 --- a/PIL/Image.py +++ b/PIL/Image.py @@ -246,7 +246,7 @@ def isImageType(t): _MODE_CONV = { # official modes - "1": ('|b1', None), # broken + "1": ('|b1', None), # Bits need to be extended to bytes "L": ('|u1', None), "LA": ('|u1', 2), "I": (_ENDIAN + 'i4', None), @@ -615,17 +615,21 @@ def _repr_png_(self): self.save(b, 'PNG') return b.getvalue() - def __getattr__(self, name): - if name == "__array_interface__": - # numpy array interface support - new = {} - shape, typestr = _conv_type_shape(self) - new['shape'] = shape - new['typestr'] = typestr + @property + def __array_interface__(self): + # numpy array interface support + new = {} + shape, typestr = _conv_type_shape(self) + new['shape'] = shape + new['typestr'] = typestr + new['version'] = 3 + if self.mode == '1': + # Binary images need to be extended from bits to bytes + # See: https://github.com/python-pillow/Pillow/issues/350 + new['data'] = self.tobytes('raw', 'L') + else: new['data'] = self.tobytes() - new['version'] = 3 - return new - raise AttributeError(name) + return new def __getstate__(self): return [ diff --git a/Tests/test_image_array.py b/Tests/test_image_array.py index e17e6c2e5f2..0d9bf626d69 100644 --- a/Tests/test_image_array.py +++ b/Tests/test_image_array.py @@ -25,13 +25,26 @@ def test(mode): self.assertEqual(test("RGBX"), (3, (100, 128, 4), '|u1', 51200)) def test_fromarray(self): + + class Wrapper(object): + """ Class with API matching Image.fromarray """ + + def __init__(self, img, arr_params): + self.img = img + self.__array_interface__ = arr_params + + def tobytes(self): + return self.img.tobytes() + def test(mode): i = im.convert(mode) a = i.__array_interface__ - a["strides"] = 1 # pretend it's non-contiguous - i.__array_interface__ = a # patch in new version of attribute - out = Image.fromarray(i) + a["strides"] = 1 # pretend it's non-contigous + # Make wrapper instance for image, new array interface + wrapped = Wrapper(i, a) + out = Image.fromarray(wrapped) return out.mode, out.size, list(i.getdata()) == list(out.getdata()) + # self.assertEqual(test("1"), ("1", (128, 100), True)) self.assertEqual(test("L"), ("L", (128, 100), True)) self.assertEqual(test("I"), ("I", (128, 100), True)) diff --git a/Tests/test_numpy.py b/Tests/test_numpy.py index 40b7c64e355..076e71b42d3 100644 --- a/Tests/test_numpy.py +++ b/Tests/test_numpy.py @@ -117,6 +117,15 @@ def test_16bit(self): self._test_img_equals_nparray(img, np_img) self.assertEqual(np_img.dtype, numpy.dtype('