Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/PIL/Image.py: 45%
Shortcuts on this page
r m x toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
Shortcuts on this page
r m x toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1#
2# The Python Imaging Library.
3# $Id$
4#
5# the Image class wrapper
6#
7# partial release history:
8# 1995-09-09 fl Created
9# 1996-03-11 fl PIL release 0.0 (proof of concept)
10# 1996-04-30 fl PIL release 0.1b1
11# 1999-07-28 fl PIL release 1.0 final
12# 2000-06-07 fl PIL release 1.1
13# 2000-10-20 fl PIL release 1.1.1
14# 2001-05-07 fl PIL release 1.1.2
15# 2002-03-15 fl PIL release 1.1.3
16# 2003-05-10 fl PIL release 1.1.4
17# 2005-03-28 fl PIL release 1.1.5
18# 2006-12-02 fl PIL release 1.1.6
19# 2009-11-15 fl PIL release 1.1.7
20#
21# Copyright (c) 1997-2009 by Secret Labs AB. All rights reserved.
22# Copyright (c) 1995-2009 by Fredrik Lundh.
23#
24# See the README file for information on usage and redistribution.
25#
27from __future__ import annotations
29import abc
30import atexit
31import builtins
32import io
33import logging
34import math
35import os
36import re
37import struct
38import sys
39import tempfile
40import warnings
41from collections.abc import MutableMapping
42from enum import IntEnum
43from typing import IO, Protocol, cast
45# VERSION was removed in Pillow 6.0.0.
46# PILLOW_VERSION was removed in Pillow 9.0.0.
47# Use __version__ instead.
48from . import (
49 ExifTags,
50 ImageMode,
51 TiffTags,
52 UnidentifiedImageError,
53 __version__,
54 _plugins,
55)
56from ._binary import i32le, o32be, o32le
57from ._deprecate import deprecate
58from ._util import DeferredError, is_path
60ElementTree: ModuleType | None
61try:
62 from defusedxml import ElementTree
63except ImportError:
64 ElementTree = None
66TYPE_CHECKING = False
67if TYPE_CHECKING:
68 from collections.abc import Callable, Iterator, Sequence
69 from types import ModuleType
70 from typing import Any, Literal
72logger = logging.getLogger(__name__)
75class DecompressionBombWarning(RuntimeWarning):
76 pass
79class DecompressionBombError(Exception):
80 pass
83WARN_POSSIBLE_FORMATS: bool = False
85# Limit to around a quarter gigabyte for a 24-bit (3 bpp) image
86MAX_IMAGE_PIXELS: int | None = int(1024 * 1024 * 1024 // 4 // 3)
89try:
90 # If the _imaging C module is not present, Pillow will not load.
91 # Note that other modules should not refer to _imaging directly;
92 # import Image and use the Image.core variable instead.
93 # Also note that Image.core is not a publicly documented interface,
94 # and should be considered private and subject to change.
95 from . import _imaging as core
97 if __version__ != getattr(core, "PILLOW_VERSION", None):
98 msg = (
99 "The _imaging extension was built for another version of Pillow or PIL:\n"
100 f"Core version: {getattr(core, 'PILLOW_VERSION', None)}\n"
101 f"Pillow version: {__version__}"
102 )
103 raise ImportError(msg)
105except ImportError as v:
106 # Explanations for ways that we know we might have an import error
107 if str(v).startswith("Module use of python"):
108 # The _imaging C module is present, but not compiled for
109 # the right version (windows only). Print a warning, if
110 # possible.
111 warnings.warn(
112 "The _imaging extension was built for another version of Python.",
113 RuntimeWarning,
114 )
115 elif str(v).startswith("The _imaging extension"):
116 warnings.warn(str(v), RuntimeWarning)
117 # Fail here anyway. Don't let people run with a mostly broken Pillow.
118 # see docs/porting.rst
119 raise
122#
123# Constants
126# transpose
127class Transpose(IntEnum):
128 FLIP_LEFT_RIGHT = 0
129 FLIP_TOP_BOTTOM = 1
130 ROTATE_90 = 2
131 ROTATE_180 = 3
132 ROTATE_270 = 4
133 TRANSPOSE = 5
134 TRANSVERSE = 6
137# transforms (also defined in Imaging.h)
138class Transform(IntEnum):
139 AFFINE = 0
140 EXTENT = 1
141 PERSPECTIVE = 2
142 QUAD = 3
143 MESH = 4
146# resampling filters (also defined in Imaging.h)
147class Resampling(IntEnum):
148 NEAREST = 0
149 BOX = 4
150 BILINEAR = 2
151 HAMMING = 5
152 BICUBIC = 3
153 LANCZOS = 1
156_filters_support = {
157 Resampling.BOX: 0.5,
158 Resampling.BILINEAR: 1.0,
159 Resampling.HAMMING: 1.0,
160 Resampling.BICUBIC: 2.0,
161 Resampling.LANCZOS: 3.0,
162}
165# dithers
166class Dither(IntEnum):
167 NONE = 0
168 ORDERED = 1 # Not yet implemented
169 RASTERIZE = 2 # Not yet implemented
170 FLOYDSTEINBERG = 3 # default
173# palettes/quantizers
174class Palette(IntEnum):
175 WEB = 0
176 ADAPTIVE = 1
179class Quantize(IntEnum):
180 MEDIANCUT = 0
181 MAXCOVERAGE = 1
182 FASTOCTREE = 2
183 LIBIMAGEQUANT = 3
186module = sys.modules[__name__]
187for enum in (Transpose, Transform, Resampling, Dither, Palette, Quantize):
188 for item in enum:
189 setattr(module, item.name, item.value)
192if hasattr(core, "DEFAULT_STRATEGY"):
193 DEFAULT_STRATEGY = core.DEFAULT_STRATEGY
194 FILTERED = core.FILTERED
195 HUFFMAN_ONLY = core.HUFFMAN_ONLY
196 RLE = core.RLE
197 FIXED = core.FIXED
200# --------------------------------------------------------------------
201# Registries
203TYPE_CHECKING = False
204if TYPE_CHECKING:
205 import mmap
206 from xml.etree.ElementTree import Element
208 from IPython.lib.pretty import PrettyPrinter
210 from . import ImageFile, ImageFilter, ImagePalette, ImageQt, TiffImagePlugin
211 from ._typing import CapsuleType, NumpyArray, StrOrBytesPath
212ID: list[str] = []
213OPEN: dict[
214 str,
215 tuple[
216 Callable[[IO[bytes], str | bytes], ImageFile.ImageFile],
217 Callable[[bytes], bool | str] | None,
218 ],
219] = {}
220MIME: dict[str, str] = {}
221SAVE: dict[str, Callable[[Image, IO[bytes], str | bytes], None]] = {}
222SAVE_ALL: dict[str, Callable[[Image, IO[bytes], str | bytes], None]] = {}
223EXTENSION: dict[str, str] = {}
224DECODERS: dict[str, type[ImageFile.PyDecoder]] = {}
225ENCODERS: dict[str, type[ImageFile.PyEncoder]] = {}
227# --------------------------------------------------------------------
228# Modes
230_ENDIAN = "<" if sys.byteorder == "little" else ">"
233def _conv_type_shape(im: Image) -> tuple[tuple[int, ...], str]:
234 m = ImageMode.getmode(im.mode)
235 shape: tuple[int, ...] = (im.height, im.width)
236 extra = len(m.bands)
237 if extra != 1:
238 shape += (extra,)
239 return shape, m.typestr
242MODES = [
243 "1",
244 "CMYK",
245 "F",
246 "HSV",
247 "I",
248 "I;16",
249 "I;16B",
250 "I;16L",
251 "I;16N",
252 "L",
253 "LA",
254 "La",
255 "LAB",
256 "P",
257 "PA",
258 "RGB",
259 "RGBA",
260 "RGBa",
261 "RGBX",
262 "YCbCr",
263]
265# raw modes that may be memory mapped. NOTE: if you change this, you
266# may have to modify the stride calculation in map.c too!
267_MAPMODES = ("L", "P", "RGBX", "RGBA", "CMYK", "I;16", "I;16L", "I;16B")
270def getmodebase(mode: str) -> str:
271 """
272 Gets the "base" mode for given mode. This function returns "L" for
273 images that contain grayscale data, and "RGB" for images that
274 contain color data.
276 :param mode: Input mode.
277 :returns: "L" or "RGB".
278 :exception KeyError: If the input mode was not a standard mode.
279 """
280 return ImageMode.getmode(mode).basemode
283def getmodetype(mode: str) -> str:
284 """
285 Gets the storage type mode. Given a mode, this function returns a
286 single-layer mode suitable for storing individual bands.
288 :param mode: Input mode.
289 :returns: "L", "I", or "F".
290 :exception KeyError: If the input mode was not a standard mode.
291 """
292 return ImageMode.getmode(mode).basetype
295def getmodebandnames(mode: str) -> tuple[str, ...]:
296 """
297 Gets a list of individual band names. Given a mode, this function returns
298 a tuple containing the names of individual bands (use
299 :py:method:`~PIL.Image.getmodetype` to get the mode used to store each
300 individual band.
302 :param mode: Input mode.
303 :returns: A tuple containing band names. The length of the tuple
304 gives the number of bands in an image of the given mode.
305 :exception KeyError: If the input mode was not a standard mode.
306 """
307 return ImageMode.getmode(mode).bands
310def getmodebands(mode: str) -> int:
311 """
312 Gets the number of individual bands for this mode.
314 :param mode: Input mode.
315 :returns: The number of bands in this mode.
316 :exception KeyError: If the input mode was not a standard mode.
317 """
318 return len(ImageMode.getmode(mode).bands)
321# --------------------------------------------------------------------
322# Helpers
324_initialized = 0
327def preinit() -> None:
328 """
329 Explicitly loads BMP, GIF, JPEG, PPM and PPM file format drivers.
331 It is called when opening or saving images.
332 """
334 global _initialized
335 if _initialized >= 1:
336 return
338 try:
339 from . import BmpImagePlugin
341 assert BmpImagePlugin
342 except ImportError:
343 pass
344 try:
345 from . import GifImagePlugin
347 assert GifImagePlugin
348 except ImportError:
349 pass
350 try:
351 from . import JpegImagePlugin
353 assert JpegImagePlugin
354 except ImportError:
355 pass
356 try:
357 from . import PpmImagePlugin
359 assert PpmImagePlugin
360 except ImportError:
361 pass
362 try:
363 from . import PngImagePlugin
365 assert PngImagePlugin
366 except ImportError:
367 pass
369 _initialized = 1
372def init() -> bool:
373 """
374 Explicitly initializes the Python Imaging Library. This function
375 loads all available file format drivers.
377 It is called when opening or saving images if :py:meth:`~preinit()` is
378 insufficient, and by :py:meth:`~PIL.features.pilinfo`.
379 """
381 global _initialized
382 if _initialized >= 2:
383 return False
385 parent_name = __name__.rpartition(".")[0]
386 for plugin in _plugins:
387 try:
388 logger.debug("Importing %s", plugin)
389 __import__(f"{parent_name}.{plugin}", globals(), locals(), [])
390 except ImportError as e:
391 logger.debug("Image: failed to import %s: %s", plugin, e)
393 if OPEN or SAVE:
394 _initialized = 2
395 return True
396 return False
399# --------------------------------------------------------------------
400# Codec factories (used by tobytes/frombytes and ImageFile.load)
403def _getdecoder(
404 mode: str, decoder_name: str, args: Any, extra: tuple[Any, ...] = ()
405) -> core.ImagingDecoder | ImageFile.PyDecoder:
406 # tweak arguments
407 if args is None:
408 args = ()
409 elif not isinstance(args, tuple):
410 args = (args,)
412 try:
413 decoder = DECODERS[decoder_name]
414 except KeyError:
415 pass
416 else:
417 return decoder(mode, *args + extra)
419 try:
420 # get decoder
421 decoder = getattr(core, f"{decoder_name}_decoder")
422 except AttributeError as e:
423 msg = f"decoder {decoder_name} not available"
424 raise OSError(msg) from e
425 return decoder(mode, *args + extra)
428def _getencoder(
429 mode: str, encoder_name: str, args: Any, extra: tuple[Any, ...] = ()
430) -> core.ImagingEncoder | ImageFile.PyEncoder:
431 # tweak arguments
432 if args is None:
433 args = ()
434 elif not isinstance(args, tuple):
435 args = (args,)
437 try:
438 encoder = ENCODERS[encoder_name]
439 except KeyError:
440 pass
441 else:
442 return encoder(mode, *args + extra)
444 try:
445 # get encoder
446 encoder = getattr(core, f"{encoder_name}_encoder")
447 except AttributeError as e:
448 msg = f"encoder {encoder_name} not available"
449 raise OSError(msg) from e
450 return encoder(mode, *args + extra)
453# --------------------------------------------------------------------
454# Simple expression analyzer
457class ImagePointTransform:
458 """
459 Used with :py:meth:`~PIL.Image.Image.point` for single band images with more than
460 8 bits, this represents an affine transformation, where the value is multiplied by
461 ``scale`` and ``offset`` is added.
462 """
464 def __init__(self, scale: float, offset: float) -> None:
465 self.scale = scale
466 self.offset = offset
468 def __neg__(self) -> ImagePointTransform:
469 return ImagePointTransform(-self.scale, -self.offset)
471 def __add__(self, other: ImagePointTransform | float) -> ImagePointTransform:
472 if isinstance(other, ImagePointTransform):
473 return ImagePointTransform(
474 self.scale + other.scale, self.offset + other.offset
475 )
476 return ImagePointTransform(self.scale, self.offset + other)
478 __radd__ = __add__
480 def __sub__(self, other: ImagePointTransform | float) -> ImagePointTransform:
481 return self + -other
483 def __rsub__(self, other: ImagePointTransform | float) -> ImagePointTransform:
484 return other + -self
486 def __mul__(self, other: ImagePointTransform | float) -> ImagePointTransform:
487 if isinstance(other, ImagePointTransform):
488 return NotImplemented
489 return ImagePointTransform(self.scale * other, self.offset * other)
491 __rmul__ = __mul__
493 def __truediv__(self, other: ImagePointTransform | float) -> ImagePointTransform:
494 if isinstance(other, ImagePointTransform):
495 return NotImplemented
496 return ImagePointTransform(self.scale / other, self.offset / other)
499def _getscaleoffset(
500 expr: Callable[[ImagePointTransform], ImagePointTransform | float],
501) -> tuple[float, float]:
502 a = expr(ImagePointTransform(1, 0))
503 return (a.scale, a.offset) if isinstance(a, ImagePointTransform) else (0, a)
506# --------------------------------------------------------------------
507# Implementation wrapper
510class SupportsGetData(Protocol):
511 def getdata(
512 self,
513 ) -> tuple[Transform, Sequence[int]]: ...
516class Image:
517 """
518 This class represents an image object. To create
519 :py:class:`~PIL.Image.Image` objects, use the appropriate factory
520 functions. There's hardly ever any reason to call the Image constructor
521 directly.
523 * :py:func:`~PIL.Image.open`
524 * :py:func:`~PIL.Image.new`
525 * :py:func:`~PIL.Image.frombytes`
526 """
528 format: str | None = None
529 format_description: str | None = None
530 _close_exclusive_fp_after_loading = True
532 def __init__(self) -> None:
533 # FIXME: take "new" parameters / other image?
534 self._im: core.ImagingCore | DeferredError | None = None
535 self._mode = ""
536 self._size = (0, 0)
537 self.palette: ImagePalette.ImagePalette | None = None
538 self.info: dict[str | tuple[int, int], Any] = {}
539 self.readonly = 0
540 self._exif: Exif | None = None
542 @property
543 def im(self) -> core.ImagingCore:
544 if isinstance(self._im, DeferredError):
545 raise self._im.ex
546 assert self._im is not None
547 return self._im
549 @im.setter
550 def im(self, im: core.ImagingCore) -> None:
551 self._im = im
553 @property
554 def width(self) -> int:
555 return self.size[0]
557 @property
558 def height(self) -> int:
559 return self.size[1]
561 @property
562 def size(self) -> tuple[int, int]:
563 return self._size
565 @property
566 def mode(self) -> str:
567 return self._mode
569 @property
570 def readonly(self) -> int:
571 return (self._im and self._im.readonly) or self._readonly
573 @readonly.setter
574 def readonly(self, readonly: int) -> None:
575 self._readonly = readonly
577 def _new(self, im: core.ImagingCore) -> Image:
578 new = Image()
579 new.im = im
580 new._mode = im.mode
581 new._size = im.size
582 if im.mode in ("P", "PA"):
583 if self.palette:
584 new.palette = self.palette.copy()
585 else:
586 from . import ImagePalette
588 new.palette = ImagePalette.ImagePalette()
589 new.info = self.info.copy()
590 return new
592 # Context manager support
593 def __enter__(self):
594 return self
596 def __exit__(self, *args):
597 from . import ImageFile
599 if isinstance(self, ImageFile.ImageFile):
600 if getattr(self, "_exclusive_fp", False):
601 self._close_fp()
602 self.fp = None
604 def close(self) -> None:
605 """
606 This operation will destroy the image core and release its memory.
607 The image data will be unusable afterward.
609 This function is required to close images that have multiple frames or
610 have not had their file read and closed by the
611 :py:meth:`~PIL.Image.Image.load` method. See :ref:`file-handling` for
612 more information.
613 """
614 if getattr(self, "map", None):
615 if sys.platform == "win32" and hasattr(sys, "pypy_version_info"):
616 self.map.close()
617 self.map: mmap.mmap | None = None
619 # Instead of simply setting to None, we're setting up a
620 # deferred error that will better explain that the core image
621 # object is gone.
622 self._im = DeferredError(ValueError("Operation on closed image"))
624 def _copy(self) -> None:
625 self.load()
626 self.im = self.im.copy()
627 self.readonly = 0
629 def _ensure_mutable(self) -> None:
630 if self.readonly:
631 self._copy()
632 else:
633 self.load()
635 def _dump(
636 self, file: str | None = None, format: str | None = None, **options: Any
637 ) -> str:
638 suffix = ""
639 if format:
640 suffix = f".{format}"
642 if not file:
643 f, filename = tempfile.mkstemp(suffix)
644 os.close(f)
645 else:
646 filename = file
647 if not filename.endswith(suffix):
648 filename = filename + suffix
650 self.load()
652 if not format or format == "PPM":
653 self.im.save_ppm(filename)
654 else:
655 self.save(filename, format, **options)
657 return filename
659 def __eq__(self, other: object) -> bool:
660 if self.__class__ is not other.__class__:
661 return False
662 assert isinstance(other, Image)
663 return (
664 self.mode == other.mode
665 and self.size == other.size
666 and self.info == other.info
667 and self.getpalette() == other.getpalette()
668 and self.tobytes() == other.tobytes()
669 )
671 def __repr__(self) -> str:
672 return (
673 f"<{self.__class__.__module__}.{self.__class__.__name__} "
674 f"image mode={self.mode} size={self.size[0]}x{self.size[1]} "
675 f"at 0x{id(self):X}>"
676 )
678 def _repr_pretty_(self, p: PrettyPrinter, cycle: bool) -> None:
679 """IPython plain text display support"""
681 # Same as __repr__ but without unpredictable id(self),
682 # to keep Jupyter notebook `text/plain` output stable.
683 p.text(
684 f"<{self.__class__.__module__}.{self.__class__.__name__} "
685 f"image mode={self.mode} size={self.size[0]}x{self.size[1]}>"
686 )
688 def _repr_image(self, image_format: str, **kwargs: Any) -> bytes | None:
689 """Helper function for iPython display hook.
691 :param image_format: Image format.
692 :returns: image as bytes, saved into the given format.
693 """
694 b = io.BytesIO()
695 try:
696 self.save(b, image_format, **kwargs)
697 except Exception:
698 return None
699 return b.getvalue()
701 def _repr_png_(self) -> bytes | None:
702 """iPython display hook support for PNG format.
704 :returns: PNG version of the image as bytes
705 """
706 return self._repr_image("PNG", compress_level=1)
708 def _repr_jpeg_(self) -> bytes | None:
709 """iPython display hook support for JPEG format.
711 :returns: JPEG version of the image as bytes
712 """
713 return self._repr_image("JPEG")
715 @property
716 def __array_interface__(self) -> dict[str, str | bytes | int | tuple[int, ...]]:
717 # numpy array interface support
718 new: dict[str, str | bytes | int | tuple[int, ...]] = {"version": 3}
719 if self.mode == "1":
720 # Binary images need to be extended from bits to bytes
721 # See: https://github.com/python-pillow/Pillow/issues/350
722 new["data"] = self.tobytes("raw", "L")
723 else:
724 new["data"] = self.tobytes()
725 new["shape"], new["typestr"] = _conv_type_shape(self)
726 return new
728 def __arrow_c_schema__(self) -> object:
729 self.load()
730 return self.im.__arrow_c_schema__()
732 def __arrow_c_array__(
733 self, requested_schema: object | None = None
734 ) -> tuple[object, object]:
735 self.load()
736 return (self.im.__arrow_c_schema__(), self.im.__arrow_c_array__())
738 def __getstate__(self) -> list[Any]:
739 im_data = self.tobytes() # load image first
740 return [self.info, self.mode, self.size, self.getpalette(), im_data]
742 def __setstate__(self, state: list[Any]) -> None:
743 Image.__init__(self)
744 info, mode, size, palette, data = state[:5]
745 self.info = info
746 self._mode = mode
747 self._size = size
748 self.im = core.new(mode, size)
749 if mode in ("L", "LA", "P", "PA") and palette:
750 self.putpalette(palette)
751 self.frombytes(data)
753 def tobytes(self, encoder_name: str = "raw", *args: Any) -> bytes:
754 """
755 Return image as a bytes object.
757 .. warning::
759 This method returns raw image data derived from Pillow's internal
760 storage. For compressed image data (e.g. PNG, JPEG) use
761 :meth:`~.save`, with a BytesIO parameter for in-memory data.
763 :param encoder_name: What encoder to use.
765 The default is to use the standard "raw" encoder.
766 To see how this packs pixel data into the returned
767 bytes, see :file:`libImaging/Pack.c`.
769 A list of C encoders can be seen under codecs
770 section of the function array in
771 :file:`_imaging.c`. Python encoders are registered
772 within the relevant plugins.
773 :param args: Extra arguments to the encoder.
774 :returns: A :py:class:`bytes` object.
775 """
777 encoder_args: Any = args
778 if len(encoder_args) == 1 and isinstance(encoder_args[0], tuple):
779 # may pass tuple instead of argument list
780 encoder_args = encoder_args[0]
782 if encoder_name == "raw" and encoder_args == ():
783 encoder_args = self.mode
785 self.load()
787 if self.width == 0 or self.height == 0:
788 return b""
790 # unpack data
791 e = _getencoder(self.mode, encoder_name, encoder_args)
792 e.setimage(self.im)
794 from . import ImageFile
796 bufsize = max(ImageFile.MAXBLOCK, self.size[0] * 4) # see RawEncode.c
798 output = []
799 while True:
800 bytes_consumed, errcode, data = e.encode(bufsize)
801 output.append(data)
802 if errcode:
803 break
804 if errcode < 0:
805 msg = f"encoder error {errcode} in tobytes"
806 raise RuntimeError(msg)
808 return b"".join(output)
810 def tobitmap(self, name: str = "image") -> bytes:
811 """
812 Returns the image converted to an X11 bitmap.
814 .. note:: This method only works for mode "1" images.
816 :param name: The name prefix to use for the bitmap variables.
817 :returns: A string containing an X11 bitmap.
818 :raises ValueError: If the mode is not "1"
819 """
821 self.load()
822 if self.mode != "1":
823 msg = "not a bitmap"
824 raise ValueError(msg)
825 data = self.tobytes("xbm")
826 return b"".join(
827 [
828 f"#define {name}_width {self.size[0]}\n".encode("ascii"),
829 f"#define {name}_height {self.size[1]}\n".encode("ascii"),
830 f"static char {name}_bits[] = {{\n".encode("ascii"),
831 data,
832 b"};",
833 ]
834 )
836 def frombytes(
837 self,
838 data: bytes | bytearray | SupportsArrayInterface,
839 decoder_name: str = "raw",
840 *args: Any,
841 ) -> None:
842 """
843 Loads this image with pixel data from a bytes object.
845 This method is similar to the :py:func:`~PIL.Image.frombytes` function,
846 but loads data into this image instead of creating a new image object.
847 """
849 if self.width == 0 or self.height == 0:
850 return
852 decoder_args: Any = args
853 if len(decoder_args) == 1 and isinstance(decoder_args[0], tuple):
854 # may pass tuple instead of argument list
855 decoder_args = decoder_args[0]
857 # default format
858 if decoder_name == "raw" and decoder_args == ():
859 decoder_args = self.mode
861 # unpack data
862 d = _getdecoder(self.mode, decoder_name, decoder_args)
863 d.setimage(self.im)
864 s = d.decode(data)
866 if s[0] >= 0:
867 msg = "not enough image data"
868 raise ValueError(msg)
869 if s[1] != 0:
870 msg = "cannot decode image data"
871 raise ValueError(msg)
873 def load(self) -> core.PixelAccess | None:
874 """
875 Allocates storage for the image and loads the pixel data. In
876 normal cases, you don't need to call this method, since the
877 Image class automatically loads an opened image when it is
878 accessed for the first time.
880 If the file associated with the image was opened by Pillow, then this
881 method will close it. The exception to this is if the image has
882 multiple frames, in which case the file will be left open for seek
883 operations. See :ref:`file-handling` for more information.
885 :returns: An image access object.
886 :rtype: :py:class:`.PixelAccess`
887 """
888 if self._im is not None and self.palette and self.palette.dirty:
889 # realize palette
890 mode, arr = self.palette.getdata()
891 self.im.putpalette(self.palette.mode, mode, arr)
892 self.palette.dirty = 0
893 self.palette.rawmode = None
894 if "transparency" in self.info and mode in ("LA", "PA"):
895 if isinstance(self.info["transparency"], int):
896 self.im.putpalettealpha(self.info["transparency"], 0)
897 else:
898 self.im.putpalettealphas(self.info["transparency"])
899 self.palette.mode = "RGBA"
900 else:
901 self.palette.palette = self.im.getpalette(
902 self.palette.mode, self.palette.mode
903 )
905 if self._im is not None:
906 return self.im.pixel_access(self.readonly)
907 return None
909 def verify(self) -> None:
910 """
911 Verifies the contents of a file. For data read from a file, this
912 method attempts to determine if the file is broken, without
913 actually decoding the image data. If this method finds any
914 problems, it raises suitable exceptions. If you need to load
915 the image after using this method, you must reopen the image
916 file.
917 """
918 pass
920 def convert(
921 self,
922 mode: str | None = None,
923 matrix: tuple[float, ...] | None = None,
924 dither: Dither | None = None,
925 palette: Palette = Palette.WEB,
926 colors: int = 256,
927 ) -> Image:
928 """
929 Returns a converted copy of this image. For the "P" mode, this
930 method translates pixels through the palette. If mode is
931 omitted, a mode is chosen so that all information in the image
932 and the palette can be represented without a palette.
934 This supports all possible conversions between "L", "RGB" and "CMYK". The
935 ``matrix`` argument only supports "L" and "RGB".
937 When translating a color image to grayscale (mode "L"),
938 the library uses the ITU-R 601-2 luma transform::
940 L = R * 299/1000 + G * 587/1000 + B * 114/1000
942 The default method of converting a grayscale ("L") or "RGB"
943 image into a bilevel (mode "1") image uses Floyd-Steinberg
944 dither to approximate the original image luminosity levels. If
945 dither is ``None``, all values larger than 127 are set to 255 (white),
946 all other values to 0 (black). To use other thresholds, use the
947 :py:meth:`~PIL.Image.Image.point` method.
949 When converting from "RGBA" to "P" without a ``matrix`` argument,
950 this passes the operation to :py:meth:`~PIL.Image.Image.quantize`,
951 and ``dither`` and ``palette`` are ignored.
953 When converting from "PA", if an "RGBA" palette is present, the alpha
954 channel from the image will be used instead of the values from the palette.
956 :param mode: The requested mode. See: :ref:`concept-modes`.
957 :param matrix: An optional conversion matrix. If given, this
958 should be 4- or 12-tuple containing floating point values.
959 :param dither: Dithering method, used when converting from
960 mode "RGB" to "P" or from "RGB" or "L" to "1".
961 Available methods are :data:`Dither.NONE` or :data:`Dither.FLOYDSTEINBERG`
962 (default). Note that this is not used when ``matrix`` is supplied.
963 :param palette: Palette to use when converting from mode "RGB"
964 to "P". Available palettes are :data:`Palette.WEB` or
965 :data:`Palette.ADAPTIVE`.
966 :param colors: Number of colors to use for the :data:`Palette.ADAPTIVE`
967 palette. Defaults to 256.
968 :rtype: :py:class:`~PIL.Image.Image`
969 :returns: An :py:class:`~PIL.Image.Image` object.
970 """
972 self.load()
974 has_transparency = "transparency" in self.info
975 if not mode and self.mode == "P":
976 # determine default mode
977 if self.palette:
978 mode = self.palette.mode
979 else:
980 mode = "RGB"
981 if mode == "RGB" and has_transparency:
982 mode = "RGBA"
983 if not mode or (mode == self.mode and not matrix):
984 return self.copy()
986 if matrix:
987 # matrix conversion
988 if mode not in ("L", "RGB"):
989 msg = "illegal conversion"
990 raise ValueError(msg)
991 im = self.im.convert_matrix(mode, matrix)
992 new_im = self._new(im)
993 if has_transparency and self.im.bands == 3:
994 transparency = new_im.info["transparency"]
996 def convert_transparency(
997 m: tuple[float, ...], v: tuple[int, int, int]
998 ) -> int:
999 value = m[0] * v[0] + m[1] * v[1] + m[2] * v[2] + m[3] * 0.5
1000 return max(0, min(255, int(value)))
1002 if mode == "L":
1003 transparency = convert_transparency(matrix, transparency)
1004 elif len(mode) == 3:
1005 transparency = tuple(
1006 convert_transparency(matrix[i * 4 : i * 4 + 4], transparency)
1007 for i in range(len(transparency))
1008 )
1009 new_im.info["transparency"] = transparency
1010 return new_im
1012 if self.mode == "RGBA":
1013 if mode == "P":
1014 return self.quantize(colors)
1015 elif mode == "PA":
1016 r, g, b, a = self.split()
1017 rgb = merge("RGB", (r, g, b))
1018 p = rgb.quantize(colors)
1019 return merge("PA", (p, a))
1021 trns = None
1022 delete_trns = False
1023 # transparency handling
1024 if has_transparency:
1025 if (self.mode in ("1", "L", "I", "I;16") and mode in ("LA", "RGBA")) or (
1026 self.mode == "RGB" and mode in ("La", "LA", "RGBa", "RGBA")
1027 ):
1028 # Use transparent conversion to promote from transparent
1029 # color to an alpha channel.
1030 new_im = self._new(
1031 self.im.convert_transparent(mode, self.info["transparency"])
1032 )
1033 del new_im.info["transparency"]
1034 return new_im
1035 elif self.mode in ("L", "RGB", "P") and mode in ("L", "RGB", "P"):
1036 t = self.info["transparency"]
1037 if isinstance(t, bytes):
1038 # Dragons. This can't be represented by a single color
1039 warnings.warn(
1040 "Palette images with Transparency expressed in bytes should be "
1041 "converted to RGBA images"
1042 )
1043 delete_trns = True
1044 else:
1045 # get the new transparency color.
1046 # use existing conversions
1047 trns_im = new(self.mode, (1, 1))
1048 if self.mode == "P":
1049 assert self.palette is not None
1050 trns_im.putpalette(self.palette, self.palette.mode)
1051 if isinstance(t, tuple):
1052 err = "Couldn't allocate a palette color for transparency"
1053 assert trns_im.palette is not None
1054 try:
1055 t = trns_im.palette.getcolor(t, self)
1056 except ValueError as e:
1057 if str(e) == "cannot allocate more than 256 colors":
1058 # If all 256 colors are in use,
1059 # then there is no need for transparency
1060 t = None
1061 else:
1062 raise ValueError(err) from e
1063 if t is None:
1064 trns = None
1065 else:
1066 trns_im.putpixel((0, 0), t)
1068 if mode in ("L", "RGB"):
1069 trns_im = trns_im.convert(mode)
1070 else:
1071 # can't just retrieve the palette number, got to do it
1072 # after quantization.
1073 trns_im = trns_im.convert("RGB")
1074 trns = trns_im.getpixel((0, 0))
1076 elif self.mode == "P" and mode in ("LA", "PA", "RGBA"):
1077 t = self.info["transparency"]
1078 delete_trns = True
1080 if isinstance(t, bytes):
1081 self.im.putpalettealphas(t)
1082 elif isinstance(t, int):
1083 self.im.putpalettealpha(t, 0)
1084 else:
1085 msg = "Transparency for P mode should be bytes or int"
1086 raise ValueError(msg)
1088 if mode == "P" and palette == Palette.ADAPTIVE:
1089 im = self.im.quantize(colors)
1090 new_im = self._new(im)
1091 from . import ImagePalette
1093 new_im.palette = ImagePalette.ImagePalette(
1094 "RGB", new_im.im.getpalette("RGB")
1095 )
1096 if delete_trns:
1097 # This could possibly happen if we requantize to fewer colors.
1098 # The transparency would be totally off in that case.
1099 del new_im.info["transparency"]
1100 if trns is not None:
1101 try:
1102 new_im.info["transparency"] = new_im.palette.getcolor(
1103 cast(tuple[int, ...], trns), # trns was converted to RGB
1104 new_im,
1105 )
1106 except Exception:
1107 # if we can't make a transparent color, don't leave the old
1108 # transparency hanging around to mess us up.
1109 del new_im.info["transparency"]
1110 warnings.warn("Couldn't allocate palette entry for transparency")
1111 return new_im
1113 if "LAB" in (self.mode, mode):
1114 im = self
1115 if mode == "LAB":
1116 if im.mode not in ("RGB", "RGBA", "RGBX"):
1117 im = im.convert("RGBA")
1118 other_mode = im.mode
1119 else:
1120 other_mode = mode
1121 if other_mode in ("RGB", "RGBA", "RGBX"):
1122 from . import ImageCms
1124 srgb = ImageCms.createProfile("sRGB")
1125 lab = ImageCms.createProfile("LAB")
1126 profiles = [lab, srgb] if im.mode == "LAB" else [srgb, lab]
1127 transform = ImageCms.buildTransform(
1128 profiles[0], profiles[1], im.mode, mode
1129 )
1130 return transform.apply(im)
1132 # colorspace conversion
1133 if dither is None:
1134 dither = Dither.FLOYDSTEINBERG
1136 try:
1137 im = self.im.convert(mode, dither)
1138 except ValueError:
1139 try:
1140 # normalize source image and try again
1141 modebase = getmodebase(self.mode)
1142 if modebase == self.mode:
1143 raise
1144 im = self.im.convert(modebase)
1145 im = im.convert(mode, dither)
1146 except KeyError as e:
1147 msg = "illegal conversion"
1148 raise ValueError(msg) from e
1150 new_im = self._new(im)
1151 if mode in ("P", "PA") and palette != Palette.ADAPTIVE:
1152 from . import ImagePalette
1154 new_im.palette = ImagePalette.ImagePalette("RGB", im.getpalette("RGB"))
1155 if delete_trns:
1156 # crash fail if we leave a bytes transparency in an rgb/l mode.
1157 del new_im.info["transparency"]
1158 if trns is not None:
1159 if new_im.mode == "P" and new_im.palette:
1160 try:
1161 new_im.info["transparency"] = new_im.palette.getcolor(
1162 cast(tuple[int, ...], trns), new_im # trns was converted to RGB
1163 )
1164 except ValueError as e:
1165 del new_im.info["transparency"]
1166 if str(e) != "cannot allocate more than 256 colors":
1167 # If all 256 colors are in use,
1168 # then there is no need for transparency
1169 warnings.warn(
1170 "Couldn't allocate palette entry for transparency"
1171 )
1172 else:
1173 new_im.info["transparency"] = trns
1174 return new_im
1176 def quantize(
1177 self,
1178 colors: int = 256,
1179 method: int | None = None,
1180 kmeans: int = 0,
1181 palette: Image | None = None,
1182 dither: Dither = Dither.FLOYDSTEINBERG,
1183 ) -> Image:
1184 """
1185 Convert the image to 'P' mode with the specified number
1186 of colors.
1188 :param colors: The desired number of colors, <= 256
1189 :param method: :data:`Quantize.MEDIANCUT` (median cut),
1190 :data:`Quantize.MAXCOVERAGE` (maximum coverage),
1191 :data:`Quantize.FASTOCTREE` (fast octree),
1192 :data:`Quantize.LIBIMAGEQUANT` (libimagequant; check support
1193 using :py:func:`PIL.features.check_feature` with
1194 ``feature="libimagequant"``).
1196 By default, :data:`Quantize.MEDIANCUT` will be used.
1198 The exception to this is RGBA images. :data:`Quantize.MEDIANCUT`
1199 and :data:`Quantize.MAXCOVERAGE` do not support RGBA images, so
1200 :data:`Quantize.FASTOCTREE` is used by default instead.
1201 :param kmeans: Integer greater than or equal to zero.
1202 :param palette: Quantize to the palette of given
1203 :py:class:`PIL.Image.Image`.
1204 :param dither: Dithering method, used when converting from
1205 mode "RGB" to "P" or from "RGB" or "L" to "1".
1206 Available methods are :data:`Dither.NONE` or :data:`Dither.FLOYDSTEINBERG`
1207 (default).
1208 :returns: A new image
1209 """
1211 self.load()
1213 if method is None:
1214 # defaults:
1215 method = Quantize.MEDIANCUT
1216 if self.mode == "RGBA":
1217 method = Quantize.FASTOCTREE
1219 if self.mode == "RGBA" and method not in (
1220 Quantize.FASTOCTREE,
1221 Quantize.LIBIMAGEQUANT,
1222 ):
1223 # Caller specified an invalid mode.
1224 msg = (
1225 "Fast Octree (method == 2) and libimagequant (method == 3) "
1226 "are the only valid methods for quantizing RGBA images"
1227 )
1228 raise ValueError(msg)
1230 if palette:
1231 # use palette from reference image
1232 palette.load()
1233 if palette.mode != "P":
1234 msg = "bad mode for palette image"
1235 raise ValueError(msg)
1236 if self.mode not in {"RGB", "L"}:
1237 msg = "only RGB or L mode images can be quantized to a palette"
1238 raise ValueError(msg)
1239 im = self.im.convert("P", dither, palette.im)
1240 new_im = self._new(im)
1241 assert palette.palette is not None
1242 new_im.palette = palette.palette.copy()
1243 return new_im
1245 if kmeans < 0:
1246 msg = "kmeans must not be negative"
1247 raise ValueError(msg)
1249 im = self._new(self.im.quantize(colors, method, kmeans))
1251 from . import ImagePalette
1253 mode = im.im.getpalettemode()
1254 palette_data = im.im.getpalette(mode, mode)[: colors * len(mode)]
1255 im.palette = ImagePalette.ImagePalette(mode, palette_data)
1257 return im
1259 def copy(self) -> Image:
1260 """
1261 Copies this image. Use this method if you wish to paste things
1262 into an image, but still retain the original.
1264 :rtype: :py:class:`~PIL.Image.Image`
1265 :returns: An :py:class:`~PIL.Image.Image` object.
1266 """
1267 self.load()
1268 return self._new(self.im.copy())
1270 __copy__ = copy
1272 def crop(self, box: tuple[float, float, float, float] | None = None) -> Image:
1273 """
1274 Returns a rectangular region from this image. The box is a
1275 4-tuple defining the left, upper, right, and lower pixel
1276 coordinate. See :ref:`coordinate-system`.
1278 Note: Prior to Pillow 3.4.0, this was a lazy operation.
1280 :param box: The crop rectangle, as a (left, upper, right, lower)-tuple.
1281 :rtype: :py:class:`~PIL.Image.Image`
1282 :returns: An :py:class:`~PIL.Image.Image` object.
1283 """
1285 if box is None:
1286 return self.copy()
1288 if box[2] < box[0]:
1289 msg = "Coordinate 'right' is less than 'left'"
1290 raise ValueError(msg)
1291 elif box[3] < box[1]:
1292 msg = "Coordinate 'lower' is less than 'upper'"
1293 raise ValueError(msg)
1295 self.load()
1296 return self._new(self._crop(self.im, box))
1298 def _crop(
1299 self, im: core.ImagingCore, box: tuple[float, float, float, float]
1300 ) -> core.ImagingCore:
1301 """
1302 Returns a rectangular region from the core image object im.
1304 This is equivalent to calling im.crop((x0, y0, x1, y1)), but
1305 includes additional sanity checks.
1307 :param im: a core image object
1308 :param box: The crop rectangle, as a (left, upper, right, lower)-tuple.
1309 :returns: A core image object.
1310 """
1312 x0, y0, x1, y1 = map(int, map(round, box))
1314 absolute_values = (abs(x1 - x0), abs(y1 - y0))
1316 _decompression_bomb_check(absolute_values)
1318 return im.crop((x0, y0, x1, y1))
1320 def draft(
1321 self, mode: str | None, size: tuple[int, int] | None
1322 ) -> tuple[str, tuple[int, int, float, float]] | None:
1323 """
1324 Configures the image file loader so it returns a version of the
1325 image that as closely as possible matches the given mode and
1326 size. For example, you can use this method to convert a color
1327 JPEG to grayscale while loading it.
1329 If any changes are made, returns a tuple with the chosen ``mode`` and
1330 ``box`` with coordinates of the original image within the altered one.
1332 Note that this method modifies the :py:class:`~PIL.Image.Image` object
1333 in place. If the image has already been loaded, this method has no
1334 effect.
1336 Note: This method is not implemented for most images. It is
1337 currently implemented only for JPEG and MPO images.
1339 :param mode: The requested mode.
1340 :param size: The requested size in pixels, as a 2-tuple:
1341 (width, height).
1342 """
1343 pass
1345 def filter(self, filter: ImageFilter.Filter | type[ImageFilter.Filter]) -> Image:
1346 """
1347 Filters this image using the given filter. For a list of
1348 available filters, see the :py:mod:`~PIL.ImageFilter` module.
1350 :param filter: Filter kernel.
1351 :returns: An :py:class:`~PIL.Image.Image` object."""
1353 from . import ImageFilter
1355 self.load()
1357 if callable(filter):
1358 filter = filter()
1359 if not hasattr(filter, "filter"):
1360 msg = "filter argument should be ImageFilter.Filter instance or class"
1361 raise TypeError(msg)
1363 multiband = isinstance(filter, ImageFilter.MultibandFilter)
1364 if self.im.bands == 1 or multiband:
1365 return self._new(filter.filter(self.im))
1367 ims = [
1368 self._new(filter.filter(self.im.getband(c))) for c in range(self.im.bands)
1369 ]
1370 return merge(self.mode, ims)
1372 def getbands(self) -> tuple[str, ...]:
1373 """
1374 Returns a tuple containing the name of each band in this image.
1375 For example, ``getbands`` on an RGB image returns ("R", "G", "B").
1377 :returns: A tuple containing band names.
1378 :rtype: tuple
1379 """
1380 return ImageMode.getmode(self.mode).bands
1382 def getbbox(self, *, alpha_only: bool = True) -> tuple[int, int, int, int] | None:
1383 """
1384 Calculates the bounding box of the non-zero regions in the
1385 image.
1387 :param alpha_only: Optional flag, defaulting to ``True``.
1388 If ``True`` and the image has an alpha channel, trim transparent pixels.
1389 Otherwise, trim pixels when all channels are zero.
1390 Keyword-only argument.
1391 :returns: The bounding box is returned as a 4-tuple defining the
1392 left, upper, right, and lower pixel coordinate. See
1393 :ref:`coordinate-system`. If the image is completely empty, this
1394 method returns None.
1396 """
1398 self.load()
1399 return self.im.getbbox(alpha_only)
1401 def getcolors(
1402 self, maxcolors: int = 256
1403 ) -> list[tuple[int, tuple[int, ...]]] | list[tuple[int, float]] | None:
1404 """
1405 Returns a list of colors used in this image.
1407 The colors will be in the image's mode. For example, an RGB image will
1408 return a tuple of (red, green, blue) color values, and a P image will
1409 return the index of the color in the palette.
1411 :param maxcolors: Maximum number of colors. If this number is
1412 exceeded, this method returns None. The default limit is
1413 256 colors.
1414 :returns: An unsorted list of (count, pixel) values.
1415 """
1417 self.load()
1418 if self.mode in ("1", "L", "P"):
1419 h = self.im.histogram()
1420 out: list[tuple[int, float]] = [(h[i], i) for i in range(256) if h[i]]
1421 if len(out) > maxcolors:
1422 return None
1423 return out
1424 return self.im.getcolors(maxcolors)
1426 def getdata(self, band: int | None = None) -> core.ImagingCore:
1427 """
1428 Returns the contents of this image as a sequence object
1429 containing pixel values. The sequence object is flattened, so
1430 that values for line one follow directly after the values of
1431 line zero, and so on.
1433 Note that the sequence object returned by this method is an
1434 internal PIL data type, which only supports certain sequence
1435 operations. To convert it to an ordinary sequence (e.g. for
1436 printing), use ``list(im.getdata())``.
1438 :param band: What band to return. The default is to return
1439 all bands. To return a single band, pass in the index
1440 value (e.g. 0 to get the "R" band from an "RGB" image).
1441 :returns: A sequence-like object.
1442 """
1444 self.load()
1445 if band is not None:
1446 return self.im.getband(band)
1447 return self.im # could be abused
1449 def getextrema(self) -> tuple[float, float] | tuple[tuple[int, int], ...]:
1450 """
1451 Gets the minimum and maximum pixel values for each band in
1452 the image.
1454 :returns: For a single-band image, a 2-tuple containing the
1455 minimum and maximum pixel value. For a multi-band image,
1456 a tuple containing one 2-tuple for each band.
1457 """
1459 self.load()
1460 if self.im.bands > 1:
1461 return tuple(self.im.getband(i).getextrema() for i in range(self.im.bands))
1462 return self.im.getextrema()
1464 def getxmp(self) -> dict[str, Any]:
1465 """
1466 Returns a dictionary containing the XMP tags.
1467 Requires defusedxml to be installed.
1469 :returns: XMP tags in a dictionary.
1470 """
1472 def get_name(tag: str) -> str:
1473 return re.sub("^{[^}]+}", "", tag)
1475 def get_value(element: Element) -> str | dict[str, Any] | None:
1476 value: dict[str, Any] = {get_name(k): v for k, v in element.attrib.items()}
1477 children = list(element)
1478 if children:
1479 for child in children:
1480 name = get_name(child.tag)
1481 child_value = get_value(child)
1482 if name in value:
1483 if not isinstance(value[name], list):
1484 value[name] = [value[name]]
1485 value[name].append(child_value)
1486 else:
1487 value[name] = child_value
1488 elif value:
1489 if element.text:
1490 value["text"] = element.text
1491 else:
1492 return element.text
1493 return value
1495 if ElementTree is None:
1496 warnings.warn("XMP data cannot be read without defusedxml dependency")
1497 return {}
1498 if "xmp" not in self.info:
1499 return {}
1500 root = ElementTree.fromstring(self.info["xmp"].rstrip(b"\x00 "))
1501 return {get_name(root.tag): get_value(root)}
1503 def getexif(self) -> Exif:
1504 """
1505 Gets EXIF data from the image.
1507 :returns: an :py:class:`~PIL.Image.Exif` object.
1508 """
1509 if self._exif is None:
1510 self._exif = Exif()
1511 elif self._exif._loaded:
1512 return self._exif
1513 self._exif._loaded = True
1515 exif_info = self.info.get("exif")
1516 if exif_info is None:
1517 if "Raw profile type exif" in self.info:
1518 exif_info = bytes.fromhex(
1519 "".join(self.info["Raw profile type exif"].split("\n")[3:])
1520 )
1521 elif hasattr(self, "tag_v2"):
1522 self._exif.bigtiff = self.tag_v2._bigtiff
1523 self._exif.endian = self.tag_v2._endian
1524 self._exif.load_from_fp(self.fp, self.tag_v2._offset)
1525 if exif_info is not None:
1526 self._exif.load(exif_info)
1528 # XMP tags
1529 if ExifTags.Base.Orientation not in self._exif:
1530 xmp_tags = self.info.get("XML:com.adobe.xmp")
1531 pattern: str | bytes = r'tiff:Orientation(="|>)([0-9])'
1532 if not xmp_tags and (xmp_tags := self.info.get("xmp")):
1533 pattern = rb'tiff:Orientation(="|>)([0-9])'
1534 if xmp_tags:
1535 match = re.search(pattern, xmp_tags)
1536 if match:
1537 self._exif[ExifTags.Base.Orientation] = int(match[2])
1539 return self._exif
1541 def _reload_exif(self) -> None:
1542 if self._exif is None or not self._exif._loaded:
1543 return
1544 self._exif._loaded = False
1545 self.getexif()
1547 def get_child_images(self) -> list[ImageFile.ImageFile]:
1548 from . import ImageFile
1550 deprecate("Image.Image.get_child_images", 13)
1551 return ImageFile.ImageFile.get_child_images(self) # type: ignore[arg-type]
1553 def getim(self) -> CapsuleType:
1554 """
1555 Returns a capsule that points to the internal image memory.
1557 :returns: A capsule object.
1558 """
1560 self.load()
1561 return self.im.ptr
1563 def getpalette(self, rawmode: str | None = "RGB") -> list[int] | None:
1564 """
1565 Returns the image palette as a list.
1567 :param rawmode: The mode in which to return the palette. ``None`` will
1568 return the palette in its current mode.
1570 .. versionadded:: 9.1.0
1572 :returns: A list of color values [r, g, b, ...], or None if the
1573 image has no palette.
1574 """
1576 self.load()
1577 try:
1578 mode = self.im.getpalettemode()
1579 except ValueError:
1580 return None # no palette
1581 if rawmode is None:
1582 rawmode = mode
1583 return list(self.im.getpalette(mode, rawmode))
1585 @property
1586 def has_transparency_data(self) -> bool:
1587 """
1588 Determine if an image has transparency data, whether in the form of an
1589 alpha channel, a palette with an alpha channel, or a "transparency" key
1590 in the info dictionary.
1592 Note the image might still appear solid, if all of the values shown
1593 within are opaque.
1595 :returns: A boolean.
1596 """
1597 if (
1598 self.mode in ("LA", "La", "PA", "RGBA", "RGBa")
1599 or "transparency" in self.info
1600 ):
1601 return True
1602 if self.mode == "P":
1603 assert self.palette is not None
1604 return self.palette.mode.endswith("A")
1605 return False
1607 def apply_transparency(self) -> None:
1608 """
1609 If a P mode image has a "transparency" key in the info dictionary,
1610 remove the key and instead apply the transparency to the palette.
1611 Otherwise, the image is unchanged.
1612 """
1613 if self.mode != "P" or "transparency" not in self.info:
1614 return
1616 from . import ImagePalette
1618 palette = self.getpalette("RGBA")
1619 assert palette is not None
1620 transparency = self.info["transparency"]
1621 if isinstance(transparency, bytes):
1622 for i, alpha in enumerate(transparency):
1623 palette[i * 4 + 3] = alpha
1624 else:
1625 palette[transparency * 4 + 3] = 0
1626 self.palette = ImagePalette.ImagePalette("RGBA", bytes(palette))
1627 self.palette.dirty = 1
1629 del self.info["transparency"]
1631 def getpixel(
1632 self, xy: tuple[int, int] | list[int]
1633 ) -> float | tuple[int, ...] | None:
1634 """
1635 Returns the pixel value at a given position.
1637 :param xy: The coordinate, given as (x, y). See
1638 :ref:`coordinate-system`.
1639 :returns: The pixel value. If the image is a multi-layer image,
1640 this method returns a tuple.
1641 """
1643 self.load()
1644 return self.im.getpixel(tuple(xy))
1646 def getprojection(self) -> tuple[list[int], list[int]]:
1647 """
1648 Get projection to x and y axes
1650 :returns: Two sequences, indicating where there are non-zero
1651 pixels along the X-axis and the Y-axis, respectively.
1652 """
1654 self.load()
1655 x, y = self.im.getprojection()
1656 return list(x), list(y)
1658 def histogram(
1659 self, mask: Image | None = None, extrema: tuple[float, float] | None = None
1660 ) -> list[int]:
1661 """
1662 Returns a histogram for the image. The histogram is returned as a
1663 list of pixel counts, one for each pixel value in the source
1664 image. Counts are grouped into 256 bins for each band, even if
1665 the image has more than 8 bits per band. If the image has more
1666 than one band, the histograms for all bands are concatenated (for
1667 example, the histogram for an "RGB" image contains 768 values).
1669 A bilevel image (mode "1") is treated as a grayscale ("L") image
1670 by this method.
1672 If a mask is provided, the method returns a histogram for those
1673 parts of the image where the mask image is non-zero. The mask
1674 image must have the same size as the image, and be either a
1675 bi-level image (mode "1") or a grayscale image ("L").
1677 :param mask: An optional mask.
1678 :param extrema: An optional tuple of manually-specified extrema.
1679 :returns: A list containing pixel counts.
1680 """
1681 self.load()
1682 if mask:
1683 mask.load()
1684 return self.im.histogram((0, 0), mask.im)
1685 if self.mode in ("I", "F"):
1686 return self.im.histogram(
1687 extrema if extrema is not None else self.getextrema()
1688 )
1689 return self.im.histogram()
1691 def entropy(
1692 self, mask: Image | None = None, extrema: tuple[float, float] | None = None
1693 ) -> float:
1694 """
1695 Calculates and returns the entropy for the image.
1697 A bilevel image (mode "1") is treated as a grayscale ("L")
1698 image by this method.
1700 If a mask is provided, the method employs the histogram for
1701 those parts of the image where the mask image is non-zero.
1702 The mask image must have the same size as the image, and be
1703 either a bi-level image (mode "1") or a grayscale image ("L").
1705 :param mask: An optional mask.
1706 :param extrema: An optional tuple of manually-specified extrema.
1707 :returns: A float value representing the image entropy
1708 """
1709 self.load()
1710 if mask:
1711 mask.load()
1712 return self.im.entropy((0, 0), mask.im)
1713 if self.mode in ("I", "F"):
1714 return self.im.entropy(
1715 extrema if extrema is not None else self.getextrema()
1716 )
1717 return self.im.entropy()
1719 def paste(
1720 self,
1721 im: Image | str | float | tuple[float, ...],
1722 box: Image | tuple[int, int, int, int] | tuple[int, int] | None = None,
1723 mask: Image | None = None,
1724 ) -> None:
1725 """
1726 Pastes another image into this image. The box argument is either
1727 a 2-tuple giving the upper left corner, a 4-tuple defining the
1728 left, upper, right, and lower pixel coordinate, or None (same as
1729 (0, 0)). See :ref:`coordinate-system`. If a 4-tuple is given, the size
1730 of the pasted image must match the size of the region.
1732 If the modes don't match, the pasted image is converted to the mode of
1733 this image (see the :py:meth:`~PIL.Image.Image.convert` method for
1734 details).
1736 Instead of an image, the source can be a integer or tuple
1737 containing pixel values. The method then fills the region
1738 with the given color. When creating RGB images, you can
1739 also use color strings as supported by the ImageColor module. See
1740 :ref:`colors` for more information.
1742 If a mask is given, this method updates only the regions
1743 indicated by the mask. You can use either "1", "L", "LA", "RGBA"
1744 or "RGBa" images (if present, the alpha band is used as mask).
1745 Where the mask is 255, the given image is copied as is. Where
1746 the mask is 0, the current value is preserved. Intermediate
1747 values will mix the two images together, including their alpha
1748 channels if they have them.
1750 See :py:meth:`~PIL.Image.Image.alpha_composite` if you want to
1751 combine images with respect to their alpha channels.
1753 :param im: Source image or pixel value (integer, float or tuple).
1754 :param box: An optional 4-tuple giving the region to paste into.
1755 If a 2-tuple is used instead, it's treated as the upper left
1756 corner. If omitted or None, the source is pasted into the
1757 upper left corner.
1759 If an image is given as the second argument and there is no
1760 third, the box defaults to (0, 0), and the second argument
1761 is interpreted as a mask image.
1762 :param mask: An optional mask image.
1763 """
1765 if isinstance(box, Image):
1766 if mask is not None:
1767 msg = "If using second argument as mask, third argument must be None"
1768 raise ValueError(msg)
1769 # abbreviated paste(im, mask) syntax
1770 mask = box
1771 box = None
1773 if box is None:
1774 box = (0, 0)
1776 if len(box) == 2:
1777 # upper left corner given; get size from image or mask
1778 if isinstance(im, Image):
1779 size = im.size
1780 elif isinstance(mask, Image):
1781 size = mask.size
1782 else:
1783 # FIXME: use self.size here?
1784 msg = "cannot determine region size; use 4-item box"
1785 raise ValueError(msg)
1786 box += (box[0] + size[0], box[1] + size[1])
1788 source: core.ImagingCore | str | float | tuple[float, ...]
1789 if isinstance(im, str):
1790 from . import ImageColor
1792 source = ImageColor.getcolor(im, self.mode)
1793 elif isinstance(im, Image):
1794 im.load()
1795 if self.mode != im.mode:
1796 if self.mode != "RGB" or im.mode not in ("LA", "RGBA", "RGBa"):
1797 # should use an adapter for this!
1798 im = im.convert(self.mode)
1799 source = im.im
1800 else:
1801 source = im
1803 self._ensure_mutable()
1805 if mask:
1806 mask.load()
1807 self.im.paste(source, box, mask.im)
1808 else:
1809 self.im.paste(source, box)
1811 def alpha_composite(
1812 self, im: Image, dest: Sequence[int] = (0, 0), source: Sequence[int] = (0, 0)
1813 ) -> None:
1814 """'In-place' analog of Image.alpha_composite. Composites an image
1815 onto this image.
1817 :param im: image to composite over this one
1818 :param dest: Optional 2 tuple (left, top) specifying the upper
1819 left corner in this (destination) image.
1820 :param source: Optional 2 (left, top) tuple for the upper left
1821 corner in the overlay source image, or 4 tuple (left, top, right,
1822 bottom) for the bounds of the source rectangle
1824 Performance Note: Not currently implemented in-place in the core layer.
1825 """
1827 if not isinstance(source, (list, tuple)):
1828 msg = "Source must be a list or tuple"
1829 raise ValueError(msg)
1830 if not isinstance(dest, (list, tuple)):
1831 msg = "Destination must be a list or tuple"
1832 raise ValueError(msg)
1834 if len(source) == 4:
1835 overlay_crop_box = tuple(source)
1836 elif len(source) == 2:
1837 overlay_crop_box = tuple(source) + im.size
1838 else:
1839 msg = "Source must be a sequence of length 2 or 4"
1840 raise ValueError(msg)
1842 if not len(dest) == 2:
1843 msg = "Destination must be a sequence of length 2"
1844 raise ValueError(msg)
1845 if min(source) < 0:
1846 msg = "Source must be non-negative"
1847 raise ValueError(msg)
1849 # over image, crop if it's not the whole image.
1850 if overlay_crop_box == (0, 0) + im.size:
1851 overlay = im
1852 else:
1853 overlay = im.crop(overlay_crop_box)
1855 # target for the paste
1856 box = tuple(dest) + (dest[0] + overlay.width, dest[1] + overlay.height)
1858 # destination image. don't copy if we're using the whole image.
1859 if box == (0, 0) + self.size:
1860 background = self
1861 else:
1862 background = self.crop(box)
1864 result = alpha_composite(background, overlay)
1865 self.paste(result, box)
1867 def point(
1868 self,
1869 lut: (
1870 Sequence[float]
1871 | NumpyArray
1872 | Callable[[int], float]
1873 | Callable[[ImagePointTransform], ImagePointTransform | float]
1874 | ImagePointHandler
1875 ),
1876 mode: str | None = None,
1877 ) -> Image:
1878 """
1879 Maps this image through a lookup table or function.
1881 :param lut: A lookup table, containing 256 (or 65536 if
1882 self.mode=="I" and mode == "L") values per band in the
1883 image. A function can be used instead, it should take a
1884 single argument. The function is called once for each
1885 possible pixel value, and the resulting table is applied to
1886 all bands of the image.
1888 It may also be an :py:class:`~PIL.Image.ImagePointHandler`
1889 object::
1891 class Example(Image.ImagePointHandler):
1892 def point(self, im: Image) -> Image:
1893 # Return result
1894 :param mode: Output mode (default is same as input). This can only be used if
1895 the source image has mode "L" or "P", and the output has mode "1" or the
1896 source image mode is "I" and the output mode is "L".
1897 :returns: An :py:class:`~PIL.Image.Image` object.
1898 """
1900 self.load()
1902 if isinstance(lut, ImagePointHandler):
1903 return lut.point(self)
1905 if callable(lut):
1906 # if it isn't a list, it should be a function
1907 if self.mode in ("I", "I;16", "F"):
1908 # check if the function can be used with point_transform
1909 # UNDONE wiredfool -- I think this prevents us from ever doing
1910 # a gamma function point transform on > 8bit images.
1911 scale, offset = _getscaleoffset(lut) # type: ignore[arg-type]
1912 return self._new(self.im.point_transform(scale, offset))
1913 # for other modes, convert the function to a table
1914 flatLut = [lut(i) for i in range(256)] * self.im.bands # type: ignore[arg-type]
1915 else:
1916 flatLut = lut
1918 if self.mode == "F":
1919 # FIXME: _imaging returns a confusing error message for this case
1920 msg = "point operation not supported for this mode"
1921 raise ValueError(msg)
1923 if mode != "F":
1924 flatLut = [round(i) for i in flatLut]
1925 return self._new(self.im.point(flatLut, mode))
1927 def putalpha(self, alpha: Image | int) -> None:
1928 """
1929 Adds or replaces the alpha layer in this image. If the image
1930 does not have an alpha layer, it's converted to "LA" or "RGBA".
1931 The new layer must be either "L" or "1".
1933 :param alpha: The new alpha layer. This can either be an "L" or "1"
1934 image having the same size as this image, or an integer.
1935 """
1937 self._ensure_mutable()
1939 if self.mode not in ("LA", "PA", "RGBA"):
1940 # attempt to promote self to a matching alpha mode
1941 try:
1942 mode = getmodebase(self.mode) + "A"
1943 try:
1944 self.im.setmode(mode)
1945 except (AttributeError, ValueError) as e:
1946 # do things the hard way
1947 im = self.im.convert(mode)
1948 if im.mode not in ("LA", "PA", "RGBA"):
1949 msg = "alpha channel could not be added"
1950 raise ValueError(msg) from e # sanity check
1951 self.im = im
1952 self._mode = self.im.mode
1953 except KeyError as e:
1954 msg = "illegal image mode"
1955 raise ValueError(msg) from e
1957 if self.mode in ("LA", "PA"):
1958 band = 1
1959 else:
1960 band = 3
1962 if isinstance(alpha, Image):
1963 # alpha layer
1964 if alpha.mode not in ("1", "L"):
1965 msg = "illegal image mode"
1966 raise ValueError(msg)
1967 alpha.load()
1968 if alpha.mode == "1":
1969 alpha = alpha.convert("L")
1970 else:
1971 # constant alpha
1972 try:
1973 self.im.fillband(band, alpha)
1974 except (AttributeError, ValueError):
1975 # do things the hard way
1976 alpha = new("L", self.size, alpha)
1977 else:
1978 return
1980 self.im.putband(alpha.im, band)
1982 def putdata(
1983 self,
1984 data: Sequence[float] | Sequence[Sequence[int]] | core.ImagingCore | NumpyArray,
1985 scale: float = 1.0,
1986 offset: float = 0.0,
1987 ) -> None:
1988 """
1989 Copies pixel data from a flattened sequence object into the image. The
1990 values should start at the upper left corner (0, 0), continue to the
1991 end of the line, followed directly by the first value of the second
1992 line, and so on. Data will be read until either the image or the
1993 sequence ends. The scale and offset values are used to adjust the
1994 sequence values: **pixel = value*scale + offset**.
1996 :param data: A flattened sequence object. See :ref:`colors` for more
1997 information about values.
1998 :param scale: An optional scale value. The default is 1.0.
1999 :param offset: An optional offset value. The default is 0.0.
2000 """
2002 self._ensure_mutable()
2004 self.im.putdata(data, scale, offset)
2006 def putpalette(
2007 self,
2008 data: ImagePalette.ImagePalette | bytes | Sequence[int],
2009 rawmode: str = "RGB",
2010 ) -> None:
2011 """
2012 Attaches a palette to this image. The image must be a "P", "PA", "L"
2013 or "LA" image.
2015 The palette sequence must contain at most 256 colors, made up of one
2016 integer value for each channel in the raw mode.
2017 For example, if the raw mode is "RGB", then it can contain at most 768
2018 values, made up of red, green and blue values for the corresponding pixel
2019 index in the 256 colors.
2020 If the raw mode is "RGBA", then it can contain at most 1024 values,
2021 containing red, green, blue and alpha values.
2023 Alternatively, an 8-bit string may be used instead of an integer sequence.
2025 :param data: A palette sequence (either a list or a string).
2026 :param rawmode: The raw mode of the palette. Either "RGB", "RGBA", or a mode
2027 that can be transformed to "RGB" or "RGBA" (e.g. "R", "BGR;15", "RGBA;L").
2028 """
2029 from . import ImagePalette
2031 if self.mode not in ("L", "LA", "P", "PA"):
2032 msg = "illegal image mode"
2033 raise ValueError(msg)
2034 if isinstance(data, ImagePalette.ImagePalette):
2035 if data.rawmode is not None:
2036 palette = ImagePalette.raw(data.rawmode, data.palette)
2037 else:
2038 palette = ImagePalette.ImagePalette(palette=data.palette)
2039 palette.dirty = 1
2040 else:
2041 if not isinstance(data, bytes):
2042 data = bytes(data)
2043 palette = ImagePalette.raw(rawmode, data)
2044 self._mode = "PA" if "A" in self.mode else "P"
2045 self.palette = palette
2046 self.palette.mode = "RGBA" if "A" in rawmode else "RGB"
2047 self.load() # install new palette
2049 def putpixel(
2050 self, xy: tuple[int, int], value: float | tuple[int, ...] | list[int]
2051 ) -> None:
2052 """
2053 Modifies the pixel at the given position. The color is given as
2054 a single numerical value for single-band images, and a tuple for
2055 multi-band images. In addition to this, RGB and RGBA tuples are
2056 accepted for P and PA images. See :ref:`colors` for more information.
2058 Note that this method is relatively slow. For more extensive changes,
2059 use :py:meth:`~PIL.Image.Image.paste` or the :py:mod:`~PIL.ImageDraw`
2060 module instead.
2062 See:
2064 * :py:meth:`~PIL.Image.Image.paste`
2065 * :py:meth:`~PIL.Image.Image.putdata`
2066 * :py:mod:`~PIL.ImageDraw`
2068 :param xy: The pixel coordinate, given as (x, y). See
2069 :ref:`coordinate-system`.
2070 :param value: The pixel value.
2071 """
2073 self._ensure_mutable()
2075 if (
2076 self.mode in ("P", "PA")
2077 and isinstance(value, (list, tuple))
2078 and len(value) in [3, 4]
2079 ):
2080 # RGB or RGBA value for a P or PA image
2081 if self.mode == "PA":
2082 alpha = value[3] if len(value) == 4 else 255
2083 value = value[:3]
2084 assert self.palette is not None
2085 palette_index = self.palette.getcolor(tuple(value), self)
2086 value = (palette_index, alpha) if self.mode == "PA" else palette_index
2087 return self.im.putpixel(xy, value)
2089 def remap_palette(
2090 self, dest_map: list[int], source_palette: bytes | bytearray | None = None
2091 ) -> Image:
2092 """
2093 Rewrites the image to reorder the palette.
2095 :param dest_map: A list of indexes into the original palette.
2096 e.g. ``[1,0]`` would swap a two item palette, and ``list(range(256))``
2097 is the identity transform.
2098 :param source_palette: Bytes or None.
2099 :returns: An :py:class:`~PIL.Image.Image` object.
2101 """
2102 from . import ImagePalette
2104 if self.mode not in ("L", "P"):
2105 msg = "illegal image mode"
2106 raise ValueError(msg)
2108 bands = 3
2109 palette_mode = "RGB"
2110 if source_palette is None:
2111 if self.mode == "P":
2112 self.load()
2113 palette_mode = self.im.getpalettemode()
2114 if palette_mode == "RGBA":
2115 bands = 4
2116 source_palette = self.im.getpalette(palette_mode, palette_mode)
2117 else: # L-mode
2118 source_palette = bytearray(i // 3 for i in range(768))
2119 elif len(source_palette) > 768:
2120 bands = 4
2121 palette_mode = "RGBA"
2123 palette_bytes = b""
2124 new_positions = [0] * 256
2126 # pick only the used colors from the palette
2127 for i, oldPosition in enumerate(dest_map):
2128 palette_bytes += source_palette[
2129 oldPosition * bands : oldPosition * bands + bands
2130 ]
2131 new_positions[oldPosition] = i
2133 # replace the palette color id of all pixel with the new id
2135 # Palette images are [0..255], mapped through a 1 or 3
2136 # byte/color map. We need to remap the whole image
2137 # from palette 1 to palette 2. New_positions is
2138 # an array of indexes into palette 1. Palette 2 is
2139 # palette 1 with any holes removed.
2141 # We're going to leverage the convert mechanism to use the
2142 # C code to remap the image from palette 1 to palette 2,
2143 # by forcing the source image into 'L' mode and adding a
2144 # mapping 'L' mode palette, then converting back to 'L'
2145 # sans palette thus converting the image bytes, then
2146 # assigning the optimized RGB palette.
2148 # perf reference, 9500x4000 gif, w/~135 colors
2149 # 14 sec prepatch, 1 sec postpatch with optimization forced.
2151 mapping_palette = bytearray(new_positions)
2153 m_im = self.copy()
2154 m_im._mode = "P"
2156 m_im.palette = ImagePalette.ImagePalette(
2157 palette_mode, palette=mapping_palette * bands
2158 )
2159 # possibly set palette dirty, then
2160 # m_im.putpalette(mapping_palette, 'L') # converts to 'P'
2161 # or just force it.
2162 # UNDONE -- this is part of the general issue with palettes
2163 m_im.im.putpalette(palette_mode, palette_mode + ";L", m_im.palette.tobytes())
2165 m_im = m_im.convert("L")
2167 m_im.putpalette(palette_bytes, palette_mode)
2168 m_im.palette = ImagePalette.ImagePalette(palette_mode, palette=palette_bytes)
2170 if "transparency" in self.info:
2171 try:
2172 m_im.info["transparency"] = dest_map.index(self.info["transparency"])
2173 except ValueError:
2174 if "transparency" in m_im.info:
2175 del m_im.info["transparency"]
2177 return m_im
2179 def _get_safe_box(
2180 self,
2181 size: tuple[int, int],
2182 resample: Resampling,
2183 box: tuple[float, float, float, float],
2184 ) -> tuple[int, int, int, int]:
2185 """Expands the box so it includes adjacent pixels
2186 that may be used by resampling with the given resampling filter.
2187 """
2188 filter_support = _filters_support[resample] - 0.5
2189 scale_x = (box[2] - box[0]) / size[0]
2190 scale_y = (box[3] - box[1]) / size[1]
2191 support_x = filter_support * scale_x
2192 support_y = filter_support * scale_y
2194 return (
2195 max(0, int(box[0] - support_x)),
2196 max(0, int(box[1] - support_y)),
2197 min(self.size[0], math.ceil(box[2] + support_x)),
2198 min(self.size[1], math.ceil(box[3] + support_y)),
2199 )
2201 def resize(
2202 self,
2203 size: tuple[int, int] | list[int] | NumpyArray,
2204 resample: int | None = None,
2205 box: tuple[float, float, float, float] | None = None,
2206 reducing_gap: float | None = None,
2207 ) -> Image:
2208 """
2209 Returns a resized copy of this image.
2211 :param size: The requested size in pixels, as a tuple or array:
2212 (width, height).
2213 :param resample: An optional resampling filter. This can be
2214 one of :py:data:`Resampling.NEAREST`, :py:data:`Resampling.BOX`,
2215 :py:data:`Resampling.BILINEAR`, :py:data:`Resampling.HAMMING`,
2216 :py:data:`Resampling.BICUBIC` or :py:data:`Resampling.LANCZOS`.
2217 If the image has mode "1" or "P", it is always set to
2218 :py:data:`Resampling.NEAREST`. Otherwise, the default filter is
2219 :py:data:`Resampling.BICUBIC`. See: :ref:`concept-filters`.
2220 :param box: An optional 4-tuple of floats providing
2221 the source image region to be scaled.
2222 The values must be within (0, 0, width, height) rectangle.
2223 If omitted or None, the entire source is used.
2224 :param reducing_gap: Apply optimization by resizing the image
2225 in two steps. First, reducing the image by integer times
2226 using :py:meth:`~PIL.Image.Image.reduce`.
2227 Second, resizing using regular resampling. The last step
2228 changes size no less than by ``reducing_gap`` times.
2229 ``reducing_gap`` may be None (no first step is performed)
2230 or should be greater than 1.0. The bigger ``reducing_gap``,
2231 the closer the result to the fair resampling.
2232 The smaller ``reducing_gap``, the faster resizing.
2233 With ``reducing_gap`` greater or equal to 3.0, the result is
2234 indistinguishable from fair resampling in most cases.
2235 The default value is None (no optimization).
2236 :returns: An :py:class:`~PIL.Image.Image` object.
2237 """
2239 if resample is None:
2240 resample = Resampling.BICUBIC
2241 elif resample not in (
2242 Resampling.NEAREST,
2243 Resampling.BILINEAR,
2244 Resampling.BICUBIC,
2245 Resampling.LANCZOS,
2246 Resampling.BOX,
2247 Resampling.HAMMING,
2248 ):
2249 msg = f"Unknown resampling filter ({resample})."
2251 filters = [
2252 f"{filter[1]} ({filter[0]})"
2253 for filter in (
2254 (Resampling.NEAREST, "Image.Resampling.NEAREST"),
2255 (Resampling.LANCZOS, "Image.Resampling.LANCZOS"),
2256 (Resampling.BILINEAR, "Image.Resampling.BILINEAR"),
2257 (Resampling.BICUBIC, "Image.Resampling.BICUBIC"),
2258 (Resampling.BOX, "Image.Resampling.BOX"),
2259 (Resampling.HAMMING, "Image.Resampling.HAMMING"),
2260 )
2261 ]
2262 msg += f" Use {', '.join(filters[:-1])} or {filters[-1]}"
2263 raise ValueError(msg)
2265 if reducing_gap is not None and reducing_gap < 1.0:
2266 msg = "reducing_gap must be 1.0 or greater"
2267 raise ValueError(msg)
2269 if box is None:
2270 box = (0, 0) + self.size
2272 size = tuple(size)
2273 if self.size == size and box == (0, 0) + self.size:
2274 return self.copy()
2276 if self.mode in ("1", "P"):
2277 resample = Resampling.NEAREST
2279 if self.mode in ["LA", "RGBA"] and resample != Resampling.NEAREST:
2280 im = self.convert({"LA": "La", "RGBA": "RGBa"}[self.mode])
2281 im = im.resize(size, resample, box)
2282 return im.convert(self.mode)
2284 self.load()
2286 if reducing_gap is not None and resample != Resampling.NEAREST:
2287 factor_x = int((box[2] - box[0]) / size[0] / reducing_gap) or 1
2288 factor_y = int((box[3] - box[1]) / size[1] / reducing_gap) or 1
2289 if factor_x > 1 or factor_y > 1:
2290 reduce_box = self._get_safe_box(size, cast(Resampling, resample), box)
2291 factor = (factor_x, factor_y)
2292 self = (
2293 self.reduce(factor, box=reduce_box)
2294 if callable(self.reduce)
2295 else Image.reduce(self, factor, box=reduce_box)
2296 )
2297 box = (
2298 (box[0] - reduce_box[0]) / factor_x,
2299 (box[1] - reduce_box[1]) / factor_y,
2300 (box[2] - reduce_box[0]) / factor_x,
2301 (box[3] - reduce_box[1]) / factor_y,
2302 )
2304 return self._new(self.im.resize(size, resample, box))
2306 def reduce(
2307 self,
2308 factor: int | tuple[int, int],
2309 box: tuple[int, int, int, int] | None = None,
2310 ) -> Image:
2311 """
2312 Returns a copy of the image reduced ``factor`` times.
2313 If the size of the image is not dividable by ``factor``,
2314 the resulting size will be rounded up.
2316 :param factor: A greater than 0 integer or tuple of two integers
2317 for width and height separately.
2318 :param box: An optional 4-tuple of ints providing
2319 the source image region to be reduced.
2320 The values must be within ``(0, 0, width, height)`` rectangle.
2321 If omitted or ``None``, the entire source is used.
2322 """
2323 if not isinstance(factor, (list, tuple)):
2324 factor = (factor, factor)
2326 if box is None:
2327 box = (0, 0) + self.size
2329 if factor == (1, 1) and box == (0, 0) + self.size:
2330 return self.copy()
2332 if self.mode in ["LA", "RGBA"]:
2333 im = self.convert({"LA": "La", "RGBA": "RGBa"}[self.mode])
2334 im = im.reduce(factor, box)
2335 return im.convert(self.mode)
2337 self.load()
2339 return self._new(self.im.reduce(factor, box))
2341 def rotate(
2342 self,
2343 angle: float,
2344 resample: Resampling = Resampling.NEAREST,
2345 expand: int | bool = False,
2346 center: tuple[float, float] | None = None,
2347 translate: tuple[int, int] | None = None,
2348 fillcolor: float | tuple[float, ...] | str | None = None,
2349 ) -> Image:
2350 """
2351 Returns a rotated copy of this image. This method returns a
2352 copy of this image, rotated the given number of degrees counter
2353 clockwise around its centre.
2355 :param angle: In degrees counter clockwise.
2356 :param resample: An optional resampling filter. This can be
2357 one of :py:data:`Resampling.NEAREST` (use nearest neighbour),
2358 :py:data:`Resampling.BILINEAR` (linear interpolation in a 2x2
2359 environment), or :py:data:`Resampling.BICUBIC` (cubic spline
2360 interpolation in a 4x4 environment). If omitted, or if the image has
2361 mode "1" or "P", it is set to :py:data:`Resampling.NEAREST`.
2362 See :ref:`concept-filters`.
2363 :param expand: Optional expansion flag. If true, expands the output
2364 image to make it large enough to hold the entire rotated image.
2365 If false or omitted, make the output image the same size as the
2366 input image. Note that the expand flag assumes rotation around
2367 the center and no translation.
2368 :param center: Optional center of rotation (a 2-tuple). Origin is
2369 the upper left corner. Default is the center of the image.
2370 :param translate: An optional post-rotate translation (a 2-tuple).
2371 :param fillcolor: An optional color for area outside the rotated image.
2372 :returns: An :py:class:`~PIL.Image.Image` object.
2373 """
2375 angle = angle % 360.0
2377 # Fast paths regardless of filter, as long as we're not
2378 # translating or changing the center.
2379 if not (center or translate):
2380 if angle == 0:
2381 return self.copy()
2382 if angle == 180:
2383 return self.transpose(Transpose.ROTATE_180)
2384 if angle in (90, 270) and (expand or self.width == self.height):
2385 return self.transpose(
2386 Transpose.ROTATE_90 if angle == 90 else Transpose.ROTATE_270
2387 )
2389 # Calculate the affine matrix. Note that this is the reverse
2390 # transformation (from destination image to source) because we
2391 # want to interpolate the (discrete) destination pixel from
2392 # the local area around the (floating) source pixel.
2394 # The matrix we actually want (note that it operates from the right):
2395 # (1, 0, tx) (1, 0, cx) ( cos a, sin a, 0) (1, 0, -cx)
2396 # (0, 1, ty) * (0, 1, cy) * (-sin a, cos a, 0) * (0, 1, -cy)
2397 # (0, 0, 1) (0, 0, 1) ( 0, 0, 1) (0, 0, 1)
2399 # The reverse matrix is thus:
2400 # (1, 0, cx) ( cos -a, sin -a, 0) (1, 0, -cx) (1, 0, -tx)
2401 # (0, 1, cy) * (-sin -a, cos -a, 0) * (0, 1, -cy) * (0, 1, -ty)
2402 # (0, 0, 1) ( 0, 0, 1) (0, 0, 1) (0, 0, 1)
2404 # In any case, the final translation may be updated at the end to
2405 # compensate for the expand flag.
2407 w, h = self.size
2409 if translate is None:
2410 post_trans = (0, 0)
2411 else:
2412 post_trans = translate
2413 if center is None:
2414 center = (w / 2, h / 2)
2416 angle = -math.radians(angle)
2417 matrix = [
2418 round(math.cos(angle), 15),
2419 round(math.sin(angle), 15),
2420 0.0,
2421 round(-math.sin(angle), 15),
2422 round(math.cos(angle), 15),
2423 0.0,
2424 ]
2426 def transform(x: float, y: float, matrix: list[float]) -> tuple[float, float]:
2427 (a, b, c, d, e, f) = matrix
2428 return a * x + b * y + c, d * x + e * y + f
2430 matrix[2], matrix[5] = transform(
2431 -center[0] - post_trans[0], -center[1] - post_trans[1], matrix
2432 )
2433 matrix[2] += center[0]
2434 matrix[5] += center[1]
2436 if expand:
2437 # calculate output size
2438 xx = []
2439 yy = []
2440 for x, y in ((0, 0), (w, 0), (w, h), (0, h)):
2441 transformed_x, transformed_y = transform(x, y, matrix)
2442 xx.append(transformed_x)
2443 yy.append(transformed_y)
2444 nw = math.ceil(max(xx)) - math.floor(min(xx))
2445 nh = math.ceil(max(yy)) - math.floor(min(yy))
2447 # We multiply a translation matrix from the right. Because of its
2448 # special form, this is the same as taking the image of the
2449 # translation vector as new translation vector.
2450 matrix[2], matrix[5] = transform(-(nw - w) / 2.0, -(nh - h) / 2.0, matrix)
2451 w, h = nw, nh
2453 return self.transform(
2454 (w, h), Transform.AFFINE, matrix, resample, fillcolor=fillcolor
2455 )
2457 def save(
2458 self, fp: StrOrBytesPath | IO[bytes], format: str | None = None, **params: Any
2459 ) -> None:
2460 """
2461 Saves this image under the given filename. If no format is
2462 specified, the format to use is determined from the filename
2463 extension, if possible.
2465 Keyword options can be used to provide additional instructions
2466 to the writer. If a writer doesn't recognise an option, it is
2467 silently ignored. The available options are described in the
2468 :doc:`image format documentation
2469 <../handbook/image-file-formats>` for each writer.
2471 You can use a file object instead of a filename. In this case,
2472 you must always specify the format. The file object must
2473 implement the ``seek``, ``tell``, and ``write``
2474 methods, and be opened in binary mode.
2476 :param fp: A filename (string), os.PathLike object or file object.
2477 :param format: Optional format override. If omitted, the
2478 format to use is determined from the filename extension.
2479 If a file object was used instead of a filename, this
2480 parameter should always be used.
2481 :param params: Extra parameters to the image writer. These can also be
2482 set on the image itself through ``encoderinfo``. This is useful when
2483 saving multiple images::
2485 # Saving XMP data to a single image
2486 from PIL import Image
2487 red = Image.new("RGB", (1, 1), "#f00")
2488 red.save("out.mpo", xmp=b"test")
2490 # Saving XMP data to the second frame of an image
2491 from PIL import Image
2492 black = Image.new("RGB", (1, 1))
2493 red = Image.new("RGB", (1, 1), "#f00")
2494 red.encoderinfo = {"xmp": b"test"}
2495 black.save("out.mpo", save_all=True, append_images=[red])
2496 :returns: None
2497 :exception ValueError: If the output format could not be determined
2498 from the file name. Use the format option to solve this.
2499 :exception OSError: If the file could not be written. The file
2500 may have been created, and may contain partial data.
2501 """
2503 filename: str | bytes = ""
2504 open_fp = False
2505 if is_path(fp):
2506 filename = os.fspath(fp)
2507 open_fp = True
2508 elif fp == sys.stdout:
2509 try:
2510 fp = sys.stdout.buffer
2511 except AttributeError:
2512 pass
2513 if not filename and hasattr(fp, "name") and is_path(fp.name):
2514 # only set the name for metadata purposes
2515 filename = os.fspath(fp.name)
2517 preinit()
2519 filename_ext = os.path.splitext(filename)[1].lower()
2520 ext = filename_ext.decode() if isinstance(filename_ext, bytes) else filename_ext
2522 if not format:
2523 if ext not in EXTENSION:
2524 init()
2525 try:
2526 format = EXTENSION[ext]
2527 except KeyError as e:
2528 msg = f"unknown file extension: {ext}"
2529 raise ValueError(msg) from e
2531 from . import ImageFile
2533 # may mutate self!
2534 if isinstance(self, ImageFile.ImageFile) and os.path.abspath(
2535 filename
2536 ) == os.path.abspath(self.filename):
2537 self._ensure_mutable()
2538 else:
2539 self.load()
2541 save_all = params.pop("save_all", None)
2542 self._default_encoderinfo = params
2543 encoderinfo = getattr(self, "encoderinfo", {})
2544 self._attach_default_encoderinfo(self)
2545 self.encoderconfig: tuple[Any, ...] = ()
2547 if format.upper() not in SAVE:
2548 init()
2549 if save_all or (
2550 save_all is None
2551 and params.get("append_images")
2552 and format.upper() in SAVE_ALL
2553 ):
2554 save_handler = SAVE_ALL[format.upper()]
2555 else:
2556 save_handler = SAVE[format.upper()]
2558 created = False
2559 if open_fp:
2560 created = not os.path.exists(filename)
2561 if params.get("append", False):
2562 # Open also for reading ("+"), because TIFF save_all
2563 # writer needs to go back and edit the written data.
2564 fp = builtins.open(filename, "r+b")
2565 else:
2566 fp = builtins.open(filename, "w+b")
2567 else:
2568 fp = cast(IO[bytes], fp)
2570 try:
2571 save_handler(self, fp, filename)
2572 except Exception:
2573 if open_fp:
2574 fp.close()
2575 if created:
2576 try:
2577 os.remove(filename)
2578 except PermissionError:
2579 pass
2580 raise
2581 finally:
2582 self.encoderinfo = encoderinfo
2583 if open_fp:
2584 fp.close()
2586 def _attach_default_encoderinfo(self, im: Image) -> dict[str, Any]:
2587 encoderinfo = getattr(self, "encoderinfo", {})
2588 self.encoderinfo = {**im._default_encoderinfo, **encoderinfo}
2589 return encoderinfo
2591 def seek(self, frame: int) -> None:
2592 """
2593 Seeks to the given frame in this sequence file. If you seek
2594 beyond the end of the sequence, the method raises an
2595 ``EOFError`` exception. When a sequence file is opened, the
2596 library automatically seeks to frame 0.
2598 See :py:meth:`~PIL.Image.Image.tell`.
2600 If defined, :attr:`~PIL.Image.Image.n_frames` refers to the
2601 number of available frames.
2603 :param frame: Frame number, starting at 0.
2604 :exception EOFError: If the call attempts to seek beyond the end
2605 of the sequence.
2606 """
2608 # overridden by file handlers
2609 if frame != 0:
2610 msg = "no more images in file"
2611 raise EOFError(msg)
2613 def show(self, title: str | None = None) -> None:
2614 """
2615 Displays this image. This method is mainly intended for debugging purposes.
2617 This method calls :py:func:`PIL.ImageShow.show` internally. You can use
2618 :py:func:`PIL.ImageShow.register` to override its default behaviour.
2620 The image is first saved to a temporary file. By default, it will be in
2621 PNG format.
2623 On Unix, the image is then opened using the **xdg-open**, **display**,
2624 **gm**, **eog** or **xv** utility, depending on which one can be found.
2626 On macOS, the image is opened with the native Preview application.
2628 On Windows, the image is opened with the standard PNG display utility.
2630 :param title: Optional title to use for the image window, where possible.
2631 """
2633 from . import ImageShow
2635 ImageShow.show(self, title)
2637 def split(self) -> tuple[Image, ...]:
2638 """
2639 Split this image into individual bands. This method returns a
2640 tuple of individual image bands from an image. For example,
2641 splitting an "RGB" image creates three new images each
2642 containing a copy of one of the original bands (red, green,
2643 blue).
2645 If you need only one band, :py:meth:`~PIL.Image.Image.getchannel`
2646 method can be more convenient and faster.
2648 :returns: A tuple containing bands.
2649 """
2651 self.load()
2652 if self.im.bands == 1:
2653 return (self.copy(),)
2654 return tuple(map(self._new, self.im.split()))
2656 def getchannel(self, channel: int | str) -> Image:
2657 """
2658 Returns an image containing a single channel of the source image.
2660 :param channel: What channel to return. Could be index
2661 (0 for "R" channel of "RGB") or channel name
2662 ("A" for alpha channel of "RGBA").
2663 :returns: An image in "L" mode.
2665 .. versionadded:: 4.3.0
2666 """
2667 self.load()
2669 if isinstance(channel, str):
2670 try:
2671 channel = self.getbands().index(channel)
2672 except ValueError as e:
2673 msg = f'The image has no channel "{channel}"'
2674 raise ValueError(msg) from e
2676 return self._new(self.im.getband(channel))
2678 def tell(self) -> int:
2679 """
2680 Returns the current frame number. See :py:meth:`~PIL.Image.Image.seek`.
2682 If defined, :attr:`~PIL.Image.Image.n_frames` refers to the
2683 number of available frames.
2685 :returns: Frame number, starting with 0.
2686 """
2687 return 0
2689 def thumbnail(
2690 self,
2691 size: tuple[float, float],
2692 resample: Resampling = Resampling.BICUBIC,
2693 reducing_gap: float | None = 2.0,
2694 ) -> None:
2695 """
2696 Make this image into a thumbnail. This method modifies the
2697 image to contain a thumbnail version of itself, no larger than
2698 the given size. This method calculates an appropriate thumbnail
2699 size to preserve the aspect of the image, calls the
2700 :py:meth:`~PIL.Image.Image.draft` method to configure the file reader
2701 (where applicable), and finally resizes the image.
2703 Note that this function modifies the :py:class:`~PIL.Image.Image`
2704 object in place. If you need to use the full resolution image as well,
2705 apply this method to a :py:meth:`~PIL.Image.Image.copy` of the original
2706 image.
2708 :param size: The requested size in pixels, as a 2-tuple:
2709 (width, height).
2710 :param resample: Optional resampling filter. This can be one
2711 of :py:data:`Resampling.NEAREST`, :py:data:`Resampling.BOX`,
2712 :py:data:`Resampling.BILINEAR`, :py:data:`Resampling.HAMMING`,
2713 :py:data:`Resampling.BICUBIC` or :py:data:`Resampling.LANCZOS`.
2714 If omitted, it defaults to :py:data:`Resampling.BICUBIC`.
2715 (was :py:data:`Resampling.NEAREST` prior to version 2.5.0).
2716 See: :ref:`concept-filters`.
2717 :param reducing_gap: Apply optimization by resizing the image
2718 in two steps. First, reducing the image by integer times
2719 using :py:meth:`~PIL.Image.Image.reduce` or
2720 :py:meth:`~PIL.Image.Image.draft` for JPEG images.
2721 Second, resizing using regular resampling. The last step
2722 changes size no less than by ``reducing_gap`` times.
2723 ``reducing_gap`` may be None (no first step is performed)
2724 or should be greater than 1.0. The bigger ``reducing_gap``,
2725 the closer the result to the fair resampling.
2726 The smaller ``reducing_gap``, the faster resizing.
2727 With ``reducing_gap`` greater or equal to 3.0, the result is
2728 indistinguishable from fair resampling in most cases.
2729 The default value is 2.0 (very close to fair resampling
2730 while still being faster in many cases).
2731 :returns: None
2732 """
2734 provided_size = tuple(map(math.floor, size))
2736 def preserve_aspect_ratio() -> tuple[int, int] | None:
2737 def round_aspect(number: float, key: Callable[[int], float]) -> int:
2738 return max(min(math.floor(number), math.ceil(number), key=key), 1)
2740 x, y = provided_size
2741 if x >= self.width and y >= self.height:
2742 return None
2744 aspect = self.width / self.height
2745 if x / y >= aspect:
2746 x = round_aspect(y * aspect, key=lambda n: abs(aspect - n / y))
2747 else:
2748 y = round_aspect(
2749 x / aspect, key=lambda n: 0 if n == 0 else abs(aspect - x / n)
2750 )
2751 return x, y
2753 preserved_size = preserve_aspect_ratio()
2754 if preserved_size is None:
2755 return
2756 final_size = preserved_size
2758 box = None
2759 if reducing_gap is not None:
2760 res = self.draft(
2761 None, (int(size[0] * reducing_gap), int(size[1] * reducing_gap))
2762 )
2763 if res is not None:
2764 box = res[1]
2766 if self.size != final_size:
2767 im = self.resize(final_size, resample, box=box, reducing_gap=reducing_gap)
2769 self.im = im.im
2770 self._size = final_size
2771 self._mode = self.im.mode
2773 self.readonly = 0
2775 # FIXME: the different transform methods need further explanation
2776 # instead of bloating the method docs, add a separate chapter.
2777 def transform(
2778 self,
2779 size: tuple[int, int],
2780 method: Transform | ImageTransformHandler | SupportsGetData,
2781 data: Sequence[Any] | None = None,
2782 resample: int = Resampling.NEAREST,
2783 fill: int = 1,
2784 fillcolor: float | tuple[float, ...] | str | None = None,
2785 ) -> Image:
2786 """
2787 Transforms this image. This method creates a new image with the
2788 given size, and the same mode as the original, and copies data
2789 to the new image using the given transform.
2791 :param size: The output size in pixels, as a 2-tuple:
2792 (width, height).
2793 :param method: The transformation method. This is one of
2794 :py:data:`Transform.EXTENT` (cut out a rectangular subregion),
2795 :py:data:`Transform.AFFINE` (affine transform),
2796 :py:data:`Transform.PERSPECTIVE` (perspective transform),
2797 :py:data:`Transform.QUAD` (map a quadrilateral to a rectangle), or
2798 :py:data:`Transform.MESH` (map a number of source quadrilaterals
2799 in one operation).
2801 It may also be an :py:class:`~PIL.Image.ImageTransformHandler`
2802 object::
2804 class Example(Image.ImageTransformHandler):
2805 def transform(self, size, data, resample, fill=1):
2806 # Return result
2808 Implementations of :py:class:`~PIL.Image.ImageTransformHandler`
2809 for some of the :py:class:`Transform` methods are provided
2810 in :py:mod:`~PIL.ImageTransform`.
2812 It may also be an object with a ``method.getdata`` method
2813 that returns a tuple supplying new ``method`` and ``data`` values::
2815 class Example:
2816 def getdata(self):
2817 method = Image.Transform.EXTENT
2818 data = (0, 0, 100, 100)
2819 return method, data
2820 :param data: Extra data to the transformation method.
2821 :param resample: Optional resampling filter. It can be one of
2822 :py:data:`Resampling.NEAREST` (use nearest neighbour),
2823 :py:data:`Resampling.BILINEAR` (linear interpolation in a 2x2
2824 environment), or :py:data:`Resampling.BICUBIC` (cubic spline
2825 interpolation in a 4x4 environment). If omitted, or if the image
2826 has mode "1" or "P", it is set to :py:data:`Resampling.NEAREST`.
2827 See: :ref:`concept-filters`.
2828 :param fill: If ``method`` is an
2829 :py:class:`~PIL.Image.ImageTransformHandler` object, this is one of
2830 the arguments passed to it. Otherwise, it is unused.
2831 :param fillcolor: Optional fill color for the area outside the
2832 transform in the output image.
2833 :returns: An :py:class:`~PIL.Image.Image` object.
2834 """
2836 if self.mode in ("LA", "RGBA") and resample != Resampling.NEAREST:
2837 return (
2838 self.convert({"LA": "La", "RGBA": "RGBa"}[self.mode])
2839 .transform(size, method, data, resample, fill, fillcolor)
2840 .convert(self.mode)
2841 )
2843 if isinstance(method, ImageTransformHandler):
2844 return method.transform(size, self, resample=resample, fill=fill)
2846 if hasattr(method, "getdata"):
2847 # compatibility w. old-style transform objects
2848 method, data = method.getdata()
2850 if data is None:
2851 msg = "missing method data"
2852 raise ValueError(msg)
2854 im = new(self.mode, size, fillcolor)
2855 if self.mode == "P" and self.palette:
2856 im.palette = self.palette.copy()
2857 im.info = self.info.copy()
2858 if method == Transform.MESH:
2859 # list of quads
2860 for box, quad in data:
2861 im.__transformer(
2862 box, self, Transform.QUAD, quad, resample, fillcolor is None
2863 )
2864 else:
2865 im.__transformer(
2866 (0, 0) + size, self, method, data, resample, fillcolor is None
2867 )
2869 return im
2871 def __transformer(
2872 self,
2873 box: tuple[int, int, int, int],
2874 image: Image,
2875 method: Transform,
2876 data: Sequence[float],
2877 resample: int = Resampling.NEAREST,
2878 fill: bool = True,
2879 ) -> None:
2880 w = box[2] - box[0]
2881 h = box[3] - box[1]
2883 if method == Transform.AFFINE:
2884 data = data[:6]
2886 elif method == Transform.EXTENT:
2887 # convert extent to an affine transform
2888 x0, y0, x1, y1 = data
2889 xs = (x1 - x0) / w
2890 ys = (y1 - y0) / h
2891 method = Transform.AFFINE
2892 data = (xs, 0, x0, 0, ys, y0)
2894 elif method == Transform.PERSPECTIVE:
2895 data = data[:8]
2897 elif method == Transform.QUAD:
2898 # quadrilateral warp. data specifies the four corners
2899 # given as NW, SW, SE, and NE.
2900 nw = data[:2]
2901 sw = data[2:4]
2902 se = data[4:6]
2903 ne = data[6:8]
2904 x0, y0 = nw
2905 As = 1.0 / w
2906 At = 1.0 / h
2907 data = (
2908 x0,
2909 (ne[0] - x0) * As,
2910 (sw[0] - x0) * At,
2911 (se[0] - sw[0] - ne[0] + x0) * As * At,
2912 y0,
2913 (ne[1] - y0) * As,
2914 (sw[1] - y0) * At,
2915 (se[1] - sw[1] - ne[1] + y0) * As * At,
2916 )
2918 else:
2919 msg = "unknown transformation method"
2920 raise ValueError(msg)
2922 if resample not in (
2923 Resampling.NEAREST,
2924 Resampling.BILINEAR,
2925 Resampling.BICUBIC,
2926 ):
2927 if resample in (Resampling.BOX, Resampling.HAMMING, Resampling.LANCZOS):
2928 unusable: dict[int, str] = {
2929 Resampling.BOX: "Image.Resampling.BOX",
2930 Resampling.HAMMING: "Image.Resampling.HAMMING",
2931 Resampling.LANCZOS: "Image.Resampling.LANCZOS",
2932 }
2933 msg = unusable[resample] + f" ({resample}) cannot be used."
2934 else:
2935 msg = f"Unknown resampling filter ({resample})."
2937 filters = [
2938 f"{filter[1]} ({filter[0]})"
2939 for filter in (
2940 (Resampling.NEAREST, "Image.Resampling.NEAREST"),
2941 (Resampling.BILINEAR, "Image.Resampling.BILINEAR"),
2942 (Resampling.BICUBIC, "Image.Resampling.BICUBIC"),
2943 )
2944 ]
2945 msg += f" Use {', '.join(filters[:-1])} or {filters[-1]}"
2946 raise ValueError(msg)
2948 image.load()
2950 self.load()
2952 if image.mode in ("1", "P"):
2953 resample = Resampling.NEAREST
2955 self.im.transform(box, image.im, method, data, resample, fill)
2957 def transpose(self, method: Transpose) -> Image:
2958 """
2959 Transpose image (flip or rotate in 90 degree steps)
2961 :param method: One of :py:data:`Transpose.FLIP_LEFT_RIGHT`,
2962 :py:data:`Transpose.FLIP_TOP_BOTTOM`, :py:data:`Transpose.ROTATE_90`,
2963 :py:data:`Transpose.ROTATE_180`, :py:data:`Transpose.ROTATE_270`,
2964 :py:data:`Transpose.TRANSPOSE` or :py:data:`Transpose.TRANSVERSE`.
2965 :returns: Returns a flipped or rotated copy of this image.
2966 """
2968 self.load()
2969 return self._new(self.im.transpose(method))
2971 def effect_spread(self, distance: int) -> Image:
2972 """
2973 Randomly spread pixels in an image.
2975 :param distance: Distance to spread pixels.
2976 """
2977 self.load()
2978 return self._new(self.im.effect_spread(distance))
2980 def toqimage(self) -> ImageQt.ImageQt:
2981 """Returns a QImage copy of this image"""
2982 from . import ImageQt
2984 if not ImageQt.qt_is_installed:
2985 msg = "Qt bindings are not installed"
2986 raise ImportError(msg)
2987 return ImageQt.toqimage(self)
2989 def toqpixmap(self) -> ImageQt.QPixmap:
2990 """Returns a QPixmap copy of this image"""
2991 from . import ImageQt
2993 if not ImageQt.qt_is_installed:
2994 msg = "Qt bindings are not installed"
2995 raise ImportError(msg)
2996 return ImageQt.toqpixmap(self)
2999# --------------------------------------------------------------------
3000# Abstract handlers.
3003class ImagePointHandler(abc.ABC):
3004 """
3005 Used as a mixin by point transforms
3006 (for use with :py:meth:`~PIL.Image.Image.point`)
3007 """
3009 @abc.abstractmethod
3010 def point(self, im: Image) -> Image:
3011 pass
3014class ImageTransformHandler(abc.ABC):
3015 """
3016 Used as a mixin by geometry transforms
3017 (for use with :py:meth:`~PIL.Image.Image.transform`)
3018 """
3020 @abc.abstractmethod
3021 def transform(
3022 self,
3023 size: tuple[int, int],
3024 image: Image,
3025 **options: Any,
3026 ) -> Image:
3027 pass
3030# --------------------------------------------------------------------
3031# Factories
3034def _check_size(size: Any) -> None:
3035 """
3036 Common check to enforce type and sanity check on size tuples
3038 :param size: Should be a 2 tuple of (width, height)
3039 :returns: None, or raises a ValueError
3040 """
3042 if not isinstance(size, (list, tuple)):
3043 msg = "Size must be a list or tuple"
3044 raise ValueError(msg)
3045 if len(size) != 2:
3046 msg = "Size must be a sequence of length 2"
3047 raise ValueError(msg)
3048 if size[0] < 0 or size[1] < 0:
3049 msg = "Width and height must be >= 0"
3050 raise ValueError(msg)
3053def new(
3054 mode: str,
3055 size: tuple[int, int] | list[int],
3056 color: float | tuple[float, ...] | str | None = 0,
3057) -> Image:
3058 """
3059 Creates a new image with the given mode and size.
3061 :param mode: The mode to use for the new image. See:
3062 :ref:`concept-modes`.
3063 :param size: A 2-tuple, containing (width, height) in pixels.
3064 :param color: What color to use for the image. Default is black. If given,
3065 this should be a single integer or floating point value for single-band
3066 modes, and a tuple for multi-band modes (one value per band). When
3067 creating RGB or HSV images, you can also use color strings as supported
3068 by the ImageColor module. See :ref:`colors` for more information. If the
3069 color is None, the image is not initialised.
3070 :returns: An :py:class:`~PIL.Image.Image` object.
3071 """
3073 _check_size(size)
3075 if color is None:
3076 # don't initialize
3077 return Image()._new(core.new(mode, size))
3079 if isinstance(color, str):
3080 # css3-style specifier
3082 from . import ImageColor
3084 color = ImageColor.getcolor(color, mode)
3086 im = Image()
3087 if (
3088 mode == "P"
3089 and isinstance(color, (list, tuple))
3090 and all(isinstance(i, int) for i in color)
3091 ):
3092 color_ints: tuple[int, ...] = cast(tuple[int, ...], tuple(color))
3093 if len(color_ints) == 3 or len(color_ints) == 4:
3094 # RGB or RGBA value for a P image
3095 from . import ImagePalette
3097 im.palette = ImagePalette.ImagePalette()
3098 color = im.palette.getcolor(color_ints)
3099 return im._new(core.fill(mode, size, color))
3102def frombytes(
3103 mode: str,
3104 size: tuple[int, int],
3105 data: bytes | bytearray | SupportsArrayInterface,
3106 decoder_name: str = "raw",
3107 *args: Any,
3108) -> Image:
3109 """
3110 Creates a copy of an image memory from pixel data in a buffer.
3112 In its simplest form, this function takes three arguments
3113 (mode, size, and unpacked pixel data).
3115 You can also use any pixel decoder supported by PIL. For more
3116 information on available decoders, see the section
3117 :ref:`Writing Your Own File Codec <file-codecs>`.
3119 Note that this function decodes pixel data only, not entire images.
3120 If you have an entire image in a string, wrap it in a
3121 :py:class:`~io.BytesIO` object, and use :py:func:`~PIL.Image.open` to load
3122 it.
3124 :param mode: The image mode. See: :ref:`concept-modes`.
3125 :param size: The image size.
3126 :param data: A byte buffer containing raw data for the given mode.
3127 :param decoder_name: What decoder to use.
3128 :param args: Additional parameters for the given decoder.
3129 :returns: An :py:class:`~PIL.Image.Image` object.
3130 """
3132 _check_size(size)
3134 im = new(mode, size)
3135 if im.width != 0 and im.height != 0:
3136 decoder_args: Any = args
3137 if len(decoder_args) == 1 and isinstance(decoder_args[0], tuple):
3138 # may pass tuple instead of argument list
3139 decoder_args = decoder_args[0]
3141 if decoder_name == "raw" and decoder_args == ():
3142 decoder_args = mode
3144 im.frombytes(data, decoder_name, decoder_args)
3145 return im
3148def frombuffer(
3149 mode: str,
3150 size: tuple[int, int],
3151 data: bytes | SupportsArrayInterface,
3152 decoder_name: str = "raw",
3153 *args: Any,
3154) -> Image:
3155 """
3156 Creates an image memory referencing pixel data in a byte buffer.
3158 This function is similar to :py:func:`~PIL.Image.frombytes`, but uses data
3159 in the byte buffer, where possible. This means that changes to the
3160 original buffer object are reflected in this image). Not all modes can
3161 share memory; supported modes include "L", "RGBX", "RGBA", and "CMYK".
3163 Note that this function decodes pixel data only, not entire images.
3164 If you have an entire image file in a string, wrap it in a
3165 :py:class:`~io.BytesIO` object, and use :py:func:`~PIL.Image.open` to load it.
3167 The default parameters used for the "raw" decoder differs from that used for
3168 :py:func:`~PIL.Image.frombytes`. This is a bug, and will probably be fixed in a
3169 future release. The current release issues a warning if you do this; to disable
3170 the warning, you should provide the full set of parameters. See below for details.
3172 :param mode: The image mode. See: :ref:`concept-modes`.
3173 :param size: The image size.
3174 :param data: A bytes or other buffer object containing raw
3175 data for the given mode.
3176 :param decoder_name: What decoder to use.
3177 :param args: Additional parameters for the given decoder. For the
3178 default encoder ("raw"), it's recommended that you provide the
3179 full set of parameters::
3181 frombuffer(mode, size, data, "raw", mode, 0, 1)
3183 :returns: An :py:class:`~PIL.Image.Image` object.
3185 .. versionadded:: 1.1.4
3186 """
3188 _check_size(size)
3190 # may pass tuple instead of argument list
3191 if len(args) == 1 and isinstance(args[0], tuple):
3192 args = args[0]
3194 if decoder_name == "raw":
3195 if args == ():
3196 args = mode, 0, 1
3197 if args[0] in _MAPMODES:
3198 im = new(mode, (0, 0))
3199 im = im._new(core.map_buffer(data, size, decoder_name, 0, args))
3200 if mode == "P":
3201 from . import ImagePalette
3203 im.palette = ImagePalette.ImagePalette("RGB", im.im.getpalette("RGB"))
3204 im.readonly = 1
3205 return im
3207 return frombytes(mode, size, data, decoder_name, args)
3210class SupportsArrayInterface(Protocol):
3211 """
3212 An object that has an ``__array_interface__`` dictionary.
3213 """
3215 @property
3216 def __array_interface__(self) -> dict[str, Any]:
3217 raise NotImplementedError()
3220class SupportsArrowArrayInterface(Protocol):
3221 """
3222 An object that has an ``__arrow_c_array__`` method corresponding to the arrow c
3223 data interface.
3224 """
3226 def __arrow_c_array__(
3227 self, requested_schema: "PyCapsule" = None # type: ignore[name-defined] # noqa: F821, UP037
3228 ) -> tuple["PyCapsule", "PyCapsule"]: # type: ignore[name-defined] # noqa: F821, UP037
3229 raise NotImplementedError()
3232def fromarray(obj: SupportsArrayInterface, mode: str | None = None) -> Image:
3233 """
3234 Creates an image memory from an object exporting the array interface
3235 (using the buffer protocol)::
3237 from PIL import Image
3238 import numpy as np
3239 a = np.zeros((5, 5))
3240 im = Image.fromarray(a)
3242 If ``obj`` is not contiguous, then the ``tobytes`` method is called
3243 and :py:func:`~PIL.Image.frombuffer` is used.
3245 In the case of NumPy, be aware that Pillow modes do not always correspond
3246 to NumPy dtypes. Pillow modes only offer 1-bit pixels, 8-bit pixels,
3247 32-bit signed integer pixels, and 32-bit floating point pixels.
3249 Pillow images can also be converted to arrays::
3251 from PIL import Image
3252 import numpy as np
3253 im = Image.open("hopper.jpg")
3254 a = np.asarray(im)
3256 When converting Pillow images to arrays however, only pixel values are
3257 transferred. This means that P and PA mode images will lose their palette.
3259 :param obj: Object with array interface
3260 :param mode: Optional mode to use when reading ``obj``. Since pixel values do not
3261 contain information about palettes or color spaces, this can be used to place
3262 grayscale L mode data within a P mode image, or read RGB data as YCbCr for
3263 example.
3265 See: :ref:`concept-modes` for general information about modes.
3266 :returns: An image object.
3268 .. versionadded:: 1.1.6
3269 """
3270 arr = obj.__array_interface__
3271 shape = arr["shape"]
3272 ndim = len(shape)
3273 strides = arr.get("strides", None)
3274 try:
3275 typekey = (1, 1) + shape[2:], arr["typestr"]
3276 except KeyError as e:
3277 if mode is not None:
3278 typekey = None
3279 color_modes: list[str] = []
3280 else:
3281 msg = "Cannot handle this data type"
3282 raise TypeError(msg) from e
3283 if typekey is not None:
3284 try:
3285 typemode, rawmode, color_modes = _fromarray_typemap[typekey]
3286 except KeyError as e:
3287 typekey_shape, typestr = typekey
3288 msg = f"Cannot handle this data type: {typekey_shape}, {typestr}"
3289 raise TypeError(msg) from e
3290 if mode is not None:
3291 if mode != typemode and mode not in color_modes:
3292 deprecate("'mode' parameter for changing data types", 13)
3293 rawmode = mode
3294 else:
3295 mode = typemode
3296 if mode in ["1", "L", "I", "P", "F"]:
3297 ndmax = 2
3298 elif mode == "RGB":
3299 ndmax = 3
3300 else:
3301 ndmax = 4
3302 if ndim > ndmax:
3303 msg = f"Too many dimensions: {ndim} > {ndmax}."
3304 raise ValueError(msg)
3306 size = 1 if ndim == 1 else shape[1], shape[0]
3307 if strides is not None:
3308 if hasattr(obj, "tobytes"):
3309 obj = obj.tobytes()
3310 elif hasattr(obj, "tostring"):
3311 obj = obj.tostring()
3312 else:
3313 msg = "'strides' requires either tobytes() or tostring()"
3314 raise ValueError(msg)
3316 return frombuffer(mode, size, obj, "raw", rawmode, 0, 1)
3319def fromarrow(
3320 obj: SupportsArrowArrayInterface, mode: str, size: tuple[int, int]
3321) -> Image:
3322 """Creates an image with zero-copy shared memory from an object exporting
3323 the arrow_c_array interface protocol::
3325 from PIL import Image
3326 import pyarrow as pa
3327 arr = pa.array([0]*(5*5*4), type=pa.uint8())
3328 im = Image.fromarrow(arr, 'RGBA', (5, 5))
3330 If the data representation of the ``obj`` is not compatible with
3331 Pillow internal storage, a ValueError is raised.
3333 Pillow images can also be converted to Arrow objects::
3335 from PIL import Image
3336 import pyarrow as pa
3337 im = Image.open('hopper.jpg')
3338 arr = pa.array(im)
3340 As with array support, when converting Pillow images to arrays,
3341 only pixel values are transferred. This means that P and PA mode
3342 images will lose their palette.
3344 :param obj: Object with an arrow_c_array interface
3345 :param mode: Image mode.
3346 :param size: Image size. This must match the storage of the arrow object.
3347 :returns: An Image object
3349 Note that according to the Arrow spec, both the producer and the
3350 consumer should consider the exported array to be immutable, as
3351 unsynchronized updates will potentially cause inconsistent data.
3353 See: :ref:`arrow-support` for more detailed information
3355 .. versionadded:: 11.2.1
3357 """
3358 if not hasattr(obj, "__arrow_c_array__"):
3359 msg = "arrow_c_array interface not found"
3360 raise ValueError(msg)
3362 (schema_capsule, array_capsule) = obj.__arrow_c_array__()
3363 _im = core.new_arrow(mode, size, schema_capsule, array_capsule)
3364 if _im:
3365 return Image()._new(_im)
3367 msg = "new_arrow returned None without an exception"
3368 raise ValueError(msg)
3371def fromqimage(im: ImageQt.QImage) -> ImageFile.ImageFile:
3372 """Creates an image instance from a QImage image"""
3373 from . import ImageQt
3375 if not ImageQt.qt_is_installed:
3376 msg = "Qt bindings are not installed"
3377 raise ImportError(msg)
3378 return ImageQt.fromqimage(im)
3381def fromqpixmap(im: ImageQt.QPixmap) -> ImageFile.ImageFile:
3382 """Creates an image instance from a QPixmap image"""
3383 from . import ImageQt
3385 if not ImageQt.qt_is_installed:
3386 msg = "Qt bindings are not installed"
3387 raise ImportError(msg)
3388 return ImageQt.fromqpixmap(im)
3391_fromarray_typemap = {
3392 # (shape, typestr) => mode, rawmode, color modes
3393 # first two members of shape are set to one
3394 ((1, 1), "|b1"): ("1", "1;8", []),
3395 ((1, 1), "|u1"): ("L", "L", ["P"]),
3396 ((1, 1), "|i1"): ("I", "I;8", []),
3397 ((1, 1), "<u2"): ("I", "I;16", []),
3398 ((1, 1), ">u2"): ("I", "I;16B", []),
3399 ((1, 1), "<i2"): ("I", "I;16S", []),
3400 ((1, 1), ">i2"): ("I", "I;16BS", []),
3401 ((1, 1), "<u4"): ("I", "I;32", []),
3402 ((1, 1), ">u4"): ("I", "I;32B", []),
3403 ((1, 1), "<i4"): ("I", "I;32S", []),
3404 ((1, 1), ">i4"): ("I", "I;32BS", []),
3405 ((1, 1), "<f4"): ("F", "F;32F", []),
3406 ((1, 1), ">f4"): ("F", "F;32BF", []),
3407 ((1, 1), "<f8"): ("F", "F;64F", []),
3408 ((1, 1), ">f8"): ("F", "F;64BF", []),
3409 ((1, 1, 2), "|u1"): ("LA", "LA", ["La", "PA"]),
3410 ((1, 1, 3), "|u1"): ("RGB", "RGB", ["YCbCr", "LAB", "HSV"]),
3411 ((1, 1, 4), "|u1"): ("RGBA", "RGBA", ["RGBa", "RGBX", "CMYK"]),
3412 # shortcuts:
3413 ((1, 1), f"{_ENDIAN}i4"): ("I", "I", []),
3414 ((1, 1), f"{_ENDIAN}f4"): ("F", "F", []),
3415}
3418def _decompression_bomb_check(size: tuple[int, int]) -> None:
3419 if MAX_IMAGE_PIXELS is None:
3420 return
3422 pixels = max(1, size[0]) * max(1, size[1])
3424 if pixels > 2 * MAX_IMAGE_PIXELS:
3425 msg = (
3426 f"Image size ({pixels} pixels) exceeds limit of {2 * MAX_IMAGE_PIXELS} "
3427 "pixels, could be decompression bomb DOS attack."
3428 )
3429 raise DecompressionBombError(msg)
3431 if pixels > MAX_IMAGE_PIXELS:
3432 warnings.warn(
3433 f"Image size ({pixels} pixels) exceeds limit of {MAX_IMAGE_PIXELS} pixels, "
3434 "could be decompression bomb DOS attack.",
3435 DecompressionBombWarning,
3436 )
3439def open(
3440 fp: StrOrBytesPath | IO[bytes],
3441 mode: Literal["r"] = "r",
3442 formats: list[str] | tuple[str, ...] | None = None,
3443) -> ImageFile.ImageFile:
3444 """
3445 Opens and identifies the given image file.
3447 This is a lazy operation; this function identifies the file, but
3448 the file remains open and the actual image data is not read from
3449 the file until you try to process the data (or call the
3450 :py:meth:`~PIL.Image.Image.load` method). See
3451 :py:func:`~PIL.Image.new`. See :ref:`file-handling`.
3453 :param fp: A filename (string), os.PathLike object or a file object.
3454 The file object must implement ``file.read``,
3455 ``file.seek``, and ``file.tell`` methods,
3456 and be opened in binary mode. The file object will also seek to zero
3457 before reading.
3458 :param mode: The mode. If given, this argument must be "r".
3459 :param formats: A list or tuple of formats to attempt to load the file in.
3460 This can be used to restrict the set of formats checked.
3461 Pass ``None`` to try all supported formats. You can print the set of
3462 available formats by running ``python3 -m PIL`` or using
3463 the :py:func:`PIL.features.pilinfo` function.
3464 :returns: An :py:class:`~PIL.Image.Image` object.
3465 :exception FileNotFoundError: If the file cannot be found.
3466 :exception PIL.UnidentifiedImageError: If the image cannot be opened and
3467 identified.
3468 :exception ValueError: If the ``mode`` is not "r", or if a ``StringIO``
3469 instance is used for ``fp``.
3470 :exception TypeError: If ``formats`` is not ``None``, a list or a tuple.
3471 """
3473 if mode != "r":
3474 msg = f"bad mode {repr(mode)}" # type: ignore[unreachable]
3475 raise ValueError(msg)
3476 elif isinstance(fp, io.StringIO):
3477 msg = ( # type: ignore[unreachable]
3478 "StringIO cannot be used to open an image. "
3479 "Binary data must be used instead."
3480 )
3481 raise ValueError(msg)
3483 if formats is None:
3484 formats = ID
3485 elif not isinstance(formats, (list, tuple)):
3486 msg = "formats must be a list or tuple" # type: ignore[unreachable]
3487 raise TypeError(msg)
3489 exclusive_fp = False
3490 filename: str | bytes = ""
3491 if is_path(fp):
3492 filename = os.fspath(fp)
3493 fp = builtins.open(filename, "rb")
3494 exclusive_fp = True
3495 else:
3496 fp = cast(IO[bytes], fp)
3498 try:
3499 fp.seek(0)
3500 except (AttributeError, io.UnsupportedOperation):
3501 fp = io.BytesIO(fp.read())
3502 exclusive_fp = True
3504 prefix = fp.read(16)
3506 preinit()
3508 warning_messages: list[str] = []
3510 def _open_core(
3511 fp: IO[bytes],
3512 filename: str | bytes,
3513 prefix: bytes,
3514 formats: list[str] | tuple[str, ...],
3515 ) -> ImageFile.ImageFile | None:
3516 for i in formats:
3517 i = i.upper()
3518 if i not in OPEN:
3519 init()
3520 try:
3521 factory, accept = OPEN[i]
3522 result = not accept or accept(prefix)
3523 if isinstance(result, str):
3524 warning_messages.append(result)
3525 elif result:
3526 fp.seek(0)
3527 im = factory(fp, filename)
3528 _decompression_bomb_check(im.size)
3529 return im
3530 except (SyntaxError, IndexError, TypeError, struct.error) as e:
3531 if WARN_POSSIBLE_FORMATS:
3532 warning_messages.append(i + " opening failed. " + str(e))
3533 except BaseException:
3534 if exclusive_fp:
3535 fp.close()
3536 raise
3537 return None
3539 im = _open_core(fp, filename, prefix, formats)
3541 if im is None and formats is ID:
3542 checked_formats = ID.copy()
3543 if init():
3544 im = _open_core(
3545 fp,
3546 filename,
3547 prefix,
3548 tuple(format for format in formats if format not in checked_formats),
3549 )
3551 if im:
3552 im._exclusive_fp = exclusive_fp
3553 return im
3555 if exclusive_fp:
3556 fp.close()
3557 for message in warning_messages:
3558 warnings.warn(message)
3559 msg = "cannot identify image file %r" % (filename if filename else fp)
3560 raise UnidentifiedImageError(msg)
3563#
3564# Image processing.
3567def alpha_composite(im1: Image, im2: Image) -> Image:
3568 """
3569 Alpha composite im2 over im1.
3571 :param im1: The first image. Must have mode RGBA or LA.
3572 :param im2: The second image. Must have the same mode and size as the first image.
3573 :returns: An :py:class:`~PIL.Image.Image` object.
3574 """
3576 im1.load()
3577 im2.load()
3578 return im1._new(core.alpha_composite(im1.im, im2.im))
3581def blend(im1: Image, im2: Image, alpha: float) -> Image:
3582 """
3583 Creates a new image by interpolating between two input images, using
3584 a constant alpha::
3586 out = image1 * (1.0 - alpha) + image2 * alpha
3588 :param im1: The first image.
3589 :param im2: The second image. Must have the same mode and size as
3590 the first image.
3591 :param alpha: The interpolation alpha factor. If alpha is 0.0, a
3592 copy of the first image is returned. If alpha is 1.0, a copy of
3593 the second image is returned. There are no restrictions on the
3594 alpha value. If necessary, the result is clipped to fit into
3595 the allowed output range.
3596 :returns: An :py:class:`~PIL.Image.Image` object.
3597 """
3599 im1.load()
3600 im2.load()
3601 return im1._new(core.blend(im1.im, im2.im, alpha))
3604def composite(image1: Image, image2: Image, mask: Image) -> Image:
3605 """
3606 Create composite image by blending images using a transparency mask.
3608 :param image1: The first image.
3609 :param image2: The second image. Must have the same mode and
3610 size as the first image.
3611 :param mask: A mask image. This image can have mode
3612 "1", "L", or "RGBA", and must have the same size as the
3613 other two images.
3614 """
3616 image = image2.copy()
3617 image.paste(image1, None, mask)
3618 return image
3621def eval(image: Image, *args: Callable[[int], float]) -> Image:
3622 """
3623 Applies the function (which should take one argument) to each pixel
3624 in the given image. If the image has more than one band, the same
3625 function is applied to each band. Note that the function is
3626 evaluated once for each possible pixel value, so you cannot use
3627 random components or other generators.
3629 :param image: The input image.
3630 :param function: A function object, taking one integer argument.
3631 :returns: An :py:class:`~PIL.Image.Image` object.
3632 """
3634 return image.point(args[0])
3637def merge(mode: str, bands: Sequence[Image]) -> Image:
3638 """
3639 Merge a set of single band images into a new multiband image.
3641 :param mode: The mode to use for the output image. See:
3642 :ref:`concept-modes`.
3643 :param bands: A sequence containing one single-band image for
3644 each band in the output image. All bands must have the
3645 same size.
3646 :returns: An :py:class:`~PIL.Image.Image` object.
3647 """
3649 if getmodebands(mode) != len(bands) or "*" in mode:
3650 msg = "wrong number of bands"
3651 raise ValueError(msg)
3652 for band in bands[1:]:
3653 if band.mode != getmodetype(mode):
3654 msg = "mode mismatch"
3655 raise ValueError(msg)
3656 if band.size != bands[0].size:
3657 msg = "size mismatch"
3658 raise ValueError(msg)
3659 for band in bands:
3660 band.load()
3661 return bands[0]._new(core.merge(mode, *[b.im for b in bands]))
3664# --------------------------------------------------------------------
3665# Plugin registry
3668def register_open(
3669 id: str,
3670 factory: (
3671 Callable[[IO[bytes], str | bytes], ImageFile.ImageFile]
3672 | type[ImageFile.ImageFile]
3673 ),
3674 accept: Callable[[bytes], bool | str] | None = None,
3675) -> None:
3676 """
3677 Register an image file plugin. This function should not be used
3678 in application code.
3680 :param id: An image format identifier.
3681 :param factory: An image file factory method.
3682 :param accept: An optional function that can be used to quickly
3683 reject images having another format.
3684 """
3685 id = id.upper()
3686 if id not in ID:
3687 ID.append(id)
3688 OPEN[id] = factory, accept
3691def register_mime(id: str, mimetype: str) -> None:
3692 """
3693 Registers an image MIME type by populating ``Image.MIME``. This function
3694 should not be used in application code.
3696 ``Image.MIME`` provides a mapping from image format identifiers to mime
3697 formats, but :py:meth:`~PIL.ImageFile.ImageFile.get_format_mimetype` can
3698 provide a different result for specific images.
3700 :param id: An image format identifier.
3701 :param mimetype: The image MIME type for this format.
3702 """
3703 MIME[id.upper()] = mimetype
3706def register_save(
3707 id: str, driver: Callable[[Image, IO[bytes], str | bytes], None]
3708) -> None:
3709 """
3710 Registers an image save function. This function should not be
3711 used in application code.
3713 :param id: An image format identifier.
3714 :param driver: A function to save images in this format.
3715 """
3716 SAVE[id.upper()] = driver
3719def register_save_all(
3720 id: str, driver: Callable[[Image, IO[bytes], str | bytes], None]
3721) -> None:
3722 """
3723 Registers an image function to save all the frames
3724 of a multiframe format. This function should not be
3725 used in application code.
3727 :param id: An image format identifier.
3728 :param driver: A function to save images in this format.
3729 """
3730 SAVE_ALL[id.upper()] = driver
3733def register_extension(id: str, extension: str) -> None:
3734 """
3735 Registers an image extension. This function should not be
3736 used in application code.
3738 :param id: An image format identifier.
3739 :param extension: An extension used for this format.
3740 """
3741 EXTENSION[extension.lower()] = id.upper()
3744def register_extensions(id: str, extensions: list[str]) -> None:
3745 """
3746 Registers image extensions. This function should not be
3747 used in application code.
3749 :param id: An image format identifier.
3750 :param extensions: A list of extensions used for this format.
3751 """
3752 for extension in extensions:
3753 register_extension(id, extension)
3756def registered_extensions() -> dict[str, str]:
3757 """
3758 Returns a dictionary containing all file extensions belonging
3759 to registered plugins
3760 """
3761 init()
3762 return EXTENSION
3765def register_decoder(name: str, decoder: type[ImageFile.PyDecoder]) -> None:
3766 """
3767 Registers an image decoder. This function should not be
3768 used in application code.
3770 :param name: The name of the decoder
3771 :param decoder: An ImageFile.PyDecoder object
3773 .. versionadded:: 4.1.0
3774 """
3775 DECODERS[name] = decoder
3778def register_encoder(name: str, encoder: type[ImageFile.PyEncoder]) -> None:
3779 """
3780 Registers an image encoder. This function should not be
3781 used in application code.
3783 :param name: The name of the encoder
3784 :param encoder: An ImageFile.PyEncoder object
3786 .. versionadded:: 4.1.0
3787 """
3788 ENCODERS[name] = encoder
3791# --------------------------------------------------------------------
3792# Simple display support.
3795def _show(image: Image, **options: Any) -> None:
3796 from . import ImageShow
3798 deprecate("Image._show", 13, "ImageShow.show")
3799 ImageShow.show(image, **options)
3802# --------------------------------------------------------------------
3803# Effects
3806def effect_mandelbrot(
3807 size: tuple[int, int], extent: tuple[float, float, float, float], quality: int
3808) -> Image:
3809 """
3810 Generate a Mandelbrot set covering the given extent.
3812 :param size: The requested size in pixels, as a 2-tuple:
3813 (width, height).
3814 :param extent: The extent to cover, as a 4-tuple:
3815 (x0, y0, x1, y1).
3816 :param quality: Quality.
3817 """
3818 return Image()._new(core.effect_mandelbrot(size, extent, quality))
3821def effect_noise(size: tuple[int, int], sigma: float) -> Image:
3822 """
3823 Generate Gaussian noise centered around 128.
3825 :param size: The requested size in pixels, as a 2-tuple:
3826 (width, height).
3827 :param sigma: Standard deviation of noise.
3828 """
3829 return Image()._new(core.effect_noise(size, sigma))
3832def linear_gradient(mode: str) -> Image:
3833 """
3834 Generate 256x256 linear gradient from black to white, top to bottom.
3836 :param mode: Input mode.
3837 """
3838 return Image()._new(core.linear_gradient(mode))
3841def radial_gradient(mode: str) -> Image:
3842 """
3843 Generate 256x256 radial gradient from black to white, centre to edge.
3845 :param mode: Input mode.
3846 """
3847 return Image()._new(core.radial_gradient(mode))
3850# --------------------------------------------------------------------
3851# Resources
3854def _apply_env_variables(env: dict[str, str] | None = None) -> None:
3855 env_dict = env if env is not None else os.environ
3857 for var_name, setter in [
3858 ("PILLOW_ALIGNMENT", core.set_alignment),
3859 ("PILLOW_BLOCK_SIZE", core.set_block_size),
3860 ("PILLOW_BLOCKS_MAX", core.set_blocks_max),
3861 ]:
3862 if var_name not in env_dict:
3863 continue
3865 var = env_dict[var_name].lower()
3867 units = 1
3868 for postfix, mul in [("k", 1024), ("m", 1024 * 1024)]:
3869 if var.endswith(postfix):
3870 units = mul
3871 var = var[: -len(postfix)]
3873 try:
3874 var_int = int(var) * units
3875 except ValueError:
3876 warnings.warn(f"{var_name} is not int")
3877 continue
3879 try:
3880 setter(var_int)
3881 except ValueError as e:
3882 warnings.warn(f"{var_name}: {e}")
3885_apply_env_variables()
3886atexit.register(core.clear_cache)
3889if TYPE_CHECKING:
3890 _ExifBase = MutableMapping[int, Any]
3891else:
3892 _ExifBase = MutableMapping
3895class Exif(_ExifBase):
3896 """
3897 This class provides read and write access to EXIF image data::
3899 from PIL import Image
3900 im = Image.open("exif.png")
3901 exif = im.getexif() # Returns an instance of this class
3903 Information can be read and written, iterated over or deleted::
3905 print(exif[274]) # 1
3906 exif[274] = 2
3907 for k, v in exif.items():
3908 print("Tag", k, "Value", v) # Tag 274 Value 2
3909 del exif[274]
3911 To access information beyond IFD0, :py:meth:`~PIL.Image.Exif.get_ifd`
3912 returns a dictionary::
3914 from PIL import ExifTags
3915 im = Image.open("exif_gps.jpg")
3916 exif = im.getexif()
3917 gps_ifd = exif.get_ifd(ExifTags.IFD.GPSInfo)
3918 print(gps_ifd)
3920 Other IFDs include ``ExifTags.IFD.Exif``, ``ExifTags.IFD.MakerNote``,
3921 ``ExifTags.IFD.Interop`` and ``ExifTags.IFD.IFD1``.
3923 :py:mod:`~PIL.ExifTags` also has enum classes to provide names for data::
3925 print(exif[ExifTags.Base.Software]) # PIL
3926 print(gps_ifd[ExifTags.GPS.GPSDateStamp]) # 1999:99:99 99:99:99
3927 """
3929 endian: str | None = None
3930 bigtiff = False
3931 _loaded = False
3933 def __init__(self) -> None:
3934 self._data: dict[int, Any] = {}
3935 self._hidden_data: dict[int, Any] = {}
3936 self._ifds: dict[int, dict[int, Any]] = {}
3937 self._info: TiffImagePlugin.ImageFileDirectory_v2 | None = None
3938 self._loaded_exif: bytes | None = None
3940 def _fixup(self, value: Any) -> Any:
3941 try:
3942 if len(value) == 1 and isinstance(value, tuple):
3943 return value[0]
3944 except Exception:
3945 pass
3946 return value
3948 def _fixup_dict(self, src_dict: dict[int, Any]) -> dict[int, Any]:
3949 # Helper function
3950 # returns a dict with any single item tuples/lists as individual values
3951 return {k: self._fixup(v) for k, v in src_dict.items()}
3953 def _get_ifd_dict(
3954 self, offset: int, group: int | None = None
3955 ) -> dict[int, Any] | None:
3956 try:
3957 # an offset pointer to the location of the nested embedded IFD.
3958 # It should be a long, but may be corrupted.
3959 self.fp.seek(offset)
3960 except (KeyError, TypeError):
3961 return None
3962 else:
3963 from . import TiffImagePlugin
3965 info = TiffImagePlugin.ImageFileDirectory_v2(self.head, group=group)
3966 info.load(self.fp)
3967 return self._fixup_dict(dict(info))
3969 def _get_head(self) -> bytes:
3970 version = b"\x2b" if self.bigtiff else b"\x2a"
3971 if self.endian == "<":
3972 head = b"II" + version + b"\x00" + o32le(8)
3973 else:
3974 head = b"MM\x00" + version + o32be(8)
3975 if self.bigtiff:
3976 head += o32le(8) if self.endian == "<" else o32be(8)
3977 head += b"\x00\x00\x00\x00"
3978 return head
3980 def load(self, data: bytes) -> None:
3981 # Extract EXIF information. This is highly experimental,
3982 # and is likely to be replaced with something better in a future
3983 # version.
3985 # The EXIF record consists of a TIFF file embedded in a JPEG
3986 # application marker (!).
3987 if data == self._loaded_exif:
3988 return
3989 self._loaded_exif = data
3990 self._data.clear()
3991 self._hidden_data.clear()
3992 self._ifds.clear()
3993 while data and data.startswith(b"Exif\x00\x00"):
3994 data = data[6:]
3995 if not data:
3996 self._info = None
3997 return
3999 self.fp: IO[bytes] = io.BytesIO(data)
4000 self.head = self.fp.read(8)
4001 # process dictionary
4002 from . import TiffImagePlugin
4004 self._info = TiffImagePlugin.ImageFileDirectory_v2(self.head)
4005 self.endian = self._info._endian
4006 self.fp.seek(self._info.next)
4007 self._info.load(self.fp)
4009 def load_from_fp(self, fp: IO[bytes], offset: int | None = None) -> None:
4010 self._loaded_exif = None
4011 self._data.clear()
4012 self._hidden_data.clear()
4013 self._ifds.clear()
4015 # process dictionary
4016 from . import TiffImagePlugin
4018 self.fp = fp
4019 if offset is not None:
4020 self.head = self._get_head()
4021 else:
4022 self.head = self.fp.read(8)
4023 self._info = TiffImagePlugin.ImageFileDirectory_v2(self.head)
4024 if self.endian is None:
4025 self.endian = self._info._endian
4026 if offset is None:
4027 offset = self._info.next
4028 self.fp.tell()
4029 self.fp.seek(offset)
4030 self._info.load(self.fp)
4032 def _get_merged_dict(self) -> dict[int, Any]:
4033 merged_dict = dict(self)
4035 # get EXIF extension
4036 if ExifTags.IFD.Exif in self:
4037 ifd = self._get_ifd_dict(self[ExifTags.IFD.Exif], ExifTags.IFD.Exif)
4038 if ifd:
4039 merged_dict.update(ifd)
4041 # GPS
4042 if ExifTags.IFD.GPSInfo in self:
4043 merged_dict[ExifTags.IFD.GPSInfo] = self._get_ifd_dict(
4044 self[ExifTags.IFD.GPSInfo], ExifTags.IFD.GPSInfo
4045 )
4047 return merged_dict
4049 def tobytes(self, offset: int = 8) -> bytes:
4050 from . import TiffImagePlugin
4052 head = self._get_head()
4053 ifd = TiffImagePlugin.ImageFileDirectory_v2(ifh=head)
4054 for tag, ifd_dict in self._ifds.items():
4055 if tag not in self:
4056 ifd[tag] = ifd_dict
4057 for tag, value in self.items():
4058 if tag in [
4059 ExifTags.IFD.Exif,
4060 ExifTags.IFD.GPSInfo,
4061 ] and not isinstance(value, dict):
4062 value = self.get_ifd(tag)
4063 if (
4064 tag == ExifTags.IFD.Exif
4065 and ExifTags.IFD.Interop in value
4066 and not isinstance(value[ExifTags.IFD.Interop], dict)
4067 ):
4068 value = value.copy()
4069 value[ExifTags.IFD.Interop] = self.get_ifd(ExifTags.IFD.Interop)
4070 ifd[tag] = value
4071 return b"Exif\x00\x00" + head + ifd.tobytes(offset)
4073 def get_ifd(self, tag: int) -> dict[int, Any]:
4074 if tag not in self._ifds:
4075 if tag == ExifTags.IFD.IFD1:
4076 if self._info is not None and self._info.next != 0:
4077 ifd = self._get_ifd_dict(self._info.next)
4078 if ifd is not None:
4079 self._ifds[tag] = ifd
4080 elif tag in [ExifTags.IFD.Exif, ExifTags.IFD.GPSInfo]:
4081 offset = self._hidden_data.get(tag, self.get(tag))
4082 if offset is not None:
4083 ifd = self._get_ifd_dict(offset, tag)
4084 if ifd is not None:
4085 self._ifds[tag] = ifd
4086 elif tag in [ExifTags.IFD.Interop, ExifTags.IFD.MakerNote]:
4087 if ExifTags.IFD.Exif not in self._ifds:
4088 self.get_ifd(ExifTags.IFD.Exif)
4089 tag_data = self._ifds[ExifTags.IFD.Exif][tag]
4090 if tag == ExifTags.IFD.MakerNote:
4091 from .TiffImagePlugin import ImageFileDirectory_v2
4093 if tag_data.startswith(b"FUJIFILM"):
4094 ifd_offset = i32le(tag_data, 8)
4095 ifd_data = tag_data[ifd_offset:]
4097 makernote = {}
4098 for i in range(struct.unpack("<H", ifd_data[:2])[0]):
4099 ifd_tag, typ, count, data = struct.unpack(
4100 "<HHL4s", ifd_data[i * 12 + 2 : (i + 1) * 12 + 2]
4101 )
4102 try:
4103 (
4104 unit_size,
4105 handler,
4106 ) = ImageFileDirectory_v2._load_dispatch[typ]
4107 except KeyError:
4108 continue
4109 size = count * unit_size
4110 if size > 4:
4111 (offset,) = struct.unpack("<L", data)
4112 data = ifd_data[offset - 12 : offset + size - 12]
4113 else:
4114 data = data[:size]
4116 if len(data) != size:
4117 warnings.warn(
4118 "Possibly corrupt EXIF MakerNote data. "
4119 f"Expecting to read {size} bytes but only got "
4120 f"{len(data)}. Skipping tag {ifd_tag}"
4121 )
4122 continue
4124 if not data:
4125 continue
4127 makernote[ifd_tag] = handler(
4128 ImageFileDirectory_v2(), data, False
4129 )
4130 self._ifds[tag] = dict(self._fixup_dict(makernote))
4131 elif self.get(0x010F) == "Nintendo":
4132 makernote = {}
4133 for i in range(struct.unpack(">H", tag_data[:2])[0]):
4134 ifd_tag, typ, count, data = struct.unpack(
4135 ">HHL4s", tag_data[i * 12 + 2 : (i + 1) * 12 + 2]
4136 )
4137 if ifd_tag == 0x1101:
4138 # CameraInfo
4139 (offset,) = struct.unpack(">L", data)
4140 self.fp.seek(offset)
4142 camerainfo: dict[str, int | bytes] = {
4143 "ModelID": self.fp.read(4)
4144 }
4146 self.fp.read(4)
4147 # Seconds since 2000
4148 camerainfo["TimeStamp"] = i32le(self.fp.read(12))
4150 self.fp.read(4)
4151 camerainfo["InternalSerialNumber"] = self.fp.read(4)
4153 self.fp.read(12)
4154 parallax = self.fp.read(4)
4155 handler = ImageFileDirectory_v2._load_dispatch[
4156 TiffTags.FLOAT
4157 ][1]
4158 camerainfo["Parallax"] = handler(
4159 ImageFileDirectory_v2(), parallax, False
4160 )[0]
4162 self.fp.read(4)
4163 camerainfo["Category"] = self.fp.read(2)
4165 makernote = {0x1101: camerainfo}
4166 self._ifds[tag] = makernote
4167 else:
4168 # Interop
4169 ifd = self._get_ifd_dict(tag_data, tag)
4170 if ifd is not None:
4171 self._ifds[tag] = ifd
4172 ifd = self._ifds.setdefault(tag, {})
4173 if tag == ExifTags.IFD.Exif and self._hidden_data:
4174 ifd = {
4175 k: v
4176 for (k, v) in ifd.items()
4177 if k not in (ExifTags.IFD.Interop, ExifTags.IFD.MakerNote)
4178 }
4179 return ifd
4181 def hide_offsets(self) -> None:
4182 for tag in (ExifTags.IFD.Exif, ExifTags.IFD.GPSInfo):
4183 if tag in self:
4184 self._hidden_data[tag] = self[tag]
4185 del self[tag]
4187 def __str__(self) -> str:
4188 if self._info is not None:
4189 # Load all keys into self._data
4190 for tag in self._info:
4191 self[tag]
4193 return str(self._data)
4195 def __len__(self) -> int:
4196 keys = set(self._data)
4197 if self._info is not None:
4198 keys.update(self._info)
4199 return len(keys)
4201 def __getitem__(self, tag: int) -> Any:
4202 if self._info is not None and tag not in self._data and tag in self._info:
4203 self._data[tag] = self._fixup(self._info[tag])
4204 del self._info[tag]
4205 return self._data[tag]
4207 def __contains__(self, tag: object) -> bool:
4208 return tag in self._data or (self._info is not None and tag in self._info)
4210 def __setitem__(self, tag: int, value: Any) -> None:
4211 if self._info is not None and tag in self._info:
4212 del self._info[tag]
4213 self._data[tag] = value
4215 def __delitem__(self, tag: int) -> None:
4216 if self._info is not None and tag in self._info:
4217 del self._info[tag]
4218 else:
4219 del self._data[tag]
4220 if tag in self._ifds:
4221 del self._ifds[tag]
4223 def __iter__(self) -> Iterator[int]:
4224 keys = set(self._data)
4225 if self._info is not None:
4226 keys.update(self._info)
4227 return iter(keys)