mirror of
https://github.com/python-pillow/Pillow.git
synced 2026-01-09 18:21:22 +03:00
Deprecate getdata(), in favour of new get_flattened_data() (#9292)
This commit is contained in:
parent
b51a036685
commit
3baedf2648
|
|
@ -55,8 +55,8 @@ def convert_to_comparable(
|
||||||
if a.mode == "P":
|
if a.mode == "P":
|
||||||
new_a = Image.new("L", a.size)
|
new_a = Image.new("L", a.size)
|
||||||
new_b = Image.new("L", b.size)
|
new_b = Image.new("L", b.size)
|
||||||
new_a.putdata(a.getdata())
|
new_a.putdata(a.get_flattened_data())
|
||||||
new_b.putdata(b.getdata())
|
new_b.putdata(b.get_flattened_data())
|
||||||
elif a.mode == "I;16":
|
elif a.mode == "I;16":
|
||||||
new_a = a.convert("I")
|
new_a = a.convert("I")
|
||||||
new_b = b.convert("I")
|
new_b = b.convert("I")
|
||||||
|
|
|
||||||
|
|
@ -28,9 +28,13 @@ def box_blur(image: Image.Image, radius: float = 1, n: int = 1) -> Image.Image:
|
||||||
|
|
||||||
|
|
||||||
def assert_image(im: Image.Image, data: list[list[int]], delta: int = 0) -> None:
|
def assert_image(im: Image.Image, data: list[list[int]], delta: int = 0) -> None:
|
||||||
it = iter(im.getdata())
|
it = iter(im.get_flattened_data())
|
||||||
for data_row in data:
|
for data_row in data:
|
||||||
im_row = [next(it) for _ in range(im.size[0])]
|
im_row = []
|
||||||
|
for _ in range(im.width):
|
||||||
|
im_v = next(it)
|
||||||
|
assert isinstance(im_v, (int, float))
|
||||||
|
im_row.append(im_v)
|
||||||
if any(abs(data_v - im_v) > delta for data_v, im_v in zip(data_row, im_row)):
|
if any(abs(data_v - im_v) > delta for data_v, im_v in zip(data_row, im_row)):
|
||||||
assert im_row == data_row
|
assert im_row == data_row
|
||||||
with pytest.raises(StopIteration):
|
with pytest.raises(StopIteration):
|
||||||
|
|
|
||||||
|
|
@ -121,7 +121,6 @@ class TestFileAvif:
|
||||||
assert image.size == (128, 128)
|
assert image.size == (128, 128)
|
||||||
assert image.format == "AVIF"
|
assert image.format == "AVIF"
|
||||||
assert image.get_format_mimetype() == "image/avif"
|
assert image.get_format_mimetype() == "image/avif"
|
||||||
image.getdata()
|
|
||||||
|
|
||||||
# generated with:
|
# generated with:
|
||||||
# avifdec hopper.avif hopper_avif_write.png
|
# avifdec hopper.avif hopper_avif_write.png
|
||||||
|
|
@ -143,7 +142,6 @@ class TestFileAvif:
|
||||||
assert reloaded.mode == "RGB"
|
assert reloaded.mode == "RGB"
|
||||||
assert reloaded.size == (128, 128)
|
assert reloaded.size == (128, 128)
|
||||||
assert reloaded.format == "AVIF"
|
assert reloaded.format == "AVIF"
|
||||||
reloaded.getdata()
|
|
||||||
|
|
||||||
# avifdec hopper.avif avif/hopper_avif_write.png
|
# avifdec hopper.avif avif/hopper_avif_write.png
|
||||||
assert_image_similar_tofile(
|
assert_image_similar_tofile(
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,6 @@ class LibTiffTestCase:
|
||||||
|
|
||||||
# Does the data actually load
|
# Does the data actually load
|
||||||
im.load()
|
im.load()
|
||||||
im.getdata()
|
|
||||||
|
|
||||||
assert isinstance(im, TiffImagePlugin.TiffImageFile)
|
assert isinstance(im, TiffImagePlugin.TiffImageFile)
|
||||||
assert im._compression == "group4"
|
assert im._compression == "group4"
|
||||||
|
|
|
||||||
|
|
@ -60,7 +60,6 @@ class TestFileWebp:
|
||||||
assert image.size == (128, 128)
|
assert image.size == (128, 128)
|
||||||
assert image.format == "WEBP"
|
assert image.format == "WEBP"
|
||||||
image.load()
|
image.load()
|
||||||
image.getdata()
|
|
||||||
|
|
||||||
# generated with:
|
# generated with:
|
||||||
# dwebp -ppm ../../Tests/images/hopper.webp -o hopper_webp_bits.ppm
|
# dwebp -ppm ../../Tests/images/hopper.webp -o hopper_webp_bits.ppm
|
||||||
|
|
@ -77,7 +76,6 @@ class TestFileWebp:
|
||||||
assert image.size == (128, 128)
|
assert image.size == (128, 128)
|
||||||
assert image.format == "WEBP"
|
assert image.format == "WEBP"
|
||||||
image.load()
|
image.load()
|
||||||
image.getdata()
|
|
||||||
|
|
||||||
if mode == self.rgb_mode:
|
if mode == self.rgb_mode:
|
||||||
# generated with: dwebp -ppm temp.webp -o hopper_webp_write.ppm
|
# generated with: dwebp -ppm temp.webp -o hopper_webp_write.ppm
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,6 @@ def test_read_rgba() -> None:
|
||||||
assert image.size == (200, 150)
|
assert image.size == (200, 150)
|
||||||
assert image.format == "WEBP"
|
assert image.format == "WEBP"
|
||||||
image.load()
|
image.load()
|
||||||
image.getdata()
|
|
||||||
|
|
||||||
image.tobytes()
|
image.tobytes()
|
||||||
|
|
||||||
|
|
@ -60,7 +59,6 @@ def test_write_lossless_rgb(tmp_path: Path) -> None:
|
||||||
assert image.size == pil_image.size
|
assert image.size == pil_image.size
|
||||||
assert image.format == "WEBP"
|
assert image.format == "WEBP"
|
||||||
image.load()
|
image.load()
|
||||||
image.getdata()
|
|
||||||
|
|
||||||
assert_image_equal(image, pil_image)
|
assert_image_equal(image, pil_image)
|
||||||
|
|
||||||
|
|
@ -83,7 +81,6 @@ def test_write_rgba(tmp_path: Path) -> None:
|
||||||
assert image.size == (10, 10)
|
assert image.size == (10, 10)
|
||||||
assert image.format == "WEBP"
|
assert image.format == "WEBP"
|
||||||
image.load()
|
image.load()
|
||||||
image.getdata()
|
|
||||||
|
|
||||||
assert_image_similar(image, pil_image, 1.0)
|
assert_image_similar(image, pil_image, 1.0)
|
||||||
|
|
||||||
|
|
@ -133,7 +130,6 @@ def test_write_unsupported_mode_PA(tmp_path: Path) -> None:
|
||||||
assert image.format == "WEBP"
|
assert image.format == "WEBP"
|
||||||
|
|
||||||
image.load()
|
image.load()
|
||||||
image.getdata()
|
|
||||||
with Image.open(file_path) as im:
|
with Image.open(file_path) as im:
|
||||||
target = im.convert("RGBA")
|
target = im.convert("RGBA")
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,5 @@ def test_write_lossless_rgb(tmp_path: Path) -> None:
|
||||||
assert image.size == (128, 128)
|
assert image.size == (128, 128)
|
||||||
assert image.format == "WEBP"
|
assert image.format == "WEBP"
|
||||||
image.load()
|
image.load()
|
||||||
image.getdata()
|
|
||||||
|
|
||||||
assert_image_equal(image, hopper(RGB_MODE))
|
assert_image_equal(image, hopper(RGB_MODE))
|
||||||
|
|
|
||||||
|
|
@ -13,15 +13,15 @@ def test_white() -> None:
|
||||||
|
|
||||||
k = i.getpixel((0, 0))
|
k = i.getpixel((0, 0))
|
||||||
|
|
||||||
L = i.getdata(0)
|
L = i.get_flattened_data(0)
|
||||||
a = i.getdata(1)
|
a = i.get_flattened_data(1)
|
||||||
b = i.getdata(2)
|
b = i.get_flattened_data(2)
|
||||||
|
|
||||||
assert k == (255, 128, 128)
|
assert k == (255, 128, 128)
|
||||||
|
|
||||||
assert list(L) == [255] * 100
|
assert L == (255,) * 100
|
||||||
assert list(a) == [128] * 100
|
assert a == (128,) * 100
|
||||||
assert list(b) == [128] * 100
|
assert b == (128,) * 100
|
||||||
|
|
||||||
|
|
||||||
def test_green() -> None:
|
def test_green() -> None:
|
||||||
|
|
|
||||||
|
|
@ -1181,10 +1181,10 @@ class TestImageBytes:
|
||||||
assert reloaded.tobytes() == source_bytes
|
assert reloaded.tobytes() == source_bytes
|
||||||
|
|
||||||
@pytest.mark.parametrize("mode", Image.MODES)
|
@pytest.mark.parametrize("mode", Image.MODES)
|
||||||
def test_getdata_putdata(self, mode: str) -> None:
|
def test_get_flattened_data_putdata(self, mode: str) -> None:
|
||||||
im = hopper(mode)
|
im = hopper(mode)
|
||||||
reloaded = Image.new(mode, im.size)
|
reloaded = Image.new(mode, im.size)
|
||||||
reloaded.putdata(im.getdata())
|
reloaded.putdata(im.get_flattened_data())
|
||||||
assert_image_equal(im, reloaded)
|
assert_image_equal(im, reloaded)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -78,7 +78,7 @@ def test_fromarray() -> None:
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
out = Image.fromarray(wrapped)
|
out = Image.fromarray(wrapped)
|
||||||
return out.mode, out.size, list(i.getdata()) == list(out.getdata())
|
return out.mode, out.size, i.get_flattened_data() == out.get_flattened_data()
|
||||||
|
|
||||||
# assert test("1") == ("1", (128, 100), True)
|
# assert test("1") == ("1", (128, 100), True)
|
||||||
assert test("L") == ("L", (128, 100), True)
|
assert test("L") == ("L", (128, 100), True)
|
||||||
|
|
|
||||||
|
|
@ -95,10 +95,10 @@ def test_crop_zero() -> None:
|
||||||
|
|
||||||
cropped = im.crop((10, 10, 20, 20))
|
cropped = im.crop((10, 10, 20, 20))
|
||||||
assert cropped.size == (10, 10)
|
assert cropped.size == (10, 10)
|
||||||
assert cropped.getdata()[0] == (0, 0, 0)
|
assert cropped.getpixel((0, 0)) == (0, 0, 0)
|
||||||
|
|
||||||
im = Image.new("RGB", (0, 0))
|
im = Image.new("RGB", (0, 0))
|
||||||
|
|
||||||
cropped = im.crop((10, 10, 20, 20))
|
cropped = im.crop((10, 10, 20, 20))
|
||||||
assert cropped.size == (10, 10)
|
assert cropped.size == (10, 10)
|
||||||
assert cropped.getdata()[2] == (0, 0, 0)
|
assert cropped.getpixel((2, 0)) == (0, 0, 0)
|
||||||
|
|
|
||||||
|
|
@ -1,23 +1,23 @@
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
|
||||||
from PIL import Image
|
from PIL import Image
|
||||||
|
|
||||||
from .helper import hopper
|
from .helper import hopper
|
||||||
|
|
||||||
|
|
||||||
def test_sanity() -> None:
|
def test_sanity() -> None:
|
||||||
data = hopper().getdata()
|
data = hopper().get_flattened_data()
|
||||||
|
|
||||||
len(data)
|
|
||||||
list(data)
|
|
||||||
|
|
||||||
|
assert len(data) == 128 * 128
|
||||||
assert data[0] == (20, 20, 70)
|
assert data[0] == (20, 20, 70)
|
||||||
|
|
||||||
|
|
||||||
def test_mode() -> None:
|
def test_mode() -> None:
|
||||||
def getdata(mode: str) -> tuple[float | tuple[int, ...] | None, int, int]:
|
def getdata(mode: str) -> tuple[float | tuple[int, ...] | None, int, int]:
|
||||||
im = hopper(mode).resize((32, 30), Image.Resampling.NEAREST)
|
im = hopper(mode).resize((32, 30), Image.Resampling.NEAREST)
|
||||||
data = im.getdata()
|
data = im.get_flattened_data()
|
||||||
return data[0], len(data), len(list(data))
|
return data[0], len(data), len(list(data))
|
||||||
|
|
||||||
assert getdata("1") == (0, 960, 960)
|
assert getdata("1") == (0, 960, 960)
|
||||||
|
|
@ -28,3 +28,13 @@ def test_mode() -> None:
|
||||||
assert getdata("RGBA") == ((11, 13, 52, 255), 960, 960)
|
assert getdata("RGBA") == ((11, 13, 52, 255), 960, 960)
|
||||||
assert getdata("CMYK") == ((244, 242, 203, 0), 960, 960)
|
assert getdata("CMYK") == ((244, 242, 203, 0), 960, 960)
|
||||||
assert getdata("YCbCr") == ((16, 147, 123), 960, 960)
|
assert getdata("YCbCr") == ((16, 147, 123), 960, 960)
|
||||||
|
|
||||||
|
|
||||||
|
def test_deprecation() -> None:
|
||||||
|
im = hopper()
|
||||||
|
with pytest.warns(DeprecationWarning, match="getdata"):
|
||||||
|
data = im.getdata()
|
||||||
|
|
||||||
|
assert len(data) == 128 * 128
|
||||||
|
assert data[0] == (20, 20, 70)
|
||||||
|
assert list(data)[0] == (20, 20, 70)
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ from __future__ import annotations
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
from array import array
|
from array import array
|
||||||
|
from typing import cast
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
|
|
@ -12,21 +13,19 @@ from .helper import assert_image_equal, hopper
|
||||||
|
|
||||||
def test_sanity() -> None:
|
def test_sanity() -> None:
|
||||||
im1 = hopper()
|
im1 = hopper()
|
||||||
|
for data in (im1.get_flattened_data(), im1.im):
|
||||||
|
im2 = Image.new(im1.mode, im1.size, 0)
|
||||||
|
im2.putdata(data)
|
||||||
|
|
||||||
data = list(im1.getdata())
|
assert_image_equal(im1, im2)
|
||||||
|
|
||||||
im2 = Image.new(im1.mode, im1.size, 0)
|
# readonly
|
||||||
im2.putdata(data)
|
im2 = Image.new(im1.mode, im2.size, 0)
|
||||||
|
im2.readonly = 1
|
||||||
|
im2.putdata(data)
|
||||||
|
|
||||||
assert_image_equal(im1, im2)
|
assert not im2.readonly
|
||||||
|
assert_image_equal(im1, im2)
|
||||||
# readonly
|
|
||||||
im2 = Image.new(im1.mode, im2.size, 0)
|
|
||||||
im2.readonly = 1
|
|
||||||
im2.putdata(data)
|
|
||||||
|
|
||||||
assert not im2.readonly
|
|
||||||
assert_image_equal(im1, im2)
|
|
||||||
|
|
||||||
|
|
||||||
def test_long_integers() -> None:
|
def test_long_integers() -> None:
|
||||||
|
|
@ -60,22 +59,22 @@ def test_mode_with_L_with_float() -> None:
|
||||||
@pytest.mark.parametrize("mode", ("I", "I;16", "I;16L", "I;16B"))
|
@pytest.mark.parametrize("mode", ("I", "I;16", "I;16L", "I;16B"))
|
||||||
def test_mode_i(mode: str) -> None:
|
def test_mode_i(mode: str) -> None:
|
||||||
src = hopper("L")
|
src = hopper("L")
|
||||||
data = list(src.getdata())
|
data = src.get_flattened_data()
|
||||||
im = Image.new(mode, src.size, 0)
|
im = Image.new(mode, src.size, 0)
|
||||||
im.putdata(data, 2, 256)
|
im.putdata(data, 2, 256)
|
||||||
|
|
||||||
target = [2 * elt + 256 for elt in data]
|
target = tuple(2 * elt + 256 for elt in cast(tuple[int, ...], data))
|
||||||
assert list(im.getdata()) == target
|
assert im.get_flattened_data() == target
|
||||||
|
|
||||||
|
|
||||||
def test_mode_F() -> None:
|
def test_mode_F() -> None:
|
||||||
src = hopper("L")
|
src = hopper("L")
|
||||||
data = list(src.getdata())
|
data = src.get_flattened_data()
|
||||||
im = Image.new("F", src.size, 0)
|
im = Image.new("F", src.size, 0)
|
||||||
im.putdata(data, 2.0, 256.0)
|
im.putdata(data, 2.0, 256.0)
|
||||||
|
|
||||||
target = [2.0 * float(elt) + 256.0 for elt in data]
|
target = tuple(2.0 * float(elt) + 256.0 for elt in cast(tuple[int, ...], data))
|
||||||
assert list(im.getdata()) == target
|
assert im.get_flattened_data() == target
|
||||||
|
|
||||||
|
|
||||||
def test_array_B() -> None:
|
def test_array_B() -> None:
|
||||||
|
|
@ -86,7 +85,7 @@ def test_array_B() -> None:
|
||||||
im = Image.new("L", (150, 100))
|
im = Image.new("L", (150, 100))
|
||||||
im.putdata(arr)
|
im.putdata(arr)
|
||||||
|
|
||||||
assert len(im.getdata()) == len(arr)
|
assert len(im.get_flattened_data()) == len(arr)
|
||||||
|
|
||||||
|
|
||||||
def test_array_F() -> None:
|
def test_array_F() -> None:
|
||||||
|
|
@ -97,7 +96,7 @@ def test_array_F() -> None:
|
||||||
arr = array("f", [0.0]) * 15000
|
arr = array("f", [0.0]) * 15000
|
||||||
im.putdata(arr)
|
im.putdata(arr)
|
||||||
|
|
||||||
assert len(im.getdata()) == len(arr)
|
assert len(im.get_flattened_data()) == len(arr)
|
||||||
|
|
||||||
|
|
||||||
def test_not_flattened() -> None:
|
def test_not_flattened() -> None:
|
||||||
|
|
|
||||||
|
|
@ -160,7 +160,7 @@ class TestImagingCoreResize:
|
||||||
r = self.resize(Image.new("RGB", (0, 0), "white"), (212, 195), resample)
|
r = self.resize(Image.new("RGB", (0, 0), "white"), (212, 195), resample)
|
||||||
assert r.mode == "RGB"
|
assert r.mode == "RGB"
|
||||||
assert r.size == (212, 195)
|
assert r.size == (212, 195)
|
||||||
assert r.getdata()[0] == (0, 0, 0)
|
assert r.getpixel((0, 0)) == (0, 0, 0)
|
||||||
|
|
||||||
def test_unknown_filter(self) -> None:
|
def test_unknown_filter(self) -> None:
|
||||||
with pytest.raises(ValueError):
|
with pytest.raises(ValueError):
|
||||||
|
|
|
||||||
|
|
@ -274,13 +274,13 @@ def test_simple_lab() -> None:
|
||||||
# not a linear luminance map. so L != 128:
|
# not a linear luminance map. so L != 128:
|
||||||
assert k == (137, 128, 128)
|
assert k == (137, 128, 128)
|
||||||
|
|
||||||
l_data = i_lab.getdata(0)
|
l_data = i_lab.get_flattened_data(0)
|
||||||
a_data = i_lab.getdata(1)
|
a_data = i_lab.get_flattened_data(1)
|
||||||
b_data = i_lab.getdata(2)
|
b_data = i_lab.get_flattened_data(2)
|
||||||
|
|
||||||
assert list(l_data) == [137] * 100
|
assert l_data == (137,) * 100
|
||||||
assert list(a_data) == [128] * 100
|
assert a_data == (128,) * 100
|
||||||
assert list(b_data) == [128] * 100
|
assert b_data == (128,) * 100
|
||||||
|
|
||||||
|
|
||||||
def test_lab_color() -> None:
|
def test_lab_color() -> None:
|
||||||
|
|
|
||||||
|
|
@ -20,21 +20,19 @@ TEST_IMAGE_SIZE = (10, 10)
|
||||||
|
|
||||||
def test_numpy_to_image() -> None:
|
def test_numpy_to_image() -> None:
|
||||||
def to_image(dtype: npt.DTypeLike, bands: int = 1, boolean: int = 0) -> Image.Image:
|
def to_image(dtype: npt.DTypeLike, bands: int = 1, boolean: int = 0) -> Image.Image:
|
||||||
|
data = tuple(range(100))
|
||||||
if bands == 1:
|
if bands == 1:
|
||||||
if boolean:
|
if boolean:
|
||||||
data = [0, 255] * 50
|
data = (0, 255) * 50
|
||||||
else:
|
|
||||||
data = list(range(100))
|
|
||||||
a = numpy.array(data, dtype=dtype)
|
a = numpy.array(data, dtype=dtype)
|
||||||
a.shape = TEST_IMAGE_SIZE
|
a.shape = TEST_IMAGE_SIZE
|
||||||
i = Image.fromarray(a)
|
i = Image.fromarray(a)
|
||||||
assert list(i.getdata()) == data
|
assert i.get_flattened_data() == data
|
||||||
else:
|
else:
|
||||||
data = list(range(100))
|
|
||||||
a = numpy.array([[x] * bands for x in data], dtype=dtype)
|
a = numpy.array([[x] * bands for x in data], dtype=dtype)
|
||||||
a.shape = TEST_IMAGE_SIZE[0], TEST_IMAGE_SIZE[1], bands
|
a.shape = TEST_IMAGE_SIZE[0], TEST_IMAGE_SIZE[1], bands
|
||||||
i = Image.fromarray(a)
|
i = Image.fromarray(a)
|
||||||
assert list(i.getchannel(0).getdata()) == list(range(100))
|
assert i.get_flattened_data(0) == tuple(range(100))
|
||||||
return i
|
return i
|
||||||
|
|
||||||
# Check supported 1-bit integer formats
|
# Check supported 1-bit integer formats
|
||||||
|
|
@ -191,7 +189,7 @@ def test_putdata() -> None:
|
||||||
arr = numpy.zeros((15000,), numpy.float32)
|
arr = numpy.zeros((15000,), numpy.float32)
|
||||||
im.putdata(arr)
|
im.putdata(arr)
|
||||||
|
|
||||||
assert len(im.getdata()) == len(arr)
|
assert len(im.get_flattened_data()) == len(arr)
|
||||||
|
|
||||||
|
|
||||||
def test_resize() -> None:
|
def test_resize() -> None:
|
||||||
|
|
@ -248,7 +246,7 @@ def test_bool() -> None:
|
||||||
a[0][0] = True
|
a[0][0] = True
|
||||||
|
|
||||||
im2 = Image.fromarray(a)
|
im2 = Image.fromarray(a)
|
||||||
assert im2.getdata()[0] == 255
|
assert im2.getpixel((0, 0)) == 255
|
||||||
|
|
||||||
|
|
||||||
def test_no_resource_warning_for_numpy_array() -> None:
|
def test_no_resource_warning_for_numpy_array() -> None:
|
||||||
|
|
|
||||||
|
|
@ -73,6 +73,16 @@ Image._show
|
||||||
``Image._show`` has been deprecated, and will be removed in Pillow 13 (2026-10-15).
|
``Image._show`` has been deprecated, and will be removed in Pillow 13 (2026-10-15).
|
||||||
Use :py:meth:`~PIL.ImageShow.show` instead.
|
Use :py:meth:`~PIL.ImageShow.show` instead.
|
||||||
|
|
||||||
|
Image getdata()
|
||||||
|
~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
.. deprecated:: 12.1.0
|
||||||
|
|
||||||
|
:py:meth:`~PIL.Image.Image.getdata` has been deprecated.
|
||||||
|
:py:meth:`~PIL.Image.Image.get_flattened_data` can be used instead. This new method is
|
||||||
|
identical, except that it returns a tuple of pixel values, instead of an internal
|
||||||
|
Pillow data type.
|
||||||
|
|
||||||
Removed features
|
Removed features
|
||||||
----------------
|
----------------
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -191,6 +191,7 @@ This helps to get the bounding box coordinates of the input image::
|
||||||
.. automethod:: PIL.Image.Image.getchannel
|
.. automethod:: PIL.Image.Image.getchannel
|
||||||
.. automethod:: PIL.Image.Image.getcolors
|
.. automethod:: PIL.Image.Image.getcolors
|
||||||
.. automethod:: PIL.Image.Image.getdata
|
.. automethod:: PIL.Image.Image.getdata
|
||||||
|
.. automethod:: PIL.Image.Image.get_flattened_data
|
||||||
.. automethod:: PIL.Image.Image.getexif
|
.. automethod:: PIL.Image.Image.getexif
|
||||||
.. automethod:: PIL.Image.Image.getextrema
|
.. automethod:: PIL.Image.Image.getextrema
|
||||||
.. automethod:: PIL.Image.Image.getpalette
|
.. automethod:: PIL.Image.Image.getpalette
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,17 @@
|
||||||
12.1.0
|
12.1.0
|
||||||
------
|
------
|
||||||
|
|
||||||
|
Deprecations
|
||||||
|
============
|
||||||
|
|
||||||
|
Image getdata()
|
||||||
|
^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
:py:meth:`~PIL.Image.Image.getdata` has been deprecated.
|
||||||
|
:py:meth:`~PIL.Image.Image.get_flattened_data` can be used instead. This new method is
|
||||||
|
identical, except that it returns a tuple of pixel values, instead of an internal
|
||||||
|
Pillow data type.
|
||||||
|
|
||||||
API changes
|
API changes
|
||||||
===========
|
===========
|
||||||
|
|
||||||
|
|
@ -13,6 +24,13 @@ To match the behaviour of :py:meth:`~PIL.ImageMorph.LutBuilder.build_lut`,
|
||||||
API additions
|
API additions
|
||||||
=============
|
=============
|
||||||
|
|
||||||
|
Image get_flattened_data()
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
:py:meth:`~PIL.Image.Image.get_flattened_data` is identical to the deprecated
|
||||||
|
:py:meth:`~PIL.Image.Image.getdata`, except that the new method returns a tuple of
|
||||||
|
pixel values, instead of an internal Pillow data type.
|
||||||
|
|
||||||
Specify window in ImageGrab on macOS
|
Specify window in ImageGrab on macOS
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -753,7 +753,7 @@ def _write_multiple_frames(
|
||||||
if delta.mode == "P":
|
if delta.mode == "P":
|
||||||
# Convert to L without considering palette
|
# Convert to L without considering palette
|
||||||
delta_l = Image.new("L", delta.size)
|
delta_l = Image.new("L", delta.size)
|
||||||
delta_l.putdata(delta.getdata())
|
delta_l.putdata(delta.get_flattened_data())
|
||||||
delta = delta_l
|
delta = delta_l
|
||||||
mask = ImageMath.lambda_eval(
|
mask = ImageMath.lambda_eval(
|
||||||
lambda args: args["convert"](args["im"] * 255, "1"),
|
lambda args: args["convert"](args["im"] * 255, "1"),
|
||||||
|
|
|
||||||
|
|
@ -1435,12 +1435,31 @@ class Image:
|
||||||
value (e.g. 0 to get the "R" band from an "RGB" image).
|
value (e.g. 0 to get the "R" band from an "RGB" image).
|
||||||
:returns: A sequence-like object.
|
:returns: A sequence-like object.
|
||||||
"""
|
"""
|
||||||
|
deprecate("Image.Image.getdata", 14, "get_flattened_data")
|
||||||
|
|
||||||
self.load()
|
self.load()
|
||||||
if band is not None:
|
if band is not None:
|
||||||
return self.im.getband(band)
|
return self.im.getband(band)
|
||||||
return self.im # could be abused
|
return self.im # could be abused
|
||||||
|
|
||||||
|
def get_flattened_data(
|
||||||
|
self, band: int | None = None
|
||||||
|
) -> tuple[tuple[int, ...], ...] | tuple[float, ...]:
|
||||||
|
"""
|
||||||
|
Returns the contents of this image as a tuple containing pixel values.
|
||||||
|
The sequence object is flattened, so that values for line one follow
|
||||||
|
directly after the values of line zero, and so on.
|
||||||
|
|
||||||
|
:param band: What band to return. The default is to return
|
||||||
|
all bands. To return a single band, pass in the index
|
||||||
|
value (e.g. 0 to get the "R" band from an "RGB" image).
|
||||||
|
:returns: A tuple containing pixel values.
|
||||||
|
"""
|
||||||
|
self.load()
|
||||||
|
if band is not None:
|
||||||
|
return tuple(self.im.getband(band))
|
||||||
|
return tuple(self.im)
|
||||||
|
|
||||||
def getextrema(self) -> tuple[float, float] | tuple[tuple[int, int], ...]:
|
def getextrema(self) -> tuple[float, float] | tuple[tuple[int, int], ...]:
|
||||||
"""
|
"""
|
||||||
Gets the minimum and maximum pixel values for each band in
|
Gets the minimum and maximum pixel values for each band in
|
||||||
|
|
|
||||||
|
|
@ -48,6 +48,8 @@ def deprecate(
|
||||||
raise RuntimeError(msg)
|
raise RuntimeError(msg)
|
||||||
elif when == 13:
|
elif when == 13:
|
||||||
removed = "Pillow 13 (2026-10-15)"
|
removed = "Pillow 13 (2026-10-15)"
|
||||||
|
elif when == 14:
|
||||||
|
removed = "Pillow 14 (2027-10-15)"
|
||||||
else:
|
else:
|
||||||
msg = f"Unknown removal version: {when}. Update {__name__}?"
|
msg = f"Unknown removal version: {when}. Update {__name__}?"
|
||||||
raise ValueError(msg)
|
raise ValueError(msg)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user