mirror of
https://github.com/python-pillow/Pillow.git
synced 2024-12-25 17:36:18 +03:00
commit
219add0239
|
@ -1511,7 +1511,7 @@ class Image:
|
||||||
self._exif._loaded = False
|
self._exif._loaded = False
|
||||||
self.getexif()
|
self.getexif()
|
||||||
|
|
||||||
def get_child_images(self):
|
def get_child_images(self) -> list[ImageFile.ImageFile]:
|
||||||
child_images = []
|
child_images = []
|
||||||
exif = self.getexif()
|
exif = self.getexif()
|
||||||
ifds = []
|
ifds = []
|
||||||
|
@ -1535,10 +1535,7 @@ class Image:
|
||||||
fp = self.fp
|
fp = self.fp
|
||||||
thumbnail_offset = ifd.get(513)
|
thumbnail_offset = ifd.get(513)
|
||||||
if thumbnail_offset is not None:
|
if thumbnail_offset is not None:
|
||||||
try:
|
thumbnail_offset += getattr(self, "_exif_offset", 0)
|
||||||
thumbnail_offset += self._exif_offset
|
|
||||||
except AttributeError:
|
|
||||||
pass
|
|
||||||
self.fp.seek(thumbnail_offset)
|
self.fp.seek(thumbnail_offset)
|
||||||
data = self.fp.read(ifd.get(514))
|
data = self.fp.read(ifd.get(514))
|
||||||
fp = io.BytesIO(data)
|
fp = io.BytesIO(data)
|
||||||
|
@ -1604,7 +1601,7 @@ class Image:
|
||||||
or "transparency" in self.info
|
or "transparency" in self.info
|
||||||
)
|
)
|
||||||
|
|
||||||
def apply_transparency(self):
|
def apply_transparency(self) -> None:
|
||||||
"""
|
"""
|
||||||
If a P mode image has a "transparency" key in the info dictionary,
|
If a P mode image has a "transparency" key in the info dictionary,
|
||||||
remove the key and instead apply the transparency to the palette.
|
remove the key and instead apply the transparency to the palette.
|
||||||
|
@ -1616,6 +1613,7 @@ class Image:
|
||||||
from . import ImagePalette
|
from . import ImagePalette
|
||||||
|
|
||||||
palette = self.getpalette("RGBA")
|
palette = self.getpalette("RGBA")
|
||||||
|
assert palette is not None
|
||||||
transparency = self.info["transparency"]
|
transparency = self.info["transparency"]
|
||||||
if isinstance(transparency, bytes):
|
if isinstance(transparency, bytes):
|
||||||
for i, alpha in enumerate(transparency):
|
for i, alpha in enumerate(transparency):
|
||||||
|
|
|
@ -908,7 +908,13 @@ def getdraw(im=None, hints=None):
|
||||||
return im, handler
|
return im, handler
|
||||||
|
|
||||||
|
|
||||||
def floodfill(image: Image.Image, xy, value, border=None, thresh=0) -> None:
|
def floodfill(
|
||||||
|
image: Image.Image,
|
||||||
|
xy: tuple[int, int],
|
||||||
|
value: float | tuple[int, ...],
|
||||||
|
border: float | tuple[int, ...] | None = None,
|
||||||
|
thresh: float = 0,
|
||||||
|
) -> None:
|
||||||
"""
|
"""
|
||||||
(experimental) Fills a bounded region with a given color.
|
(experimental) Fills a bounded region with a given color.
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,7 @@ from __future__ import annotations
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
import sys
|
import sys
|
||||||
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
from ._deprecate import deprecate
|
from ._deprecate import deprecate
|
||||||
|
|
||||||
|
@ -48,9 +49,12 @@ except ImportError as ex:
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from . import Image
|
||||||
|
|
||||||
|
|
||||||
class PyAccess:
|
class PyAccess:
|
||||||
def __init__(self, img, readonly=False):
|
def __init__(self, img: Image.Image, readonly: bool = False) -> None:
|
||||||
deprecate("PyAccess", 11)
|
deprecate("PyAccess", 11)
|
||||||
vals = dict(img.im.unsafe_ptrs)
|
vals = dict(img.im.unsafe_ptrs)
|
||||||
self.readonly = readonly
|
self.readonly = readonly
|
||||||
|
@ -77,7 +81,8 @@ class PyAccess:
|
||||||
"""
|
"""
|
||||||
Modifies the pixel at x,y. The color is given as a single
|
Modifies the pixel at x,y. The color is given as a single
|
||||||
numerical value for single band images, and a tuple for
|
numerical value for single band images, and a tuple for
|
||||||
multi-band images
|
multi-band images. In addition to this, RGB and RGBA tuples
|
||||||
|
are accepted for P and PA images.
|
||||||
|
|
||||||
:param xy: The pixel coordinate, given as (x, y). See
|
:param xy: The pixel coordinate, given as (x, y). See
|
||||||
:ref:`coordinate-system`.
|
:ref:`coordinate-system`.
|
||||||
|
@ -108,7 +113,7 @@ class PyAccess:
|
||||||
|
|
||||||
return self.set_pixel(x, y, color)
|
return self.set_pixel(x, y, color)
|
||||||
|
|
||||||
def __getitem__(self, xy):
|
def __getitem__(self, xy: tuple[int, int]) -> float | tuple[int, ...]:
|
||||||
"""
|
"""
|
||||||
Returns the pixel at x,y. The pixel is returned as a single
|
Returns the pixel at x,y. The pixel is returned as a single
|
||||||
value for single band images or a tuple for multiple band
|
value for single band images or a tuple for multiple band
|
||||||
|
@ -130,13 +135,19 @@ class PyAccess:
|
||||||
putpixel = __setitem__
|
putpixel = __setitem__
|
||||||
getpixel = __getitem__
|
getpixel = __getitem__
|
||||||
|
|
||||||
def check_xy(self, xy):
|
def check_xy(self, xy: tuple[int, int]) -> tuple[int, int]:
|
||||||
(x, y) = xy
|
(x, y) = xy
|
||||||
if not (0 <= x < self.xsize and 0 <= y < self.ysize):
|
if not (0 <= x < self.xsize and 0 <= y < self.ysize):
|
||||||
msg = "pixel location out of range"
|
msg = "pixel location out of range"
|
||||||
raise ValueError(msg)
|
raise ValueError(msg)
|
||||||
return xy
|
return xy
|
||||||
|
|
||||||
|
def get_pixel(self, x: int, y: int) -> float | tuple[int, ...]:
|
||||||
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
def set_pixel(self, x: int, y: int, color: float | tuple[int, ...]) -> None:
|
||||||
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
|
||||||
class _PyAccess32_2(PyAccess):
|
class _PyAccess32_2(PyAccess):
|
||||||
"""PA, LA, stored in first and last bytes of a 32 bit word"""
|
"""PA, LA, stored in first and last bytes of a 32 bit word"""
|
||||||
|
@ -144,7 +155,7 @@ class _PyAccess32_2(PyAccess):
|
||||||
def _post_init(self, *args, **kwargs):
|
def _post_init(self, *args, **kwargs):
|
||||||
self.pixels = ffi.cast("struct Pixel_RGBA **", self.image32)
|
self.pixels = ffi.cast("struct Pixel_RGBA **", self.image32)
|
||||||
|
|
||||||
def get_pixel(self, x, y):
|
def get_pixel(self, x: int, y: int) -> tuple[int, int]:
|
||||||
pixel = self.pixels[y][x]
|
pixel = self.pixels[y][x]
|
||||||
return pixel.r, pixel.a
|
return pixel.r, pixel.a
|
||||||
|
|
||||||
|
@ -161,7 +172,7 @@ class _PyAccess32_3(PyAccess):
|
||||||
def _post_init(self, *args, **kwargs):
|
def _post_init(self, *args, **kwargs):
|
||||||
self.pixels = ffi.cast("struct Pixel_RGBA **", self.image32)
|
self.pixels = ffi.cast("struct Pixel_RGBA **", self.image32)
|
||||||
|
|
||||||
def get_pixel(self, x, y):
|
def get_pixel(self, x: int, y: int) -> tuple[int, int, int]:
|
||||||
pixel = self.pixels[y][x]
|
pixel = self.pixels[y][x]
|
||||||
return pixel.r, pixel.g, pixel.b
|
return pixel.r, pixel.g, pixel.b
|
||||||
|
|
||||||
|
@ -180,7 +191,7 @@ class _PyAccess32_4(PyAccess):
|
||||||
def _post_init(self, *args, **kwargs):
|
def _post_init(self, *args, **kwargs):
|
||||||
self.pixels = ffi.cast("struct Pixel_RGBA **", self.image32)
|
self.pixels = ffi.cast("struct Pixel_RGBA **", self.image32)
|
||||||
|
|
||||||
def get_pixel(self, x, y):
|
def get_pixel(self, x: int, y: int) -> tuple[int, int, int, int]:
|
||||||
pixel = self.pixels[y][x]
|
pixel = self.pixels[y][x]
|
||||||
return pixel.r, pixel.g, pixel.b, pixel.a
|
return pixel.r, pixel.g, pixel.b, pixel.a
|
||||||
|
|
||||||
|
@ -199,7 +210,7 @@ class _PyAccess8(PyAccess):
|
||||||
def _post_init(self, *args, **kwargs):
|
def _post_init(self, *args, **kwargs):
|
||||||
self.pixels = self.image8
|
self.pixels = self.image8
|
||||||
|
|
||||||
def get_pixel(self, x, y):
|
def get_pixel(self, x: int, y: int) -> int:
|
||||||
return self.pixels[y][x]
|
return self.pixels[y][x]
|
||||||
|
|
||||||
def set_pixel(self, x, y, color):
|
def set_pixel(self, x, y, color):
|
||||||
|
@ -217,7 +228,7 @@ class _PyAccessI16_N(PyAccess):
|
||||||
def _post_init(self, *args, **kwargs):
|
def _post_init(self, *args, **kwargs):
|
||||||
self.pixels = ffi.cast("unsigned short **", self.image)
|
self.pixels = ffi.cast("unsigned short **", self.image)
|
||||||
|
|
||||||
def get_pixel(self, x, y):
|
def get_pixel(self, x: int, y: int) -> int:
|
||||||
return self.pixels[y][x]
|
return self.pixels[y][x]
|
||||||
|
|
||||||
def set_pixel(self, x, y, color):
|
def set_pixel(self, x, y, color):
|
||||||
|
@ -235,7 +246,7 @@ class _PyAccessI16_L(PyAccess):
|
||||||
def _post_init(self, *args, **kwargs):
|
def _post_init(self, *args, **kwargs):
|
||||||
self.pixels = ffi.cast("struct Pixel_I16 **", self.image)
|
self.pixels = ffi.cast("struct Pixel_I16 **", self.image)
|
||||||
|
|
||||||
def get_pixel(self, x, y):
|
def get_pixel(self, x: int, y: int) -> int:
|
||||||
pixel = self.pixels[y][x]
|
pixel = self.pixels[y][x]
|
||||||
return pixel.l + pixel.r * 256
|
return pixel.l + pixel.r * 256
|
||||||
|
|
||||||
|
@ -256,7 +267,7 @@ class _PyAccessI16_B(PyAccess):
|
||||||
def _post_init(self, *args, **kwargs):
|
def _post_init(self, *args, **kwargs):
|
||||||
self.pixels = ffi.cast("struct Pixel_I16 **", self.image)
|
self.pixels = ffi.cast("struct Pixel_I16 **", self.image)
|
||||||
|
|
||||||
def get_pixel(self, x, y):
|
def get_pixel(self, x: int, y: int) -> int:
|
||||||
pixel = self.pixels[y][x]
|
pixel = self.pixels[y][x]
|
||||||
return pixel.l * 256 + pixel.r
|
return pixel.l * 256 + pixel.r
|
||||||
|
|
||||||
|
@ -277,7 +288,7 @@ class _PyAccessI32_N(PyAccess):
|
||||||
def _post_init(self, *args, **kwargs):
|
def _post_init(self, *args, **kwargs):
|
||||||
self.pixels = self.image32
|
self.pixels = self.image32
|
||||||
|
|
||||||
def get_pixel(self, x, y):
|
def get_pixel(self, x: int, y: int) -> int:
|
||||||
return self.pixels[y][x]
|
return self.pixels[y][x]
|
||||||
|
|
||||||
def set_pixel(self, x, y, color):
|
def set_pixel(self, x, y, color):
|
||||||
|
@ -296,7 +307,7 @@ class _PyAccessI32_Swap(PyAccess):
|
||||||
chars[0], chars[1], chars[2], chars[3] = chars[3], chars[2], chars[1], chars[0]
|
chars[0], chars[1], chars[2], chars[3] = chars[3], chars[2], chars[1], chars[0]
|
||||||
return ffi.cast("int *", chars)[0]
|
return ffi.cast("int *", chars)[0]
|
||||||
|
|
||||||
def get_pixel(self, x, y):
|
def get_pixel(self, x: int, y: int) -> int:
|
||||||
return self.reverse(self.pixels[y][x])
|
return self.reverse(self.pixels[y][x])
|
||||||
|
|
||||||
def set_pixel(self, x, y, color):
|
def set_pixel(self, x, y, color):
|
||||||
|
@ -309,7 +320,7 @@ class _PyAccessF(PyAccess):
|
||||||
def _post_init(self, *args, **kwargs):
|
def _post_init(self, *args, **kwargs):
|
||||||
self.pixels = ffi.cast("float **", self.image32)
|
self.pixels = ffi.cast("float **", self.image32)
|
||||||
|
|
||||||
def get_pixel(self, x, y):
|
def get_pixel(self, x: int, y: int) -> float:
|
||||||
return self.pixels[y][x]
|
return self.pixels[y][x]
|
||||||
|
|
||||||
def set_pixel(self, x, y, color):
|
def set_pixel(self, x, y, color):
|
||||||
|
@ -357,7 +368,7 @@ else:
|
||||||
mode_map["I;32B"] = _PyAccessI32_N
|
mode_map["I;32B"] = _PyAccessI32_N
|
||||||
|
|
||||||
|
|
||||||
def new(img, readonly=False):
|
def new(img: Image.Image, readonly: bool = False) -> PyAccess | None:
|
||||||
access_type = mode_map.get(img.mode, None)
|
access_type = mode_map.get(img.mode, None)
|
||||||
if not access_type:
|
if not access_type:
|
||||||
logger.debug("PyAccess Not Implemented: %s", img.mode)
|
logger.debug("PyAccess Not Implemented: %s", img.mode)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user