--- /srv/rebuilderd/tmp/rebuilderdUsXdpC/inputs/python-pil-doc_11.3.0-1_all.deb +++ /srv/rebuilderd/tmp/rebuilderdUsXdpC/out/python-pil-doc_11.3.0-1_all.deb ├── file list │ @@ -1,3 +1,3 @@ │ -rw-r--r-- 0 0 0 4 2025-08-28 10:15:42.000000 debian-binary │ --rw-r--r-- 0 0 0 10040 2025-08-28 10:15:42.000000 control.tar.xz │ --rw-r--r-- 0 0 0 1128432 2025-08-28 10:15:42.000000 data.tar.xz │ +-rw-r--r-- 0 0 0 10032 2025-08-28 10:15:42.000000 control.tar.xz │ +-rw-r--r-- 0 0 0 1128444 2025-08-28 10:15:42.000000 data.tar.xz ├── control.tar.xz │ ├── control.tar │ │ ├── ./control │ │ │ @@ -1,13 +1,13 @@ │ │ │ Package: python-pil-doc │ │ │ Source: pillow │ │ │ Version: 11.3.0-1 │ │ │ Architecture: all │ │ │ Maintainer: Matthias Klose │ │ │ -Installed-Size: 17586 │ │ │ +Installed-Size: 17587 │ │ │ Depends: libjs-sphinxdoc (>= 8.2) │ │ │ Suggests: python3-doc, python3-pil, python3-pil.imagetk │ │ │ Section: doc │ │ │ Priority: optional │ │ │ Multi-Arch: foreign │ │ │ Homepage: http://python-pillow.github.io/ │ │ │ Description: Examples for the Python Imaging Library │ │ ├── ./md5sums │ │ │ ├── ./md5sums │ │ │ │┄ Files differ ├── data.tar.xz │ ├── data.tar │ │ ├── file list │ │ │ @@ -61,15 +61,15 @@ │ │ │ -rw-r--r-- 0 root (0) root (0) 55096 2025-08-28 10:15:42.000000 ./usr/share/doc/python-pil-doc/html/_modules/PIL/GimpGradientFile.html │ │ │ -rw-r--r-- 0 root (0) root (0) 41319 2025-08-28 10:15:42.000000 ./usr/share/doc/python-pil-doc/html/_modules/PIL/GimpPaletteFile.html │ │ │ -rw-r--r-- 0 root (0) root (0) 40753 2025-08-28 10:15:42.000000 ./usr/share/doc/python-pil-doc/html/_modules/PIL/GribStubImagePlugin.html │ │ │ -rw-r--r-- 0 root (0) root (0) 40768 2025-08-28 10:15:42.000000 ./usr/share/doc/python-pil-doc/html/_modules/PIL/Hdf5StubImagePlugin.html │ │ │ -rw-r--r-- 0 root (0) root (0) 103233 2025-08-28 10:15:42.000000 ./usr/share/doc/python-pil-doc/html/_modules/PIL/IcnsImagePlugin.html │ │ │ -rw-r--r-- 0 root (0) root (0) 90473 2025-08-28 10:15:42.000000 ./usr/share/doc/python-pil-doc/html/_modules/PIL/IcoImagePlugin.html │ │ │ -rw-r--r-- 0 root (0) root (0) 95842 2025-08-28 10:15:42.000000 ./usr/share/doc/python-pil-doc/html/_modules/PIL/ImImagePlugin.html │ │ │ --rw-r--r-- 0 root (0) root (0) 613970 2025-08-28 10:15:42.000000 ./usr/share/doc/python-pil-doc/html/_modules/PIL/Image.html │ │ │ +-rw-r--r-- 0 root (0) root (0) 614789 2025-08-28 10:15:42.000000 ./usr/share/doc/python-pil-doc/html/_modules/PIL/Image.html │ │ │ -rw-r--r-- 0 root (0) root (0) 68168 2025-08-28 10:15:42.000000 ./usr/share/doc/python-pil-doc/html/_modules/PIL/ImageChops.html │ │ │ -rw-r--r-- 0 root (0) root (0) 151466 2025-08-28 10:15:42.000000 ./usr/share/doc/python-pil-doc/html/_modules/PIL/ImageCms.html │ │ │ -rw-r--r-- 0 root (0) root (0) 80194 2025-08-28 10:15:42.000000 ./usr/share/doc/python-pil-doc/html/_modules/PIL/ImageColor.html │ │ │ -rw-r--r-- 0 root (0) root (0) 229250 2025-08-28 10:15:42.000000 ./usr/share/doc/python-pil-doc/html/_modules/PIL/ImageDraw.html │ │ │ -rw-r--r-- 0 root (0) root (0) 68301 2025-08-28 10:15:42.000000 ./usr/share/doc/python-pil-doc/html/_modules/PIL/ImageDraw2.html │ │ │ -rw-r--r-- 0 root (0) root (0) 47038 2025-08-28 10:15:42.000000 ./usr/share/doc/python-pil-doc/html/_modules/PIL/ImageEnhance.html │ │ │ -rw-r--r-- 0 root (0) root (0) 158882 2025-08-28 10:15:42.000000 ./usr/share/doc/python-pil-doc/html/_modules/PIL/ImageFile.html │ │ ├── ./usr/share/doc/python-pil-doc/html/_modules/PIL/Image.html │ │ │ @@ -512,41 +512,41 @@ │ │ │ │ │ │ # │ │ │ # Constants │ │ │ │ │ │ │ │ │ # transpose │ │ │
│ │ │ -[docs] │ │ │ +[docs] │ │ │ class Transpose(IntEnum): │ │ │ FLIP_LEFT_RIGHT = 0 │ │ │ FLIP_TOP_BOTTOM = 1 │ │ │ ROTATE_90 = 2 │ │ │ ROTATE_180 = 3 │ │ │ ROTATE_270 = 4 │ │ │ TRANSPOSE = 5 │ │ │ TRANSVERSE = 6
│ │ │ │ │ │ │ │ │ │ │ │ # transforms (also defined in Imaging.h) │ │ │
│ │ │ -[docs] │ │ │ +[docs] │ │ │ class Transform(IntEnum): │ │ │ AFFINE = 0 │ │ │ EXTENT = 1 │ │ │ PERSPECTIVE = 2 │ │ │ QUAD = 3 │ │ │ MESH = 4
│ │ │ │ │ │ │ │ │ │ │ │ # resampling filters (also defined in Imaging.h) │ │ │
│ │ │ -[docs] │ │ │ +[docs] │ │ │ class Resampling(IntEnum): │ │ │ NEAREST = 0 │ │ │ BOX = 4 │ │ │ BILINEAR = 2 │ │ │ HAMMING = 5 │ │ │ BICUBIC = 3 │ │ │ LANCZOS = 1
│ │ │ @@ -560,34 +560,34 @@ │ │ │ Resampling.BICUBIC: 2.0, │ │ │ Resampling.LANCZOS: 3.0, │ │ │ } │ │ │ │ │ │ │ │ │ # dithers │ │ │
│ │ │ -[docs] │ │ │ +[docs] │ │ │ class Dither(IntEnum): │ │ │ NONE = 0 │ │ │ ORDERED = 1 # Not yet implemented │ │ │ RASTERIZE = 2 # Not yet implemented │ │ │ FLOYDSTEINBERG = 3 # default
│ │ │ │ │ │ │ │ │ │ │ │ # palettes/quantizers │ │ │
│ │ │ -[docs] │ │ │ +[docs] │ │ │ class Palette(IntEnum): │ │ │ WEB = 0 │ │ │ ADAPTIVE = 1
│ │ │ │ │ │ │ │ │ │ │ │
│ │ │ -[docs] │ │ │ +[docs] │ │ │ class Quantize(IntEnum): │ │ │ MEDIANCUT = 0 │ │ │ MAXCOVERAGE = 1 │ │ │ FASTOCTREE = 2 │ │ │ LIBIMAGEQUANT = 3
│ │ │ │ │ │ │ │ │ @@ -730,15 +730,15 @@ │ │ │ # -------------------------------------------------------------------- │ │ │ # Helpers │ │ │ │ │ │ _initialized = 0 │ │ │ │ │ │ │ │ │
│ │ │ -[docs] │ │ │ +[docs] │ │ │ def preinit() -> None: │ │ │ """ │ │ │ Explicitly loads BMP, GIF, JPEG, PPM and PPM file format drivers. │ │ │ │ │ │ It is called when opening or saving images. │ │ │ """ │ │ │ │ │ │ @@ -778,15 +778,15 @@ │ │ │ pass │ │ │ │ │ │ _initialized = 1
│ │ │ │ │ │ │ │ │ │ │ │
│ │ │ -[docs] │ │ │ +[docs] │ │ │ def init() -> bool: │ │ │ """ │ │ │ Explicitly initializes the Python Imaging Library. This function │ │ │ loads all available file format drivers. │ │ │ │ │ │ It is called when opening or saving images if :py:meth:`~preinit()` is │ │ │ insufficient, and by :py:meth:`~PIL.features.pilinfo`. │ │ │ @@ -866,15 +866,15 @@ │ │ │ │ │ │ │ │ │ # -------------------------------------------------------------------- │ │ │ # Simple expression analyzer │ │ │ │ │ │ │ │ │
│ │ │ -[docs] │ │ │ +[docs] │ │ │ class ImagePointTransform: │ │ │ """ │ │ │ Used with :py:meth:`~PIL.Image.Image.point` for single band images with more than │ │ │ 8 bits, this represents an affine transformation, where the value is multiplied by │ │ │ ``scale`` and ``offset`` is added. │ │ │ """ │ │ │ │ │ │ @@ -922,24 +922,24 @@ │ │ │ │ │ │ │ │ │ # -------------------------------------------------------------------- │ │ │ # Implementation wrapper │ │ │ │ │ │ │ │ │
│ │ │ -[docs] │ │ │ +[docs] │ │ │ class SupportsGetData(Protocol): │ │ │ def getdata( │ │ │ self, │ │ │ ) -> tuple[Transform, Sequence[int]]: ...
│ │ │ │ │ │ │ │ │ │ │ │
│ │ │ -[docs] │ │ │ +[docs] │ │ │ class Image: │ │ │ """ │ │ │ This class represents an image object. To create │ │ │ :py:class:`~PIL.Image.Image` objects, use the appropriate factory │ │ │ functions. There's hardly ever any reason to call the Image constructor │ │ │ directly. │ │ │ │ │ │ @@ -1021,15 +1021,15 @@ │ │ │ │ │ │ if isinstance(self, ImageFile.ImageFile): │ │ │ if getattr(self, "_exclusive_fp", False): │ │ │ self._close_fp() │ │ │ self.fp = None │ │ │ │ │ │
│ │ │ -[docs] │ │ │ +[docs] │ │ │ def close(self) -> None: │ │ │ """ │ │ │ This operation will destroy the image core and release its memory. │ │ │ The image data will be unusable afterward. │ │ │ │ │ │ This function is required to close images that have multiple frames or │ │ │ have not had their file read and closed by the │ │ │ @@ -1173,15 +1173,15 @@ │ │ │ self._size = size │ │ │ self.im = core.new(mode, size) │ │ │ if mode in ("L", "LA", "P", "PA") and palette: │ │ │ self.putpalette(palette) │ │ │ self.frombytes(data) │ │ │ │ │ │
│ │ │ -[docs] │ │ │ +[docs] │ │ │ def tobytes(self, encoder_name: str = "raw", *args: Any) -> bytes: │ │ │ """ │ │ │ Return image as a bytes object. │ │ │ │ │ │ .. warning:: │ │ │ │ │ │ This method returns raw image data derived from Pillow's internal │ │ │ @@ -1233,15 +1233,15 @@ │ │ │ msg = f"encoder error {errcode} in tobytes" │ │ │ raise RuntimeError(msg) │ │ │ │ │ │ return b"".join(output)
│ │ │ │ │ │ │ │ │
│ │ │ -[docs] │ │ │ +[docs] │ │ │ def tobitmap(self, name: str = "image") -> bytes: │ │ │ """ │ │ │ Returns the image converted to an X11 bitmap. │ │ │ │ │ │ .. note:: This method only works for mode "1" images. │ │ │ │ │ │ :param name: The name prefix to use for the bitmap variables. │ │ │ @@ -1262,15 +1262,15 @@ │ │ │ data, │ │ │ b"};", │ │ │ ] │ │ │ )
│ │ │ │ │ │ │ │ │
│ │ │ -[docs] │ │ │ +[docs] │ │ │ def frombytes( │ │ │ self, │ │ │ data: bytes | bytearray | SupportsArrayInterface, │ │ │ decoder_name: str = "raw", │ │ │ *args: Any, │ │ │ ) -> None: │ │ │ """ │ │ │ @@ -1302,15 +1302,15 @@ │ │ │ raise ValueError(msg) │ │ │ if s[1] != 0: │ │ │ msg = "cannot decode image data" │ │ │ raise ValueError(msg)
│ │ │ │ │ │ │ │ │
│ │ │ -[docs] │ │ │ +[docs] │ │ │ def load(self) -> core.PixelAccess | None: │ │ │ """ │ │ │ Allocates storage for the image and loads the pixel data. In │ │ │ normal cases, you don't need to call this method, since the │ │ │ Image class automatically loads an opened image when it is │ │ │ accessed for the first time. │ │ │ │ │ │ @@ -1341,29 +1341,29 @@ │ │ │ │ │ │ if self._im is not None: │ │ │ return self.im.pixel_access(self.readonly) │ │ │ return None
│ │ │ │ │ │ │ │ │
│ │ │ -[docs] │ │ │ +[docs] │ │ │ def verify(self) -> None: │ │ │ """ │ │ │ Verifies the contents of a file. For data read from a file, this │ │ │ method attempts to determine if the file is broken, without │ │ │ actually decoding the image data. If this method finds any │ │ │ problems, it raises suitable exceptions. If you need to load │ │ │ the image after using this method, you must reopen the image │ │ │ file. │ │ │ """ │ │ │ pass
│ │ │ │ │ │ │ │ │
│ │ │ -[docs] │ │ │ +[docs] │ │ │ def convert( │ │ │ self, │ │ │ mode: str | None = None, │ │ │ matrix: tuple[float, ...] | None = None, │ │ │ dither: Dither | None = None, │ │ │ palette: Palette = Palette.WEB, │ │ │ colors: int = 256, │ │ │ @@ -1611,15 +1611,15 @@ │ │ │ ) │ │ │ else: │ │ │ new_im.info["transparency"] = trns │ │ │ return new_im
│ │ │ │ │ │ │ │ │
│ │ │ -[docs] │ │ │ +[docs] │ │ │ def quantize( │ │ │ self, │ │ │ colors: int = 256, │ │ │ method: int | None = None, │ │ │ kmeans: int = 0, │ │ │ palette: Image | None = None, │ │ │ dither: Dither = Dither.FLOYDSTEINBERG, │ │ │ @@ -1697,15 +1697,15 @@ │ │ │ palette_data = im.im.getpalette(mode, mode)[: colors * len(mode)] │ │ │ im.palette = ImagePalette.ImagePalette(mode, palette_data) │ │ │ │ │ │ return im
│ │ │ │ │ │ │ │ │
│ │ │ -[docs] │ │ │ +[docs] │ │ │ def copy(self) -> Image: │ │ │ """ │ │ │ Copies this image. Use this method if you wish to paste things │ │ │ into an image, but still retain the original. │ │ │ │ │ │ :rtype: :py:class:`~PIL.Image.Image` │ │ │ :returns: An :py:class:`~PIL.Image.Image` object. │ │ │ @@ -1713,15 +1713,15 @@ │ │ │ self.load() │ │ │ return self._new(self.im.copy())
│ │ │ │ │ │ │ │ │ __copy__ = copy │ │ │ │ │ │
│ │ │ -[docs] │ │ │ +[docs] │ │ │ def crop(self, box: tuple[float, float, float, float] | None = None) -> Image: │ │ │ """ │ │ │ Returns a rectangular region from this image. The box is a │ │ │ 4-tuple defining the left, upper, right, and lower pixel │ │ │ coordinate. See :ref:`coordinate-system`. │ │ │ │ │ │ Note: Prior to Pillow 3.4.0, this was a lazy operation. │ │ │ @@ -1764,15 +1764,15 @@ │ │ │ absolute_values = (abs(x1 - x0), abs(y1 - y0)) │ │ │ │ │ │ _decompression_bomb_check(absolute_values) │ │ │ │ │ │ return im.crop((x0, y0, x1, y1)) │ │ │ │ │ │
│ │ │ -[docs] │ │ │ +[docs] │ │ │ def draft( │ │ │ self, mode: str | None, size: tuple[int, int] | None │ │ │ ) -> tuple[str, tuple[int, int, float, float]] | None: │ │ │ """ │ │ │ Configures the image file loader so it returns a version of the │ │ │ image that as closely as possible matches the given mode and │ │ │ size. For example, you can use this method to convert a color │ │ │ @@ -1798,15 +1798,15 @@ │ │ │ def _expand(self, xmargin: int, ymargin: int | None = None) -> Image: │ │ │ if ymargin is None: │ │ │ ymargin = xmargin │ │ │ self.load() │ │ │ return self._new(self.im.expand(xmargin, ymargin)) │ │ │ │ │ │
│ │ │ -[docs] │ │ │ +[docs] │ │ │ def filter(self, filter: ImageFilter.Filter | type[ImageFilter.Filter]) -> Image: │ │ │ """ │ │ │ Filters this image using the given filter. For a list of │ │ │ available filters, see the :py:mod:`~PIL.ImageFilter` module. │ │ │ │ │ │ :param filter: Filter kernel. │ │ │ :returns: An :py:class:`~PIL.Image.Image` object.""" │ │ │ @@ -1828,28 +1828,28 @@ │ │ │ ims = [ │ │ │ self._new(filter.filter(self.im.getband(c))) for c in range(self.im.bands) │ │ │ ] │ │ │ return merge(self.mode, ims)
│ │ │ │ │ │ │ │ │
│ │ │ -[docs] │ │ │ +[docs] │ │ │ def getbands(self) -> tuple[str, ...]: │ │ │ """ │ │ │ Returns a tuple containing the name of each band in this image. │ │ │ For example, ``getbands`` on an RGB image returns ("R", "G", "B"). │ │ │ │ │ │ :returns: A tuple containing band names. │ │ │ :rtype: tuple │ │ │ """ │ │ │ return ImageMode.getmode(self.mode).bands
│ │ │ │ │ │ │ │ │
│ │ │ -[docs] │ │ │ +[docs] │ │ │ def getbbox(self, *, alpha_only: bool = True) -> tuple[int, int, int, int] | None: │ │ │ """ │ │ │ Calculates the bounding box of the non-zero regions in the │ │ │ image. │ │ │ │ │ │ :param alpha_only: Optional flag, defaulting to ``True``. │ │ │ If ``True`` and the image has an alpha channel, trim transparent pixels. │ │ │ @@ -1863,15 +1863,15 @@ │ │ │ """ │ │ │ │ │ │ self.load() │ │ │ return self.im.getbbox(alpha_only)
│ │ │ │ │ │ │ │ │
│ │ │ -[docs] │ │ │ +[docs] │ │ │ def getcolors( │ │ │ self, maxcolors: int = 256 │ │ │ ) -> list[tuple[int, tuple[int, ...]]] | list[tuple[int, float]] | None: │ │ │ """ │ │ │ Returns a list of colors used in this image. │ │ │ │ │ │ The colors will be in the image's mode. For example, an RGB image will │ │ │ @@ -1891,15 +1891,15 @@ │ │ │ if len(out) > maxcolors: │ │ │ return None │ │ │ return out │ │ │ return self.im.getcolors(maxcolors)
│ │ │ │ │ │ │ │ │
│ │ │ -[docs] │ │ │ +[docs] │ │ │ def getdata(self, band: int | None = None) -> core.ImagingCore: │ │ │ """ │ │ │ Returns the contents of this image as a sequence object │ │ │ 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. │ │ │ │ │ │ @@ -1917,15 +1917,15 @@ │ │ │ self.load() │ │ │ if band is not None: │ │ │ return self.im.getband(band) │ │ │ return self.im # could be abused
│ │ │ │ │ │ │ │ │
│ │ │ -[docs] │ │ │ +[docs] │ │ │ def getextrema(self) -> tuple[float, float] | tuple[tuple[int, int], ...]: │ │ │ """ │ │ │ Gets the minimum and maximum pixel values for each band in │ │ │ the image. │ │ │ │ │ │ :returns: For a single-band image, a 2-tuple containing the │ │ │ minimum and maximum pixel value. For a multi-band image, │ │ │ @@ -1935,15 +1935,15 @@ │ │ │ self.load() │ │ │ if self.im.bands > 1: │ │ │ return tuple(self.im.getband(i).getextrema() for i in range(self.im.bands)) │ │ │ return self.im.getextrema()
│ │ │ │ │ │ │ │ │
│ │ │ -[docs] │ │ │ +[docs] │ │ │ def getxmp(self) -> dict[str, Any]: │ │ │ """ │ │ │ Returns a dictionary containing the XMP tags. │ │ │ Requires defusedxml to be installed. │ │ │ │ │ │ :returns: XMP tags in a dictionary. │ │ │ """ │ │ │ @@ -1977,15 +1977,15 @@ │ │ │ if "xmp" not in self.info: │ │ │ return {} │ │ │ root = ElementTree.fromstring(self.info["xmp"].rstrip(b"\x00 ")) │ │ │ return {get_name(root.tag): get_value(root)}
│ │ │ │ │ │ │ │ │
│ │ │ -[docs] │ │ │ +[docs] │ │ │ def getexif(self) -> Exif: │ │ │ """ │ │ │ Gets EXIF data from the image. │ │ │ │ │ │ :returns: an :py:class:`~PIL.Image.Exif` object. │ │ │ """ │ │ │ if self._exif is None: │ │ │ @@ -2040,15 +2040,15 @@ │ │ │ :returns: A capsule object. │ │ │ """ │ │ │ │ │ │ self.load() │ │ │ return self.im.ptr │ │ │ │ │ │
│ │ │ -[docs] │ │ │ +[docs] │ │ │ def getpalette(self, rawmode: str | None = "RGB") -> list[int] | None: │ │ │ """ │ │ │ Returns the image palette as a list. │ │ │ │ │ │ :param rawmode: The mode in which to return the palette. ``None`` will │ │ │ return the palette in its current mode. │ │ │ │ │ │ @@ -2087,15 +2087,15 @@ │ │ │ return True │ │ │ if self.mode == "P": │ │ │ assert self.palette is not None │ │ │ return self.palette.mode.endswith("A") │ │ │ return False │ │ │ │ │ │
│ │ │ -[docs] │ │ │ +[docs] │ │ │ def apply_transparency(self) -> None: │ │ │ """ │ │ │ If a P mode image has a "transparency" key in the info dictionary, │ │ │ remove the key and instead apply the transparency to the palette. │ │ │ Otherwise, the image is unchanged. │ │ │ """ │ │ │ if self.mode != "P" or "transparency" not in self.info: │ │ │ @@ -2114,15 +2114,15 @@ │ │ │ self.palette = ImagePalette.ImagePalette("RGBA", bytes(palette)) │ │ │ self.palette.dirty = 1 │ │ │ │ │ │ del self.info["transparency"]
│ │ │ │ │ │ │ │ │
│ │ │ -[docs] │ │ │ +[docs] │ │ │ def getpixel( │ │ │ self, xy: tuple[int, int] | list[int] │ │ │ ) -> float | tuple[int, ...] | None: │ │ │ """ │ │ │ Returns the pixel value at a given position. │ │ │ │ │ │ :param xy: The coordinate, given as (x, y). See │ │ │ @@ -2132,30 +2132,30 @@ │ │ │ """ │ │ │ │ │ │ self.load() │ │ │ return self.im.getpixel(tuple(xy))
│ │ │ │ │ │ │ │ │
│ │ │ -[docs] │ │ │ +[docs] │ │ │ def getprojection(self) -> tuple[list[int], list[int]]: │ │ │ """ │ │ │ Get projection to x and y axes │ │ │ │ │ │ :returns: Two sequences, indicating where there are non-zero │ │ │ pixels along the X-axis and the Y-axis, respectively. │ │ │ """ │ │ │ │ │ │ self.load() │ │ │ x, y = self.im.getprojection() │ │ │ return list(x), list(y)
│ │ │ │ │ │ │ │ │
│ │ │ -[docs] │ │ │ +[docs] │ │ │ def histogram( │ │ │ self, mask: Image | None = None, extrema: tuple[float, float] | None = None │ │ │ ) -> list[int]: │ │ │ """ │ │ │ Returns a histogram for the image. The histogram is returned as a │ │ │ list of pixel counts, one for each pixel value in the source │ │ │ image. Counts are grouped into 256 bins for each band, even if │ │ │ @@ -2183,15 +2183,15 @@ │ │ │ return self.im.histogram( │ │ │ extrema if extrema is not None else self.getextrema() │ │ │ ) │ │ │ return self.im.histogram()
│ │ │ │ │ │ │ │ │
│ │ │ -[docs] │ │ │ +[docs] │ │ │ def entropy( │ │ │ self, mask: Image | None = None, extrema: tuple[float, float] | None = None │ │ │ ) -> float: │ │ │ """ │ │ │ Calculates and returns the entropy for the image. │ │ │ │ │ │ A bilevel image (mode "1") is treated as a grayscale ("L") │ │ │ @@ -2214,15 +2214,15 @@ │ │ │ return self.im.entropy( │ │ │ extrema if extrema is not None else self.getextrema() │ │ │ ) │ │ │ return self.im.entropy()
│ │ │ │ │ │ │ │ │
│ │ │ -[docs] │ │ │ +[docs] │ │ │ def paste( │ │ │ self, │ │ │ im: Image | str | float | tuple[float, ...], │ │ │ box: Image | tuple[int, int, int, int] | tuple[int, int] | None = None, │ │ │ mask: Image | None = None, │ │ │ ) -> None: │ │ │ """ │ │ │ @@ -2308,15 +2308,15 @@ │ │ │ mask.load() │ │ │ self.im.paste(source, box, mask.im) │ │ │ else: │ │ │ self.im.paste(source, box)
│ │ │ │ │ │ │ │ │
│ │ │ -[docs] │ │ │ +[docs] │ │ │ def alpha_composite( │ │ │ self, im: Image, dest: Sequence[int] = (0, 0), source: Sequence[int] = (0, 0) │ │ │ ) -> None: │ │ │ """'In-place' analog of Image.alpha_composite. Composites an image │ │ │ onto this image. │ │ │ │ │ │ :param im: image to composite over this one │ │ │ @@ -2367,15 +2367,15 @@ │ │ │ background = self.crop(box) │ │ │ │ │ │ result = alpha_composite(background, overlay) │ │ │ self.paste(result, box)
│ │ │ │ │ │ │ │ │
│ │ │ -[docs] │ │ │ +[docs] │ │ │ def point( │ │ │ self, │ │ │ lut: ( │ │ │ Sequence[float] │ │ │ | NumpyArray │ │ │ | Callable[[int], float] │ │ │ | Callable[[ImagePointTransform], ImagePointTransform | float] │ │ │ @@ -2430,15 +2430,15 @@ │ │ │ │ │ │ if mode != "F": │ │ │ flatLut = [round(i) for i in flatLut] │ │ │ return self._new(self.im.point(flatLut, mode))
│ │ │ │ │ │ │ │ │
│ │ │ -[docs] │ │ │ +[docs] │ │ │ def putalpha(self, alpha: Image | int) -> None: │ │ │ """ │ │ │ Adds or replaces the alpha layer in this image. If the image │ │ │ does not have an alpha layer, it's converted to "LA" or "RGBA". │ │ │ The new layer must be either "L" or "1". │ │ │ │ │ │ :param alpha: The new alpha layer. This can either be an "L" or "1" │ │ │ @@ -2488,15 +2488,15 @@ │ │ │ else: │ │ │ return │ │ │ │ │ │ self.im.putband(alpha.im, band)
│ │ │ │ │ │ │ │ │
│ │ │ -[docs] │ │ │ +[docs] │ │ │ def putdata( │ │ │ self, │ │ │ data: Sequence[float] | Sequence[Sequence[int]] | core.ImagingCore | NumpyArray, │ │ │ scale: float = 1.0, │ │ │ offset: float = 0.0, │ │ │ ) -> None: │ │ │ """ │ │ │ @@ -2514,15 +2514,15 @@ │ │ │ │ │ │ self._ensure_mutable() │ │ │ │ │ │ self.im.putdata(data, scale, offset)
│ │ │ │ │ │ │ │ │
│ │ │ -[docs] │ │ │ +[docs] │ │ │ def putpalette( │ │ │ self, │ │ │ data: ImagePalette.ImagePalette | bytes | Sequence[int], │ │ │ rawmode: str = "RGB", │ │ │ ) -> None: │ │ │ """ │ │ │ Attaches a palette to this image. The image must be a "P", "PA", "L" │ │ │ @@ -2560,15 +2560,15 @@ │ │ │ self._mode = "PA" if "A" in self.mode else "P" │ │ │ self.palette = palette │ │ │ self.palette.mode = "RGBA" if "A" in rawmode else "RGB" │ │ │ self.load() # install new palette
│ │ │ │ │ │ │ │ │
│ │ │ -[docs] │ │ │ +[docs] │ │ │ def putpixel( │ │ │ self, xy: tuple[int, int], value: float | tuple[int, ...] | list[int] │ │ │ ) -> None: │ │ │ """ │ │ │ Modifies the pixel at the given position. The color is given as │ │ │ a single numerical value for single-band images, and a tuple for │ │ │ multi-band images. In addition to this, RGB and RGBA tuples are │ │ │ @@ -2605,15 +2605,15 @@ │ │ │ assert self.palette is not None │ │ │ palette_index = self.palette.getcolor(tuple(value), self) │ │ │ value = (palette_index, alpha) if self.mode == "PA" else palette_index │ │ │ return self.im.putpixel(xy, value)
│ │ │ │ │ │ │ │ │
│ │ │ -[docs] │ │ │ +[docs] │ │ │ def remap_palette( │ │ │ self, dest_map: list[int], source_palette: bytes | bytearray | None = None │ │ │ ) -> Image: │ │ │ """ │ │ │ Rewrites the image to reorder the palette. │ │ │ │ │ │ :param dest_map: A list of indexes into the original palette. │ │ │ @@ -2720,15 +2720,15 @@ │ │ │ max(0, int(box[0] - support_x)), │ │ │ max(0, int(box[1] - support_y)), │ │ │ min(self.size[0], math.ceil(box[2] + support_x)), │ │ │ min(self.size[1], math.ceil(box[3] + support_y)), │ │ │ ) │ │ │ │ │ │
│ │ │ -[docs] │ │ │ +[docs] │ │ │ def resize( │ │ │ self, │ │ │ size: tuple[int, int] | list[int] | NumpyArray, │ │ │ resample: int | None = None, │ │ │ box: tuple[float, float, float, float] | None = None, │ │ │ reducing_gap: float | None = None, │ │ │ ) -> Image: │ │ │ @@ -2831,15 +2831,15 @@ │ │ │ (box[3] - reduce_box[1]) / factor_y, │ │ │ ) │ │ │ │ │ │ return self._new(self.im.resize(size, resample, box))
│ │ │ │ │ │ │ │ │
│ │ │ -[docs] │ │ │ +[docs] │ │ │ def reduce( │ │ │ self, │ │ │ factor: int | tuple[int, int], │ │ │ box: tuple[int, int, int, int] | None = None, │ │ │ ) -> Image: │ │ │ """ │ │ │ Returns a copy of the image reduced ``factor`` times. │ │ │ @@ -2869,15 +2869,15 @@ │ │ │ │ │ │ self.load() │ │ │ │ │ │ return self._new(self.im.reduce(factor, box))
│ │ │ │ │ │ │ │ │
│ │ │ -[docs] │ │ │ +[docs] │ │ │ def rotate( │ │ │ self, │ │ │ angle: float, │ │ │ resample: Resampling = Resampling.NEAREST, │ │ │ expand: int | bool = False, │ │ │ center: tuple[float, float] | None = None, │ │ │ translate: tuple[int, int] | None = None, │ │ │ @@ -2988,15 +2988,15 @@ │ │ │ │ │ │ return self.transform( │ │ │ (w, h), Transform.AFFINE, matrix, resample, fillcolor=fillcolor │ │ │ )
│ │ │ │ │ │ │ │ │
│ │ │ -[docs] │ │ │ +[docs] │ │ │ def save( │ │ │ self, fp: StrOrBytesPath | IO[bytes], format: str | None = None, **params: Any │ │ │ ) -> None: │ │ │ """ │ │ │ Saves this image under the given filename. If no format is │ │ │ specified, the format to use is determined from the filename │ │ │ extension, if possible. │ │ │ @@ -3125,15 +3125,15 @@ │ │ │ │ │ │ def _attach_default_encoderinfo(self, im: Image) -> dict[str, Any]: │ │ │ encoderinfo = getattr(self, "encoderinfo", {}) │ │ │ self.encoderinfo = {**im._default_encoderinfo, **encoderinfo} │ │ │ return encoderinfo │ │ │ │ │ │
│ │ │ -[docs] │ │ │ +[docs] │ │ │ def seek(self, frame: int) -> None: │ │ │ """ │ │ │ Seeks to the given frame in this sequence file. If you seek │ │ │ beyond the end of the sequence, the method raises an │ │ │ ``EOFError`` exception. When a sequence file is opened, the │ │ │ library automatically seeks to frame 0. │ │ │ │ │ │ @@ -3150,15 +3150,15 @@ │ │ │ # overridden by file handlers │ │ │ if frame != 0: │ │ │ msg = "no more images in file" │ │ │ raise EOFError(msg)
│ │ │ │ │ │ │ │ │
│ │ │ -[docs] │ │ │ +[docs] │ │ │ def show(self, title: str | None = None) -> None: │ │ │ """ │ │ │ Displays this image. This method is mainly intended for debugging purposes. │ │ │ │ │ │ This method calls :py:func:`PIL.ImageShow.show` internally. You can use │ │ │ :py:func:`PIL.ImageShow.register` to override its default behaviour. │ │ │ │ │ │ @@ -3175,15 +3175,15 @@ │ │ │ :param title: Optional title to use for the image window, where possible. │ │ │ """ │ │ │ │ │ │ _show(self, title=title)
│ │ │ │ │ │ │ │ │
│ │ │ -[docs] │ │ │ +[docs] │ │ │ def split(self) -> tuple[Image, ...]: │ │ │ """ │ │ │ Split this image into individual bands. This method returns a │ │ │ tuple of individual image bands from an image. For example, │ │ │ splitting an "RGB" image creates three new images each │ │ │ containing a copy of one of the original bands (red, green, │ │ │ blue). │ │ │ @@ -3197,15 +3197,15 @@ │ │ │ self.load() │ │ │ if self.im.bands == 1: │ │ │ return (self.copy(),) │ │ │ return tuple(map(self._new, self.im.split()))
│ │ │ │ │ │ │ │ │
│ │ │ -[docs] │ │ │ +[docs] │ │ │ def getchannel(self, channel: int | str) -> Image: │ │ │ """ │ │ │ Returns an image containing a single channel of the source image. │ │ │ │ │ │ :param channel: What channel to return. Could be index │ │ │ (0 for "R" channel of "RGB") or channel name │ │ │ ("A" for alpha channel of "RGBA"). │ │ │ @@ -3222,29 +3222,29 @@ │ │ │ msg = f'The image has no channel "{channel}"' │ │ │ raise ValueError(msg) from e │ │ │ │ │ │ return self._new(self.im.getband(channel))
│ │ │ │ │ │ │ │ │
│ │ │ -[docs] │ │ │ +[docs] │ │ │ def tell(self) -> int: │ │ │ """ │ │ │ Returns the current frame number. See :py:meth:`~PIL.Image.Image.seek`. │ │ │ │ │ │ If defined, :attr:`~PIL.Image.Image.n_frames` refers to the │ │ │ number of available frames. │ │ │ │ │ │ :returns: Frame number, starting with 0. │ │ │ """ │ │ │ return 0
│ │ │ │ │ │ │ │ │
│ │ │ -[docs] │ │ │ +[docs] │ │ │ def thumbnail( │ │ │ self, │ │ │ size: tuple[float, float], │ │ │ resample: Resampling = Resampling.BICUBIC, │ │ │ reducing_gap: float | None = 2.0, │ │ │ ) -> None: │ │ │ """ │ │ │ @@ -3327,15 +3327,15 @@ │ │ │ │ │ │ self.readonly = 0
│ │ │ │ │ │ │ │ │ # FIXME: the different transform methods need further explanation │ │ │ # instead of bloating the method docs, add a separate chapter. │ │ │
│ │ │ -[docs] │ │ │ +[docs] │ │ │ def transform( │ │ │ self, │ │ │ size: tuple[int, int], │ │ │ method: Transform | ImageTransformHandler | SupportsGetData, │ │ │ data: Sequence[Any] | None = None, │ │ │ resample: int = Resampling.NEAREST, │ │ │ fill: int = 1, │ │ │ @@ -3510,15 +3510,15 @@ │ │ │ │ │ │ if image.mode in ("1", "P"): │ │ │ resample = Resampling.NEAREST │ │ │ │ │ │ self.im.transform(box, image.im, method, data, resample, fill) │ │ │ │ │ │
│ │ │ -[docs] │ │ │ +[docs] │ │ │ def transpose(self, method: Transpose) -> Image: │ │ │ """ │ │ │ Transpose image (flip or rotate in 90 degree steps) │ │ │ │ │ │ :param method: One of :py:data:`Transpose.FLIP_LEFT_RIGHT`, │ │ │ :py:data:`Transpose.FLIP_TOP_BOTTOM`, :py:data:`Transpose.ROTATE_90`, │ │ │ :py:data:`Transpose.ROTATE_180`, :py:data:`Transpose.ROTATE_270`, │ │ │ @@ -3527,15 +3527,15 @@ │ │ │ """ │ │ │ │ │ │ self.load() │ │ │ return self._new(self.im.transpose(method))
│ │ │ │ │ │ │ │ │
│ │ │ -[docs] │ │ │ +[docs] │ │ │ def effect_spread(self, distance: int) -> Image: │ │ │ """ │ │ │ Randomly spread pixels in an image. │ │ │ │ │ │ :param distance: Distance to spread pixels. │ │ │ """ │ │ │ self.load() │ │ │ @@ -3563,29 +3563,29 @@ │ │ │ │ │ │ │ │ │ # -------------------------------------------------------------------- │ │ │ # Abstract handlers. │ │ │ │ │ │ │ │ │
│ │ │ -[docs] │ │ │ +[docs] │ │ │ class ImagePointHandler(abc.ABC): │ │ │ """ │ │ │ Used as a mixin by point transforms │ │ │ (for use with :py:meth:`~PIL.Image.Image.point`) │ │ │ """ │ │ │ │ │ │ @abc.abstractmethod │ │ │ def point(self, im: Image) -> Image: │ │ │ pass
│ │ │ │ │ │ │ │ │ │ │ │
│ │ │ -[docs] │ │ │ +[docs] │ │ │ class ImageTransformHandler(abc.ABC): │ │ │ """ │ │ │ Used as a mixin by geometry transforms │ │ │ (for use with :py:meth:`~PIL.Image.Image.transform`) │ │ │ """ │ │ │ │ │ │ @abc.abstractmethod │ │ │ @@ -3619,15 +3619,15 @@ │ │ │ raise ValueError(msg) │ │ │ if size[0] < 0 or size[1] < 0: │ │ │ msg = "Width and height must be >= 0" │ │ │ raise ValueError(msg) │ │ │ │ │ │ │ │ │
│ │ │ -[docs] │ │ │ +[docs] │ │ │ def new( │ │ │ mode: str, │ │ │ size: tuple[int, int] | list[int], │ │ │ color: float | tuple[float, ...] | str | None = 0, │ │ │ ) -> Image: │ │ │ """ │ │ │ Creates a new image with the given mode and size. │ │ │ @@ -3674,15 +3674,15 @@ │ │ │ im.palette = ImagePalette.ImagePalette() │ │ │ color = im.palette.getcolor(color_ints) │ │ │ return im._new(core.fill(mode, size, color))
│ │ │ │ │ │ │ │ │ │ │ │
│ │ │ -[docs] │ │ │ +[docs] │ │ │ def frombytes( │ │ │ mode: str, │ │ │ size: tuple[int, int], │ │ │ data: bytes | bytearray | SupportsArrayInterface, │ │ │ decoder_name: str = "raw", │ │ │ *args: Any, │ │ │ ) -> Image: │ │ │ @@ -3723,15 +3723,15 @@ │ │ │ │ │ │ im.frombytes(data, decoder_name, decoder_args) │ │ │ return im
│ │ │ │ │ │ │ │ │ │ │ │
│ │ │ -[docs] │ │ │ +[docs] │ │ │ def frombuffer( │ │ │ mode: str, │ │ │ size: tuple[int, int], │ │ │ data: bytes | SupportsArrayInterface, │ │ │ decoder_name: str = "raw", │ │ │ *args: Any, │ │ │ ) -> Image: │ │ │ @@ -3788,43 +3788,43 @@ │ │ │ return im │ │ │ │ │ │ return frombytes(mode, size, data, decoder_name, args)
│ │ │ │ │ │ │ │ │ │ │ │
│ │ │ -[docs] │ │ │ +[docs] │ │ │ class SupportsArrayInterface(Protocol): │ │ │ """ │ │ │ An object that has an ``__array_interface__`` dictionary. │ │ │ """ │ │ │ │ │ │ @property │ │ │ def __array_interface__(self) -> dict[str, Any]: │ │ │ raise NotImplementedError()
│ │ │ │ │ │ │ │ │ │ │ │
│ │ │ -[docs] │ │ │ +[docs] │ │ │ class SupportsArrowArrayInterface(Protocol): │ │ │ """ │ │ │ An object that has an ``__arrow_c_array__`` method corresponding to the arrow c │ │ │ data interface. │ │ │ """ │ │ │ │ │ │ def __arrow_c_array__( │ │ │ self, requested_schema: "PyCapsule" = None # type: ignore[name-defined] # noqa: F821, UP037 │ │ │ ) -> tuple["PyCapsule", "PyCapsule"]: # type: ignore[name-defined] # noqa: F821, UP037 │ │ │ raise NotImplementedError()
│ │ │ │ │ │ │ │ │ │ │ │
│ │ │ -[docs] │ │ │ +[docs] │ │ │ def fromarray(obj: SupportsArrayInterface, mode: str | None = None) -> Image: │ │ │ """ │ │ │ Creates an image memory from an object exporting the array interface │ │ │ (using the buffer protocol):: │ │ │ │ │ │ from PIL import Image │ │ │ import numpy as np │ │ │ @@ -3908,15 +3908,15 @@ │ │ │ raise ValueError(msg) │ │ │ │ │ │ return frombuffer(mode, size, obj, "raw", rawmode, 0, 1)
│ │ │ │ │ │ │ │ │ │ │ │
│ │ │ -[docs] │ │ │ +[docs] │ │ │ def fromarrow( │ │ │ obj: SupportsArrowArrayInterface, mode: str, size: tuple[int, int] │ │ │ ) -> Image: │ │ │ """Creates an image with zero-copy shared memory from an object exporting │ │ │ the arrow_c_array interface protocol:: │ │ │ │ │ │ from PIL import Image │ │ │ @@ -4031,15 +4031,15 @@ │ │ │ f"Image size ({pixels} pixels) exceeds limit of {MAX_IMAGE_PIXELS} pixels, " │ │ │ "could be decompression bomb DOS attack.", │ │ │ DecompressionBombWarning, │ │ │ ) │ │ │ │ │ │ │ │ │
│ │ │ -[docs] │ │ │ +[docs] │ │ │ def open( │ │ │ fp: StrOrBytesPath | IO[bytes], │ │ │ mode: Literal["r"] = "r", │ │ │ formats: list[str] | tuple[str, ...] | None = None, │ │ │ ) -> ImageFile.ImageFile: │ │ │ """ │ │ │ Opens and identifies the given image file. │ │ │ @@ -4162,15 +4162,15 @@ │ │ │ │ │ │ │ │ │ # │ │ │ # Image processing. │ │ │ │ │ │ │ │ │
│ │ │ -[docs] │ │ │ +[docs] │ │ │ def alpha_composite(im1: Image, im2: Image) -> Image: │ │ │ """ │ │ │ Alpha composite im2 over im1. │ │ │ │ │ │ :param im1: The first image. Must have mode RGBA. │ │ │ :param im2: The second image. Must have mode RGBA, and the same size as │ │ │ the first image. │ │ │ @@ -4180,15 +4180,15 @@ │ │ │ im1.load() │ │ │ im2.load() │ │ │ return im1._new(core.alpha_composite(im1.im, im2.im))
│ │ │ │ │ │ │ │ │ │ │ │
│ │ │ -[docs] │ │ │ +[docs] │ │ │ def blend(im1: Image, im2: Image, alpha: float) -> Image: │ │ │ """ │ │ │ Creates a new image by interpolating between two input images, using │ │ │ a constant alpha:: │ │ │ │ │ │ out = image1 * (1.0 - alpha) + image2 * alpha │ │ │ │ │ │ @@ -4206,15 +4206,15 @@ │ │ │ im1.load() │ │ │ im2.load() │ │ │ return im1._new(core.blend(im1.im, im2.im, alpha))
│ │ │ │ │ │ │ │ │ │ │ │
│ │ │ -[docs] │ │ │ +[docs] │ │ │ def composite(image1: Image, image2: Image, mask: Image) -> Image: │ │ │ """ │ │ │ Create composite image by blending images using a transparency mask. │ │ │ │ │ │ :param image1: The first image. │ │ │ :param image2: The second image. Must have the same mode and │ │ │ size as the first image. │ │ │ @@ -4226,15 +4226,15 @@ │ │ │ image = image2.copy() │ │ │ image.paste(image1, None, mask) │ │ │ return image
│ │ │ │ │ │ │ │ │ │ │ │
│ │ │ -[docs] │ │ │ +[docs] │ │ │ def eval(image: Image, *args: Callable[[int], float]) -> Image: │ │ │ """ │ │ │ Applies the function (which should take one argument) to each pixel │ │ │ in the given image. If the image has more than one band, the same │ │ │ function is applied to each band. Note that the function is │ │ │ evaluated once for each possible pixel value, so you cannot use │ │ │ random components or other generators. │ │ │ @@ -4245,15 +4245,15 @@ │ │ │ """ │ │ │ │ │ │ return image.point(args[0])
│ │ │ │ │ │ │ │ │ │ │ │
│ │ │ -[docs] │ │ │ +[docs] │ │ │ def merge(mode: str, bands: Sequence[Image]) -> Image: │ │ │ """ │ │ │ Merge a set of single band images into a new multiband image. │ │ │ │ │ │ :param mode: The mode to use for the output image. See: │ │ │ :ref:`concept-modes`. │ │ │ :param bands: A sequence containing one single-band image for │ │ │ @@ -4279,15 +4279,15 @@ │ │ │ │ │ │ │ │ │ # -------------------------------------------------------------------- │ │ │ # Plugin registry │ │ │ │ │ │ │ │ │
│ │ │ -[docs] │ │ │ +[docs] │ │ │ def register_open( │ │ │ id: str, │ │ │ factory: ( │ │ │ Callable[[IO[bytes], str | bytes], ImageFile.ImageFile] │ │ │ | type[ImageFile.ImageFile] │ │ │ ), │ │ │ accept: Callable[[bytes], bool | str] | None = None, │ │ │ @@ -4305,15 +4305,15 @@ │ │ │ if id not in ID: │ │ │ ID.append(id) │ │ │ OPEN[id] = factory, accept
│ │ │ │ │ │ │ │ │ │ │ │
│ │ │ -[docs] │ │ │ +[docs] │ │ │ def register_mime(id: str, mimetype: str) -> None: │ │ │ """ │ │ │ Registers an image MIME type by populating ``Image.MIME``. This function │ │ │ should not be used in application code. │ │ │ │ │ │ ``Image.MIME`` provides a mapping from image format identifiers to mime │ │ │ formats, but :py:meth:`~PIL.ImageFile.ImageFile.get_format_mimetype` can │ │ │ @@ -4323,15 +4323,15 @@ │ │ │ :param mimetype: The image MIME type for this format. │ │ │ """ │ │ │ MIME[id.upper()] = mimetype
│ │ │ │ │ │ │ │ │ │ │ │
│ │ │ -[docs] │ │ │ +[docs] │ │ │ def register_save( │ │ │ id: str, driver: Callable[[Image, IO[bytes], str | bytes], None] │ │ │ ) -> None: │ │ │ """ │ │ │ Registers an image save function. This function should not be │ │ │ used in application code. │ │ │ │ │ │ @@ -4339,15 +4339,15 @@ │ │ │ :param driver: A function to save images in this format. │ │ │ """ │ │ │ SAVE[id.upper()] = driver
│ │ │ │ │ │ │ │ │ │ │ │
│ │ │ -[docs] │ │ │ +[docs] │ │ │ def register_save_all( │ │ │ id: str, driver: Callable[[Image, IO[bytes], str | bytes], None] │ │ │ ) -> None: │ │ │ """ │ │ │ Registers an image function to save all the frames │ │ │ of a multiframe format. This function should not be │ │ │ used in application code. │ │ │ @@ -4356,56 +4356,56 @@ │ │ │ :param driver: A function to save images in this format. │ │ │ """ │ │ │ SAVE_ALL[id.upper()] = driver
│ │ │ │ │ │ │ │ │ │ │ │
│ │ │ -[docs] │ │ │ +[docs] │ │ │ def register_extension(id: str, extension: str) -> None: │ │ │ """ │ │ │ Registers an image extension. This function should not be │ │ │ used in application code. │ │ │ │ │ │ :param id: An image format identifier. │ │ │ :param extension: An extension used for this format. │ │ │ """ │ │ │ EXTENSION[extension.lower()] = id.upper()
│ │ │ │ │ │ │ │ │ │ │ │
│ │ │ -[docs] │ │ │ +[docs] │ │ │ def register_extensions(id: str, extensions: list[str]) -> None: │ │ │ """ │ │ │ Registers image extensions. This function should not be │ │ │ used in application code. │ │ │ │ │ │ :param id: An image format identifier. │ │ │ :param extensions: A list of extensions used for this format. │ │ │ """ │ │ │ for extension in extensions: │ │ │ register_extension(id, extension)
│ │ │ │ │ │ │ │ │ │ │ │
│ │ │ -[docs] │ │ │ +[docs] │ │ │ def registered_extensions() -> dict[str, str]: │ │ │ """ │ │ │ Returns a dictionary containing all file extensions belonging │ │ │ to registered plugins │ │ │ """ │ │ │ init() │ │ │ return EXTENSION
│ │ │ │ │ │ │ │ │ │ │ │
│ │ │ -[docs] │ │ │ +[docs] │ │ │ def register_decoder(name: str, decoder: type[ImageFile.PyDecoder]) -> None: │ │ │ """ │ │ │ Registers an image decoder. This function should not be │ │ │ used in application code. │ │ │ │ │ │ :param name: The name of the decoder │ │ │ :param decoder: An ImageFile.PyDecoder object │ │ │ @@ -4413,15 +4413,15 @@ │ │ │ .. versionadded:: 4.1.0 │ │ │ """ │ │ │ DECODERS[name] = decoder
│ │ │ │ │ │ │ │ │ │ │ │
│ │ │ -[docs] │ │ │ +[docs] │ │ │ def register_encoder(name: str, encoder: type[ImageFile.PyEncoder]) -> None: │ │ │ """ │ │ │ Registers an image encoder. This function should not be │ │ │ used in application code. │ │ │ │ │ │ :param name: The name of the encoder │ │ │ :param encoder: An ImageFile.PyEncoder object │ │ │ @@ -4443,15 +4443,15 @@ │ │ │ │ │ │ │ │ │ # -------------------------------------------------------------------- │ │ │ # Effects │ │ │ │ │ │ │ │ │
│ │ │ -[docs] │ │ │ +[docs] │ │ │ def effect_mandelbrot( │ │ │ size: tuple[int, int], extent: tuple[float, float, float, float], quality: int │ │ │ ) -> Image: │ │ │ """ │ │ │ Generate a Mandelbrot set covering the given extent. │ │ │ │ │ │ :param size: The requested size in pixels, as a 2-tuple: │ │ │ @@ -4461,41 +4461,41 @@ │ │ │ :param quality: Quality. │ │ │ """ │ │ │ return Image()._new(core.effect_mandelbrot(size, extent, quality))
│ │ │ │ │ │ │ │ │ │ │ │
│ │ │ -[docs] │ │ │ +[docs] │ │ │ def effect_noise(size: tuple[int, int], sigma: float) -> Image: │ │ │ """ │ │ │ Generate Gaussian noise centered around 128. │ │ │ │ │ │ :param size: The requested size in pixels, as a 2-tuple: │ │ │ (width, height). │ │ │ :param sigma: Standard deviation of noise. │ │ │ """ │ │ │ return Image()._new(core.effect_noise(size, sigma))
│ │ │ │ │ │ │ │ │ │ │ │
│ │ │ -[docs] │ │ │ +[docs] │ │ │ def linear_gradient(mode: str) -> Image: │ │ │ """ │ │ │ Generate 256x256 linear gradient from black to white, top to bottom. │ │ │ │ │ │ :param mode: Input mode. │ │ │ """ │ │ │ return Image()._new(core.linear_gradient(mode))
│ │ │ │ │ │ │ │ │ │ │ │
│ │ │ -[docs] │ │ │ +[docs] │ │ │ def radial_gradient(mode: str) -> Image: │ │ │ """ │ │ │ Generate 256x256 radial gradient from black to white, centre to edge. │ │ │ │ │ │ :param mode: Input mode. │ │ │ """ │ │ │ return Image()._new(core.radial_gradient(mode))
│ │ │ @@ -4544,15 +4544,15 @@ │ │ │ if TYPE_CHECKING: │ │ │ _ExifBase = MutableMapping[int, Any] │ │ │ else: │ │ │ _ExifBase = MutableMapping │ │ │ │ │ │ │ │ │
│ │ │ -[docs] │ │ │ +[docs] │ │ │ class Exif(_ExifBase): │ │ │ """ │ │ │ This class provides read and write access to EXIF image data:: │ │ │ │ │ │ from PIL import Image │ │ │ im = Image.open("exif.png") │ │ │ exif = im.getexif() # Returns an instance of this class │ │ │ @@ -4631,15 +4631,15 @@ │ │ │ head = b"MM\x00" + version + o32be(8) │ │ │ if self.bigtiff: │ │ │ head += o32le(8) if self.endian == "<" else o32be(8) │ │ │ head += b"\x00\x00\x00\x00" │ │ │ return head │ │ │ │ │ │
│ │ │ -[docs] │ │ │ +[docs] │ │ │ def load(self, data: bytes) -> None: │ │ │ # Extract EXIF information. This is highly experimental, │ │ │ # and is likely to be replaced with something better in a future │ │ │ # version. │ │ │ │ │ │ # The EXIF record consists of a TIFF file embedded in a JPEG │ │ │ # application marker (!). │ │ │ @@ -4663,15 +4663,15 @@ │ │ │ self._info = TiffImagePlugin.ImageFileDirectory_v2(self.head) │ │ │ self.endian = self._info._endian │ │ │ self.fp.seek(self._info.next) │ │ │ self._info.load(self.fp)
│ │ │ │ │ │ │ │ │
│ │ │ -[docs] │ │ │ +[docs] │ │ │ def load_from_fp(self, fp: IO[bytes], offset: int | None = None) -> None: │ │ │ self._loaded_exif = None │ │ │ self._data.clear() │ │ │ self._hidden_data.clear() │ │ │ self._ifds.clear() │ │ │ │ │ │ # process dictionary │ │ │ @@ -4706,15 +4706,15 @@ │ │ │ merged_dict[ExifTags.IFD.GPSInfo] = self._get_ifd_dict( │ │ │ self[ExifTags.IFD.GPSInfo], ExifTags.IFD.GPSInfo │ │ │ ) │ │ │ │ │ │ return merged_dict │ │ │ │ │ │
│ │ │ -[docs] │ │ │ +[docs] │ │ │ def tobytes(self, offset: int = 8) -> bytes: │ │ │ from . import TiffImagePlugin │ │ │ │ │ │ head = self._get_head() │ │ │ ifd = TiffImagePlugin.ImageFileDirectory_v2(ifh=head) │ │ │ for tag, ifd_dict in self._ifds.items(): │ │ │ if tag not in self: │ │ │ @@ -4733,15 +4733,15 @@ │ │ │ value = value.copy() │ │ │ value[ExifTags.IFD.Interop] = self.get_ifd(ExifTags.IFD.Interop) │ │ │ ifd[tag] = value │ │ │ return b"Exif\x00\x00" + head + ifd.tobytes(offset)
│ │ │ │ │ │ │ │ │
│ │ │ -[docs] │ │ │ +[docs] │ │ │ def get_ifd(self, tag: int) -> dict[int, Any]: │ │ │ if tag not in self._ifds: │ │ │ if tag == ExifTags.IFD.IFD1: │ │ │ if self._info is not None and self._info.next != 0: │ │ │ ifd = self._get_ifd_dict(self._info.next) │ │ │ if ifd is not None: │ │ │ self._ifds[tag] = ifd │ │ │ @@ -4844,15 +4844,15 @@ │ │ │ for (k, v) in ifd.items() │ │ │ if k not in (ExifTags.IFD.Interop, ExifTags.IFD.MakerNote) │ │ │ } │ │ │ return ifd
│ │ │ │ │ │ │ │ │
│ │ │ -[docs] │ │ │ +[docs] │ │ │ def hide_offsets(self) -> None: │ │ │ for tag in (ExifTags.IFD.Exif, ExifTags.IFD.GPSInfo): │ │ │ if tag in self: │ │ │ self._hidden_data[tag] = self[tag] │ │ │ del self[tag]