Skip to content

Commit 9973722

Browse files
committed
Only deprecate fromarray mode for changing data types
1 parent 44a553a commit 9973722

File tree

2 files changed

+49
-46
lines changed

2 files changed

+49
-46
lines changed

Tests/test_image_array.py

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -101,9 +101,8 @@ def __init__(self, arr_params: dict[str, Any]) -> None:
101101
self.__array_interface__ = arr_params
102102

103103
with pytest.raises(ValueError):
104-
wrapped = Wrapper({"shape": (1, 1), "strides": (1, 1)})
105-
with pytest.warns(DeprecationWarning, match="'mode' parameter"):
106-
Image.fromarray(wrapped, "L")
104+
wrapped = Wrapper({"shape": (1, 1), "strides": (1, 1), "typestr": "|u1"})
105+
Image.fromarray(wrapped, "L")
107106

108107

109108
def test_fromarray_palette() -> None:
@@ -112,9 +111,16 @@ def test_fromarray_palette() -> None:
112111
a = numpy.array(i)
113112

114113
# Act
115-
with pytest.warns(DeprecationWarning, match="'mode' parameter"):
116-
out = Image.fromarray(a, "P")
114+
out = Image.fromarray(a, "P")
117115

118116
# Assert that the Python and C palettes match
119117
assert out.palette is not None
120118
assert len(out.palette.colors) == len(out.im.getpalette()) / 3
119+
120+
121+
def test_deprecation() -> None:
122+
a = numpy.array(im.convert("L"))
123+
with pytest.warns(
124+
DeprecationWarning, match="'mode' parameter for changing data types"
125+
):
126+
Image.fromarray(a, "1")

src/PIL/Image.py

Lines changed: 38 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -3251,19 +3251,9 @@ def fromarray(obj: SupportsArrayInterface, mode: str | None = None) -> Image:
32513251
transferred. This means that P and PA mode images will lose their palette.
32523252
32533253
:param obj: Object with array interface
3254-
:param mode: Optional mode to use when reading ``obj``. Will be determined from
3255-
type if ``None``. Deprecated.
3256-
3257-
This will not be used to convert the data after reading, but will be used to
3258-
change how the data is read::
3259-
3260-
from PIL import Image
3261-
import numpy as np
3262-
a = np.full((1, 1), 300)
3263-
im = Image.fromarray(a, mode="L")
3264-
im.getpixel((0, 0)) # 44
3265-
im = Image.fromarray(a, mode="RGB")
3266-
im.getpixel((0, 0)) # (44, 1, 0)
3254+
:param mode: Optional mode to use when reading ``obj``. Since pixel values do not
3255+
contain information about palettes or color spaces, this can be used to place
3256+
grayscale L mode data within a P mode image, or read RGB data as YCbCr.
32673257
32683258
See: :ref:`concept-modes` for general information about modes.
32693259
:returns: An image object.
@@ -3274,21 +3264,28 @@ def fromarray(obj: SupportsArrayInterface, mode: str | None = None) -> Image:
32743264
shape = arr["shape"]
32753265
ndim = len(shape)
32763266
strides = arr.get("strides", None)
3277-
if mode is None:
3278-
try:
3279-
typekey = (1, 1) + shape[2:], arr["typestr"]
3280-
except KeyError as e:
3267+
try:
3268+
typekey = (1, 1) + shape[2:], arr["typestr"]
3269+
except KeyError as e:
3270+
if mode is not None:
3271+
typekey = None
3272+
color_modes: list[str] = []
3273+
else:
32813274
msg = "Cannot handle this data type"
32823275
raise TypeError(msg) from e
3276+
if typekey is not None:
32833277
try:
3284-
mode, rawmode = _fromarray_typemap[typekey]
3278+
typemode, rawmode, color_modes = _fromarray_typemap[typekey]
32853279
except KeyError as e:
32863280
typekey_shape, typestr = typekey
32873281
msg = f"Cannot handle this data type: {typekey_shape}, {typestr}"
32883282
raise TypeError(msg) from e
3289-
else:
3290-
deprecate("'mode' parameter", 13)
3283+
if mode is not None:
3284+
if mode != typemode and mode not in color_modes:
3285+
deprecate("'mode' parameter for changing data types", 13)
32913286
rawmode = mode
3287+
else:
3288+
mode = typemode
32923289
if mode in ["1", "L", "I", "P", "F"]:
32933290
ndmax = 2
32943291
elif mode == "RGB":
@@ -3385,29 +3382,29 @@ def fromqpixmap(im: ImageQt.QPixmap) -> ImageFile.ImageFile:
33853382

33863383

33873384
_fromarray_typemap = {
3388-
# (shape, typestr) => mode, rawmode
3385+
# (shape, typestr) => mode, rawmode, color modes
33893386
# first two members of shape are set to one
3390-
((1, 1), "|b1"): ("1", "1;8"),
3391-
((1, 1), "|u1"): ("L", "L"),
3392-
((1, 1), "|i1"): ("I", "I;8"),
3393-
((1, 1), "<u2"): ("I", "I;16"),
3394-
((1, 1), ">u2"): ("I", "I;16B"),
3395-
((1, 1), "<i2"): ("I", "I;16S"),
3396-
((1, 1), ">i2"): ("I", "I;16BS"),
3397-
((1, 1), "<u4"): ("I", "I;32"),
3398-
((1, 1), ">u4"): ("I", "I;32B"),
3399-
((1, 1), "<i4"): ("I", "I;32S"),
3400-
((1, 1), ">i4"): ("I", "I;32BS"),
3401-
((1, 1), "<f4"): ("F", "F;32F"),
3402-
((1, 1), ">f4"): ("F", "F;32BF"),
3403-
((1, 1), "<f8"): ("F", "F;64F"),
3404-
((1, 1), ">f8"): ("F", "F;64BF"),
3405-
((1, 1, 2), "|u1"): ("LA", "LA"),
3406-
((1, 1, 3), "|u1"): ("RGB", "RGB"),
3407-
((1, 1, 4), "|u1"): ("RGBA", "RGBA"),
3387+
((1, 1), "|b1"): ("1", "1;8", []),
3388+
((1, 1), "|u1"): ("L", "L", ["P"]),
3389+
((1, 1), "|i1"): ("I", "I;8", []),
3390+
((1, 1), "<u2"): ("I", "I;16", []),
3391+
((1, 1), ">u2"): ("I", "I;16B", []),
3392+
((1, 1), "<i2"): ("I", "I;16S", []),
3393+
((1, 1), ">i2"): ("I", "I;16BS", []),
3394+
((1, 1), "<u4"): ("I", "I;32", []),
3395+
((1, 1), ">u4"): ("I", "I;32B", []),
3396+
((1, 1), "<i4"): ("I", "I;32S", []),
3397+
((1, 1), ">i4"): ("I", "I;32BS", []),
3398+
((1, 1), "<f4"): ("F", "F;32F", []),
3399+
((1, 1), ">f4"): ("F", "F;32BF", []),
3400+
((1, 1), "<f8"): ("F", "F;64F", []),
3401+
((1, 1), ">f8"): ("F", "F;64BF", []),
3402+
((1, 1, 2), "|u1"): ("LA", "LA", ["La", "PA"]),
3403+
((1, 1, 3), "|u1"): ("RGB", "RGB", ["YCbCr", "LAB", "HSV"]),
3404+
((1, 1, 4), "|u1"): ("RGBA", "RGBA", ["RGBa"]),
34083405
# shortcuts:
3409-
((1, 1), f"{_ENDIAN}i4"): ("I", "I"),
3410-
((1, 1), f"{_ENDIAN}f4"): ("F", "F"),
3406+
((1, 1), f"{_ENDIAN}i4"): ("I", "I", []),
3407+
((1, 1), f"{_ENDIAN}f4"): ("F", "F", []),
34113408
}
34123409

34133410

0 commit comments

Comments
 (0)