From 1c03526b6527df9f2d206708ce16b721aad06538 Mon Sep 17 00:00:00 2001 From: Thomas Viehmann Date: Thu, 1 Jul 2021 13:09:40 +0200 Subject: [PATCH 1/3] Make Image.__array__ take optional dtype argument This is required by the numpy protocol. --- Tests/test_image_array.py | 7 +++++++ src/PIL/Image.py | 7 +++++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/Tests/test_image_array.py b/Tests/test_image_array.py index 4dbbdd218..c4e124ee5 100644 --- a/Tests/test_image_array.py +++ b/Tests/test_image_array.py @@ -14,6 +14,10 @@ def test_toarray(): ai = numpy.array(im.convert(mode)) return ai.shape, ai.dtype.str, ai.nbytes + def test_with_dtype(dtype): + ai = numpy.array(im, dtype=dtype) + assert ai.dtype == dtype + # assert test("1") == ((100, 128), '|b1', 1600)) assert test("L") == ((100, 128), "|u1", 12800) @@ -27,6 +31,9 @@ def test_toarray(): assert test("RGBA") == ((100, 128, 4), "|u1", 51200) assert test("RGBX") == ((100, 128, 4), "|u1", 51200) + test_with_dtype(numpy.float) + test_with_dtype(numpy.uint8) + with Image.open("Tests/images/truncated_jpeg.jpg") as im_truncated: with pytest.raises(OSError): numpy.array(im_truncated) diff --git a/src/PIL/Image.py b/src/PIL/Image.py index 9debddeec..98dfec726 100644 --- a/src/PIL/Image.py +++ b/src/PIL/Image.py @@ -681,7 +681,7 @@ class Image: raise ValueError("Could not save to PNG for display") from e return b.getvalue() - def __array__(self): + def __array__(self, dtype=None): # numpy array interface support import numpy as np @@ -700,7 +700,10 @@ class Image: class ArrayData: __array_interface__ = new - return np.array(ArrayData()) + arr = np.array(ArrayData()) + if dtype is not None: + arr = arr.astype(dtype) + return arr def __getstate__(self): return [self.info, self.mode, self.size, self.getpalette(), self.tobytes()] From 73f6cf22f345065ad0463fcdb2a41b213b000df4 Mon Sep 17 00:00:00 2001 From: Thomas Viehmann Date: Thu, 1 Jul 2021 14:06:13 +0200 Subject: [PATCH 2/3] Use numpy.float64 instead of numpy.float to avoid deprecation (thank you radarhere) --- Tests/test_image_array.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tests/test_image_array.py b/Tests/test_image_array.py index c4e124ee5..850dc2aaa 100644 --- a/Tests/test_image_array.py +++ b/Tests/test_image_array.py @@ -31,7 +31,7 @@ def test_toarray(): assert test("RGBA") == ((100, 128, 4), "|u1", 51200) assert test("RGBX") == ((100, 128, 4), "|u1", 51200) - test_with_dtype(numpy.float) + test_with_dtype(numpy.float64) test_with_dtype(numpy.uint8) with Image.open("Tests/images/truncated_jpeg.jpg") as im_truncated: From 8d1b433c76c8aea0416224e99f58782d793f5925 Mon Sep 17 00:00:00 2001 From: Thomas Viehmann Date: Thu, 1 Jul 2021 14:08:51 +0200 Subject: [PATCH 3/3] Use numpy.array with dtype Thank you @radarhere. Co-authored-by: Andrew Murray <3112309+radarhere@users.noreply.github.com> --- src/PIL/Image.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/PIL/Image.py b/src/PIL/Image.py index 98dfec726..6017882aa 100644 --- a/src/PIL/Image.py +++ b/src/PIL/Image.py @@ -700,10 +700,7 @@ class Image: class ArrayData: __array_interface__ = new - arr = np.array(ArrayData()) - if dtype is not None: - arr = arr.astype(dtype) - return arr + return np.array(ArrayData(), dtype) def __getstate__(self): return [self.info, self.mode, self.size, self.getpalette(), self.tobytes()]