mirror of
				https://github.com/python-pillow/Pillow.git
				synced 2025-11-04 01:47:47 +03:00 
			
		
		
		
	Only deprecate fromarray mode for changing data types (#9063)
This commit is contained in:
		
						commit
						ba04d58851
					
				| 
						 | 
				
			
			@ -101,9 +101,8 @@ def test_fromarray_strides_without_tobytes() -> None:
 | 
			
		|||
            self.__array_interface__ = arr_params
 | 
			
		||||
 | 
			
		||||
    with pytest.raises(ValueError):
 | 
			
		||||
        wrapped = Wrapper({"shape": (1, 1), "strides": (1, 1)})
 | 
			
		||||
        with pytest.warns(DeprecationWarning, match="'mode' parameter"):
 | 
			
		||||
            Image.fromarray(wrapped, "L")
 | 
			
		||||
        wrapped = Wrapper({"shape": (1, 1), "strides": (1, 1), "typestr": "|u1"})
 | 
			
		||||
        Image.fromarray(wrapped, "L")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def test_fromarray_palette() -> None:
 | 
			
		||||
| 
						 | 
				
			
			@ -112,9 +111,16 @@ def test_fromarray_palette() -> None:
 | 
			
		|||
    a = numpy.array(i)
 | 
			
		||||
 | 
			
		||||
    # Act
 | 
			
		||||
    with pytest.warns(DeprecationWarning, match="'mode' parameter"):
 | 
			
		||||
        out = Image.fromarray(a, "P")
 | 
			
		||||
    out = Image.fromarray(a, "P")
 | 
			
		||||
 | 
			
		||||
    # Assert that the Python and C palettes match
 | 
			
		||||
    assert out.palette is not None
 | 
			
		||||
    assert len(out.palette.colors) == len(out.im.getpalette()) / 3
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def test_deprecation() -> None:
 | 
			
		||||
    a = numpy.array(im.convert("L"))
 | 
			
		||||
    with pytest.warns(
 | 
			
		||||
        DeprecationWarning, match="'mode' parameter for changing data types"
 | 
			
		||||
    ):
 | 
			
		||||
        Image.fromarray(a, "1")
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -35,8 +35,12 @@ Image.fromarray mode parameter
 | 
			
		|||
 | 
			
		||||
.. deprecated:: 11.3.0
 | 
			
		||||
 | 
			
		||||
The ``mode`` parameter in :py:meth:`~PIL.Image.fromarray()` has been deprecated. The
 | 
			
		||||
mode can be automatically determined from the object's shape and type instead.
 | 
			
		||||
Using the ``mode`` parameter in :py:meth:`~PIL.Image.fromarray()` was deprecated in
 | 
			
		||||
Pillow 11.3.0. In Pillow 12.0.0, this was partially reverted, and it is now only
 | 
			
		||||
deprecated when changing data types. Since pixel values do not contain information
 | 
			
		||||
about palettes or color spaces, the parameter can still be used to place grayscale L
 | 
			
		||||
mode data within a P mode image, or read RGB data as YCbCr for example. If omitted, the
 | 
			
		||||
mode will be automatically determined from the object's shape and type.
 | 
			
		||||
 | 
			
		||||
Saving I mode images as PNG
 | 
			
		||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -29,6 +29,13 @@ Image.fromarray mode parameter
 | 
			
		|||
The ``mode`` parameter in :py:meth:`~PIL.Image.fromarray()` has been deprecated. The
 | 
			
		||||
mode can be automatically determined from the object's shape and type instead.
 | 
			
		||||
 | 
			
		||||
.. note::
 | 
			
		||||
 | 
			
		||||
    Since pixel values do not contain information about palettes or color spaces, part
 | 
			
		||||
    of this functionality was restored in Pillow 12.0.0. The parameter can be used to
 | 
			
		||||
    place grayscale L mode data within a P mode image, or read RGB data as YCbCr for
 | 
			
		||||
    example.
 | 
			
		||||
 | 
			
		||||
Saving I mode images as PNG
 | 
			
		||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -157,6 +157,15 @@ of 3.14.0 final (2025-10-07, :pep:`745`).
 | 
			
		|||
 | 
			
		||||
Pillow 12.0.0 now officially supports Python 3.14.
 | 
			
		||||
 | 
			
		||||
Image.fromarray mode parameter
 | 
			
		||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 | 
			
		||||
 | 
			
		||||
In Pillow 11.3.0, the ``mode`` parameter in :py:meth:`~PIL.Image.fromarray()` was
 | 
			
		||||
deprecated. Part of this functionality has been restored in Pillow 12.0.0. Since pixel
 | 
			
		||||
values do not contain information about palettes or color spaces, the parameter can be
 | 
			
		||||
used to place grayscale L mode data within a P mode image, or read RGB data as YCbCr
 | 
			
		||||
for example.
 | 
			
		||||
 | 
			
		||||
ImageMorph operations must have length 1
 | 
			
		||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3259,19 +3259,10 @@ def fromarray(obj: SupportsArrayInterface, mode: str | None = None) -> Image:
 | 
			
		|||
    transferred. This means that P and PA mode images will lose their palette.
 | 
			
		||||
 | 
			
		||||
    :param obj: Object with array interface
 | 
			
		||||
    :param mode: Optional mode to use when reading ``obj``. Will be determined from
 | 
			
		||||
      type if ``None``. Deprecated.
 | 
			
		||||
 | 
			
		||||
      This will not be used to convert the data after reading, but will be used to
 | 
			
		||||
      change how the data is read::
 | 
			
		||||
 | 
			
		||||
        from PIL import Image
 | 
			
		||||
        import numpy as np
 | 
			
		||||
        a = np.full((1, 1), 300)
 | 
			
		||||
        im = Image.fromarray(a, mode="L")
 | 
			
		||||
        im.getpixel((0, 0))  # 44
 | 
			
		||||
        im = Image.fromarray(a, mode="RGB")
 | 
			
		||||
        im.getpixel((0, 0))  # (44, 1, 0)
 | 
			
		||||
    :param mode: Optional mode to use when reading ``obj``. Since pixel values do not
 | 
			
		||||
      contain information about palettes or color spaces, this can be used to place
 | 
			
		||||
      grayscale L mode data within a P mode image, or read RGB data as YCbCr for
 | 
			
		||||
      example.
 | 
			
		||||
 | 
			
		||||
      See: :ref:`concept-modes` for general information about modes.
 | 
			
		||||
    :returns: An image object.
 | 
			
		||||
| 
						 | 
				
			
			@ -3282,21 +3273,28 @@ def fromarray(obj: SupportsArrayInterface, mode: str | None = None) -> Image:
 | 
			
		|||
    shape = arr["shape"]
 | 
			
		||||
    ndim = len(shape)
 | 
			
		||||
    strides = arr.get("strides", None)
 | 
			
		||||
    if mode is None:
 | 
			
		||||
        try:
 | 
			
		||||
            typekey = (1, 1) + shape[2:], arr["typestr"]
 | 
			
		||||
        except KeyError as e:
 | 
			
		||||
    try:
 | 
			
		||||
        typekey = (1, 1) + shape[2:], arr["typestr"]
 | 
			
		||||
    except KeyError as e:
 | 
			
		||||
        if mode is not None:
 | 
			
		||||
            typekey = None
 | 
			
		||||
            color_modes: list[str] = []
 | 
			
		||||
        else:
 | 
			
		||||
            msg = "Cannot handle this data type"
 | 
			
		||||
            raise TypeError(msg) from e
 | 
			
		||||
    if typekey is not None:
 | 
			
		||||
        try:
 | 
			
		||||
            mode, rawmode = _fromarray_typemap[typekey]
 | 
			
		||||
            typemode, rawmode, color_modes = _fromarray_typemap[typekey]
 | 
			
		||||
        except KeyError as e:
 | 
			
		||||
            typekey_shape, typestr = typekey
 | 
			
		||||
            msg = f"Cannot handle this data type: {typekey_shape}, {typestr}"
 | 
			
		||||
            raise TypeError(msg) from e
 | 
			
		||||
    else:
 | 
			
		||||
        deprecate("'mode' parameter", 13)
 | 
			
		||||
    if mode is not None:
 | 
			
		||||
        if mode != typemode and mode not in color_modes:
 | 
			
		||||
            deprecate("'mode' parameter for changing data types", 13)
 | 
			
		||||
        rawmode = mode
 | 
			
		||||
    else:
 | 
			
		||||
        mode = typemode
 | 
			
		||||
    if mode in ["1", "L", "I", "P", "F"]:
 | 
			
		||||
        ndmax = 2
 | 
			
		||||
    elif mode == "RGB":
 | 
			
		||||
| 
						 | 
				
			
			@ -3393,29 +3391,29 @@ def fromqpixmap(im: ImageQt.QPixmap) -> ImageFile.ImageFile:
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
_fromarray_typemap = {
 | 
			
		||||
    # (shape, typestr) => mode, rawmode
 | 
			
		||||
    # (shape, typestr) => mode, rawmode, color modes
 | 
			
		||||
    # first two members of shape are set to one
 | 
			
		||||
    ((1, 1), "|b1"): ("1", "1;8"),
 | 
			
		||||
    ((1, 1), "|u1"): ("L", "L"),
 | 
			
		||||
    ((1, 1), "|i1"): ("I", "I;8"),
 | 
			
		||||
    ((1, 1), "<u2"): ("I", "I;16"),
 | 
			
		||||
    ((1, 1), ">u2"): ("I", "I;16B"),
 | 
			
		||||
    ((1, 1), "<i2"): ("I", "I;16S"),
 | 
			
		||||
    ((1, 1), ">i2"): ("I", "I;16BS"),
 | 
			
		||||
    ((1, 1), "<u4"): ("I", "I;32"),
 | 
			
		||||
    ((1, 1), ">u4"): ("I", "I;32B"),
 | 
			
		||||
    ((1, 1), "<i4"): ("I", "I;32S"),
 | 
			
		||||
    ((1, 1), ">i4"): ("I", "I;32BS"),
 | 
			
		||||
    ((1, 1), "<f4"): ("F", "F;32F"),
 | 
			
		||||
    ((1, 1), ">f4"): ("F", "F;32BF"),
 | 
			
		||||
    ((1, 1), "<f8"): ("F", "F;64F"),
 | 
			
		||||
    ((1, 1), ">f8"): ("F", "F;64BF"),
 | 
			
		||||
    ((1, 1, 2), "|u1"): ("LA", "LA"),
 | 
			
		||||
    ((1, 1, 3), "|u1"): ("RGB", "RGB"),
 | 
			
		||||
    ((1, 1, 4), "|u1"): ("RGBA", "RGBA"),
 | 
			
		||||
    ((1, 1), "|b1"): ("1", "1;8", []),
 | 
			
		||||
    ((1, 1), "|u1"): ("L", "L", ["P"]),
 | 
			
		||||
    ((1, 1), "|i1"): ("I", "I;8", []),
 | 
			
		||||
    ((1, 1), "<u2"): ("I", "I;16", []),
 | 
			
		||||
    ((1, 1), ">u2"): ("I", "I;16B", []),
 | 
			
		||||
    ((1, 1), "<i2"): ("I", "I;16S", []),
 | 
			
		||||
    ((1, 1), ">i2"): ("I", "I;16BS", []),
 | 
			
		||||
    ((1, 1), "<u4"): ("I", "I;32", []),
 | 
			
		||||
    ((1, 1), ">u4"): ("I", "I;32B", []),
 | 
			
		||||
    ((1, 1), "<i4"): ("I", "I;32S", []),
 | 
			
		||||
    ((1, 1), ">i4"): ("I", "I;32BS", []),
 | 
			
		||||
    ((1, 1), "<f4"): ("F", "F;32F", []),
 | 
			
		||||
    ((1, 1), ">f4"): ("F", "F;32BF", []),
 | 
			
		||||
    ((1, 1), "<f8"): ("F", "F;64F", []),
 | 
			
		||||
    ((1, 1), ">f8"): ("F", "F;64BF", []),
 | 
			
		||||
    ((1, 1, 2), "|u1"): ("LA", "LA", ["La", "PA"]),
 | 
			
		||||
    ((1, 1, 3), "|u1"): ("RGB", "RGB", ["YCbCr", "LAB", "HSV"]),
 | 
			
		||||
    ((1, 1, 4), "|u1"): ("RGBA", "RGBA", ["RGBa", "RGBX", "CMYK"]),
 | 
			
		||||
    # shortcuts:
 | 
			
		||||
    ((1, 1), f"{_ENDIAN}i4"): ("I", "I"),
 | 
			
		||||
    ((1, 1), f"{_ENDIAN}f4"): ("F", "F"),
 | 
			
		||||
    ((1, 1), f"{_ENDIAN}i4"): ("I", "I", []),
 | 
			
		||||
    ((1, 1), f"{_ENDIAN}f4"): ("F", "F", []),
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue
	
	Block a user