Coverage for /usr/lib/python3/dist-packages/PIL/Image.py: 16%

1683 statements  

« prev     ^ index     » next       coverage.py v7.4.4, created at 2025-06-14 15:25 +0200

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# 

26 

27from __future__ import annotations 

28 

29import atexit 

30import builtins 

31import io 

32import logging 

33import math 

34import os 

35import re 

36import struct 

37import sys 

38import tempfile 

39import warnings 

40from collections.abc import Callable, MutableMapping 

41from enum import IntEnum 

42from pathlib import Path 

43 

44try: 

45 from defusedxml import ElementTree 

46except ImportError: 

47 ElementTree = None 

48 

49# VERSION was removed in Pillow 6.0.0. 

50# PILLOW_VERSION was removed in Pillow 9.0.0. 

51# Use __version__ instead. 

52from . import ( 

53 ExifTags, 

54 ImageMode, 

55 TiffTags, 

56 UnidentifiedImageError, 

57 __version__, 

58 _plugins, 

59) 

60from ._binary import i32le, o32be, o32le 

61from ._util import DeferredError, is_path 

62 

63logger = logging.getLogger(__name__) 

64 

65 

66class DecompressionBombWarning(RuntimeWarning): 

67 pass 

68 

69 

70class DecompressionBombError(Exception): 

71 pass 

72 

73 

74# Limit to around a quarter gigabyte for a 24-bit (3 bpp) image 

75MAX_IMAGE_PIXELS = int(1024 * 1024 * 1024 // 4 // 3) 

76 

77 

78try: 

79 # If the _imaging C module is not present, Pillow will not load. 

80 # Note that other modules should not refer to _imaging directly; 

81 # import Image and use the Image.core variable instead. 

82 # Also note that Image.core is not a publicly documented interface, 

83 # and should be considered private and subject to change. 

84 from . import _imaging as core 

85 

86 if __version__ != getattr(core, "PILLOW_VERSION", None): 

87 msg = ( 

88 "The _imaging extension was built for another version of Pillow or PIL:\n" 

89 f"Core version: {getattr(core, 'PILLOW_VERSION', None)}\n" 

90 f"Pillow version: {__version__}" 

91 ) 

92 raise ImportError(msg) 

93 

94except ImportError as v: 

95 core = DeferredError.new(ImportError("The _imaging C module is not installed.")) 

96 # Explanations for ways that we know we might have an import error 

97 if str(v).startswith("Module use of python"): 

98 # The _imaging C module is present, but not compiled for 

99 # the right version (windows only). Print a warning, if 

100 # possible. 

101 warnings.warn( 

102 "The _imaging extension was built for another version of Python.", 

103 RuntimeWarning, 

104 ) 

105 elif str(v).startswith("The _imaging extension"): 

106 warnings.warn(str(v), RuntimeWarning) 

107 # Fail here anyway. Don't let people run with a mostly broken Pillow. 

108 # see docs/porting.rst 

109 raise 

110 

111 

112USE_CFFI_ACCESS = False 

113try: 

114 import cffi 

115except ImportError: 

116 cffi = None 

117 

118 

119def isImageType(t): 

120 """ 

121 Checks if an object is an image object. 

122 

123 .. warning:: 

124 

125 This function is for internal use only. 

126 

127 :param t: object to check if it's an image 

128 :returns: True if the object is an image 

129 """ 

130 return hasattr(t, "im") 

131 

132 

133# 

134# Constants 

135 

136 

137# transpose 

138class Transpose(IntEnum): 

139 FLIP_LEFT_RIGHT = 0 

140 FLIP_TOP_BOTTOM = 1 

141 ROTATE_90 = 2 

142 ROTATE_180 = 3 

143 ROTATE_270 = 4 

144 TRANSPOSE = 5 

145 TRANSVERSE = 6 

146 

147 

148# transforms (also defined in Imaging.h) 

149class Transform(IntEnum): 

150 AFFINE = 0 

151 EXTENT = 1 

152 PERSPECTIVE = 2 

153 QUAD = 3 

154 MESH = 4 

155 

156 

157# resampling filters (also defined in Imaging.h) 

158class Resampling(IntEnum): 

159 NEAREST = 0 

160 BOX = 4 

161 BILINEAR = 2 

162 HAMMING = 5 

163 BICUBIC = 3 

164 LANCZOS = 1 

165 

166 

167_filters_support = { 

168 Resampling.BOX: 0.5, 

169 Resampling.BILINEAR: 1.0, 

170 Resampling.HAMMING: 1.0, 

171 Resampling.BICUBIC: 2.0, 

172 Resampling.LANCZOS: 3.0, 

173} 

174 

175 

176# dithers 

177class Dither(IntEnum): 

178 NONE = 0 

179 ORDERED = 1 # Not yet implemented 

180 RASTERIZE = 2 # Not yet implemented 

181 FLOYDSTEINBERG = 3 # default 

182 

183 

184# palettes/quantizers 

185class Palette(IntEnum): 

186 WEB = 0 

187 ADAPTIVE = 1 

188 

189 

190class Quantize(IntEnum): 

191 MEDIANCUT = 0 

192 MAXCOVERAGE = 1 

193 FASTOCTREE = 2 

194 LIBIMAGEQUANT = 3 

195 

196 

197module = sys.modules[__name__] 

198for enum in (Transpose, Transform, Resampling, Dither, Palette, Quantize): 

199 for item in enum: 

200 setattr(module, item.name, item.value) 

201 

202 

203if hasattr(core, "DEFAULT_STRATEGY"): 

204 DEFAULT_STRATEGY = core.DEFAULT_STRATEGY 

205 FILTERED = core.FILTERED 

206 HUFFMAN_ONLY = core.HUFFMAN_ONLY 

207 RLE = core.RLE 

208 FIXED = core.FIXED 

209 

210 

211# -------------------------------------------------------------------- 

212# Registries 

213 

214ID = [] 

215OPEN = {} 

216MIME = {} 

217SAVE = {} 

218SAVE_ALL = {} 

219EXTENSION = {} 

220DECODERS = {} 

221ENCODERS = {} 

222 

223# -------------------------------------------------------------------- 

224# Modes 

225 

226_ENDIAN = "<" if sys.byteorder == "little" else ">" 

227 

228 

229def _conv_type_shape(im): 

230 m = ImageMode.getmode(im.mode) 

231 shape = (im.height, im.width) 

232 extra = len(m.bands) 

233 if extra != 1: 

234 shape += (extra,) 

235 return shape, m.typestr 

236 

237 

238MODES = ["1", "CMYK", "F", "HSV", "I", "L", "LAB", "P", "RGB", "RGBA", "RGBX", "YCbCr"] 

239 

240# raw modes that may be memory mapped. NOTE: if you change this, you 

241# may have to modify the stride calculation in map.c too! 

242_MAPMODES = ("L", "P", "RGBX", "RGBA", "CMYK", "I;16", "I;16L", "I;16B") 

243 

244 

245def getmodebase(mode): 

246 """ 

247 Gets the "base" mode for given mode. This function returns "L" for 

248 images that contain grayscale data, and "RGB" for images that 

249 contain color data. 

250 

251 :param mode: Input mode. 

252 :returns: "L" or "RGB". 

253 :exception KeyError: If the input mode was not a standard mode. 

254 """ 

255 return ImageMode.getmode(mode).basemode 

256 

257 

258def getmodetype(mode): 

259 """ 

260 Gets the storage type mode. Given a mode, this function returns a 

261 single-layer mode suitable for storing individual bands. 

262 

263 :param mode: Input mode. 

264 :returns: "L", "I", or "F". 

265 :exception KeyError: If the input mode was not a standard mode. 

266 """ 

267 return ImageMode.getmode(mode).basetype 

268 

269 

270def getmodebandnames(mode): 

271 """ 

272 Gets a list of individual band names. Given a mode, this function returns 

273 a tuple containing the names of individual bands (use 

274 :py:method:`~PIL.Image.getmodetype` to get the mode used to store each 

275 individual band. 

276 

277 :param mode: Input mode. 

278 :returns: A tuple containing band names. The length of the tuple 

279 gives the number of bands in an image of the given mode. 

280 :exception KeyError: If the input mode was not a standard mode. 

281 """ 

282 return ImageMode.getmode(mode).bands 

283 

284 

285def getmodebands(mode): 

286 """ 

287 Gets the number of individual bands for this mode. 

288 

289 :param mode: Input mode. 

290 :returns: The number of bands in this mode. 

291 :exception KeyError: If the input mode was not a standard mode. 

292 """ 

293 return len(ImageMode.getmode(mode).bands) 

294 

295 

296# -------------------------------------------------------------------- 

297# Helpers 

298 

299_initialized = 0 

300 

301 

302def preinit(): 

303 """ 

304 Explicitly loads BMP, GIF, JPEG, PPM and PPM file format drivers. 

305 

306 It is called when opening or saving images. 

307 """ 

308 

309 global _initialized 

310 if _initialized >= 1: 

311 return 

312 

313 try: 

314 from . import BmpImagePlugin 

315 

316 assert BmpImagePlugin 

317 except ImportError: 

318 pass 

319 try: 

320 from . import GifImagePlugin 

321 

322 assert GifImagePlugin 

323 except ImportError: 

324 pass 

325 try: 

326 from . import JpegImagePlugin 

327 

328 assert JpegImagePlugin 

329 except ImportError: 

330 pass 

331 try: 

332 from . import PpmImagePlugin 

333 

334 assert PpmImagePlugin 

335 except ImportError: 

336 pass 

337 try: 

338 from . import PngImagePlugin 

339 

340 assert PngImagePlugin 

341 except ImportError: 

342 pass 

343 

344 _initialized = 1 

345 

346 

347def init(): 

348 """ 

349 Explicitly initializes the Python Imaging Library. This function 

350 loads all available file format drivers. 

351 

352 It is called when opening or saving images if :py:meth:`~preinit()` is 

353 insufficient, and by :py:meth:`~PIL.features.pilinfo`. 

354 """ 

355 

356 global _initialized 

357 if _initialized >= 2: 

358 return 0 

359 

360 parent_name = __name__.rpartition(".")[0] 

361 for plugin in _plugins: 

362 try: 

363 logger.debug("Importing %s", plugin) 

364 __import__(f"{parent_name}.{plugin}", globals(), locals(), []) 

365 except ImportError as e: 

366 logger.debug("Image: failed to import %s: %s", plugin, e) 

367 

368 if OPEN or SAVE: 

369 _initialized = 2 

370 return 1 

371 

372 

373# -------------------------------------------------------------------- 

374# Codec factories (used by tobytes/frombytes and ImageFile.load) 

375 

376 

377def _getdecoder(mode, decoder_name, args, extra=()): 

378 # tweak arguments 

379 if args is None: 

380 args = () 

381 elif not isinstance(args, tuple): 

382 args = (args,) 

383 

384 try: 

385 decoder = DECODERS[decoder_name] 

386 except KeyError: 

387 pass 

388 else: 

389 return decoder(mode, *args + extra) 

390 

391 try: 

392 # get decoder 

393 decoder = getattr(core, decoder_name + "_decoder") 

394 except AttributeError as e: 

395 msg = f"decoder {decoder_name} not available" 

396 raise OSError(msg) from e 

397 return decoder(mode, *args + extra) 

398 

399 

400def _getencoder(mode, encoder_name, args, extra=()): 

401 # tweak arguments 

402 if args is None: 

403 args = () 

404 elif not isinstance(args, tuple): 

405 args = (args,) 

406 

407 try: 

408 encoder = ENCODERS[encoder_name] 

409 except KeyError: 

410 pass 

411 else: 

412 return encoder(mode, *args + extra) 

413 

414 try: 

415 # get encoder 

416 encoder = getattr(core, encoder_name + "_encoder") 

417 except AttributeError as e: 

418 msg = f"encoder {encoder_name} not available" 

419 raise OSError(msg) from e 

420 return encoder(mode, *args + extra) 

421 

422 

423# -------------------------------------------------------------------- 

424# Simple expression analyzer 

425 

426 

427class _E: 

428 def __init__(self, scale, offset): 

429 self.scale = scale 

430 self.offset = offset 

431 

432 def __neg__(self): 

433 return _E(-self.scale, -self.offset) 

434 

435 def __add__(self, other): 

436 if isinstance(other, _E): 

437 return _E(self.scale + other.scale, self.offset + other.offset) 

438 return _E(self.scale, self.offset + other) 

439 

440 __radd__ = __add__ 

441 

442 def __sub__(self, other): 

443 return self + -other 

444 

445 def __rsub__(self, other): 

446 return other + -self 

447 

448 def __mul__(self, other): 

449 if isinstance(other, _E): 

450 return NotImplemented 

451 return _E(self.scale * other, self.offset * other) 

452 

453 __rmul__ = __mul__ 

454 

455 def __truediv__(self, other): 

456 if isinstance(other, _E): 

457 return NotImplemented 

458 return _E(self.scale / other, self.offset / other) 

459 

460 

461def _getscaleoffset(expr): 

462 a = expr(_E(1, 0)) 

463 return (a.scale, a.offset) if isinstance(a, _E) else (0, a) 

464 

465 

466# -------------------------------------------------------------------- 

467# Implementation wrapper 

468 

469 

470class Image: 

471 """ 

472 This class represents an image object. To create 

473 :py:class:`~PIL.Image.Image` objects, use the appropriate factory 

474 functions. There's hardly ever any reason to call the Image constructor 

475 directly. 

476 

477 * :py:func:`~PIL.Image.open` 

478 * :py:func:`~PIL.Image.new` 

479 * :py:func:`~PIL.Image.frombytes` 

480 """ 

481 

482 format: str | None = None 

483 format_description: str | None = None 

484 _close_exclusive_fp_after_loading = True 

485 

486 def __init__(self): 

487 # FIXME: take "new" parameters / other image? 

488 # FIXME: turn mode and size into delegating properties? 

489 self.im = None 

490 self._mode = "" 

491 self._size = (0, 0) 

492 self.palette = None 

493 self.info = {} 

494 self.readonly = 0 

495 self.pyaccess = None 

496 self._exif = None 

497 

498 @property 

499 def width(self): 

500 return self.size[0] 

501 

502 @property 

503 def height(self): 

504 return self.size[1] 

505 

506 @property 

507 def size(self): 

508 return self._size 

509 

510 @property 

511 def mode(self): 

512 return self._mode 

513 

514 def _new(self, im): 

515 new = Image() 

516 new.im = im 

517 new._mode = im.mode 

518 new._size = im.size 

519 if im.mode in ("P", "PA"): 

520 if self.palette: 

521 new.palette = self.palette.copy() 

522 else: 

523 from . import ImagePalette 

524 

525 new.palette = ImagePalette.ImagePalette() 

526 new.info = self.info.copy() 

527 return new 

528 

529 # Context manager support 

530 def __enter__(self): 

531 return self 

532 

533 def _close_fp(self): 

534 if getattr(self, "_fp", False): 

535 if self._fp != self.fp: 

536 self._fp.close() 

537 self._fp = DeferredError(ValueError("Operation on closed image")) 

538 if self.fp: 

539 self.fp.close() 

540 

541 def __exit__(self, *args): 

542 if hasattr(self, "fp"): 

543 if getattr(self, "_exclusive_fp", False): 

544 self._close_fp() 

545 self.fp = None 

546 

547 def close(self): 

548 """ 

549 Closes the file pointer, if possible. 

550 

551 This operation will destroy the image core and release its memory. 

552 The image data will be unusable afterward. 

553 

554 This function is required to close images that have multiple frames or 

555 have not had their file read and closed by the 

556 :py:meth:`~PIL.Image.Image.load` method. See :ref:`file-handling` for 

557 more information. 

558 """ 

559 if hasattr(self, "fp"): 

560 try: 

561 self._close_fp() 

562 self.fp = None 

563 except Exception as msg: 

564 logger.debug("Error closing: %s", msg) 

565 

566 if getattr(self, "map", None): 

567 self.map = None 

568 

569 # Instead of simply setting to None, we're setting up a 

570 # deferred error that will better explain that the core image 

571 # object is gone. 

572 self.im = DeferredError(ValueError("Operation on closed image")) 

573 

574 def _copy(self): 

575 self.load() 

576 self.im = self.im.copy() 

577 self.pyaccess = None 

578 self.readonly = 0 

579 

580 def _ensure_mutable(self): 

581 if self.readonly: 

582 self._copy() 

583 else: 

584 self.load() 

585 

586 def _dump(self, file=None, format=None, **options): 

587 suffix = "" 

588 if format: 

589 suffix = "." + format 

590 

591 if not file: 

592 f, filename = tempfile.mkstemp(suffix) 

593 os.close(f) 

594 else: 

595 filename = file 

596 if not filename.endswith(suffix): 

597 filename = filename + suffix 

598 

599 self.load() 

600 

601 if not format or format == "PPM": 

602 self.im.save_ppm(filename) 

603 else: 

604 self.save(filename, format, **options) 

605 

606 return filename 

607 

608 def __eq__(self, other): 

609 return ( 

610 self.__class__ is other.__class__ 

611 and self.mode == other.mode 

612 and self.size == other.size 

613 and self.info == other.info 

614 and self.getpalette() == other.getpalette() 

615 and self.tobytes() == other.tobytes() 

616 ) 

617 

618 def __repr__(self): 

619 return "<%s.%s image mode=%s size=%dx%d at 0x%X>" % ( 

620 self.__class__.__module__, 

621 self.__class__.__name__, 

622 self.mode, 

623 self.size[0], 

624 self.size[1], 

625 id(self), 

626 ) 

627 

628 def _repr_pretty_(self, p, cycle): 

629 """IPython plain text display support""" 

630 

631 # Same as __repr__ but without unpredictable id(self), 

632 # to keep Jupyter notebook `text/plain` output stable. 

633 p.text( 

634 "<%s.%s image mode=%s size=%dx%d>" 

635 % ( 

636 self.__class__.__module__, 

637 self.__class__.__name__, 

638 self.mode, 

639 self.size[0], 

640 self.size[1], 

641 ) 

642 ) 

643 

644 def _repr_image(self, image_format, **kwargs): 

645 """Helper function for iPython display hook. 

646 

647 :param image_format: Image format. 

648 :returns: image as bytes, saved into the given format. 

649 """ 

650 b = io.BytesIO() 

651 try: 

652 self.save(b, image_format, **kwargs) 

653 except Exception: 

654 return None 

655 return b.getvalue() 

656 

657 def _repr_png_(self): 

658 """iPython display hook support for PNG format. 

659 

660 :returns: PNG version of the image as bytes 

661 """ 

662 return self._repr_image("PNG", compress_level=1) 

663 

664 def _repr_jpeg_(self): 

665 """iPython display hook support for JPEG format. 

666 

667 :returns: JPEG version of the image as bytes 

668 """ 

669 return self._repr_image("JPEG") 

670 

671 @property 

672 def __array_interface__(self): 

673 # numpy array interface support 

674 new = {"version": 3} 

675 try: 

676 if self.mode == "1": 

677 # Binary images need to be extended from bits to bytes 

678 # See: https://github.com/python-pillow/Pillow/issues/350 

679 new["data"] = self.tobytes("raw", "L") 

680 else: 

681 new["data"] = self.tobytes() 

682 except Exception as e: 

683 if not isinstance(e, (MemoryError, RecursionError)): 

684 try: 

685 import numpy 

686 from packaging.version import parse as parse_version 

687 except ImportError: 

688 pass 

689 else: 

690 if parse_version(numpy.__version__) < parse_version("1.23"): 

691 warnings.warn(e) 

692 raise 

693 new["shape"], new["typestr"] = _conv_type_shape(self) 

694 return new 

695 

696 def __getstate__(self): 

697 im_data = self.tobytes() # load image first 

698 return [self.info, self.mode, self.size, self.getpalette(), im_data] 

699 

700 def __setstate__(self, state): 

701 Image.__init__(self) 

702 info, mode, size, palette, data = state 

703 self.info = info 

704 self._mode = mode 

705 self._size = size 

706 self.im = core.new(mode, size) 

707 if mode in ("L", "LA", "P", "PA") and palette: 

708 self.putpalette(palette) 

709 self.frombytes(data) 

710 

711 def tobytes(self, encoder_name="raw", *args): 

712 """ 

713 Return image as a bytes object. 

714 

715 .. warning:: 

716 

717 This method returns the raw image data from the internal 

718 storage. For compressed image data (e.g. PNG, JPEG) use 

719 :meth:`~.save`, with a BytesIO parameter for in-memory 

720 data. 

721 

722 :param encoder_name: What encoder to use. The default is to 

723 use the standard "raw" encoder. 

724 

725 A list of C encoders can be seen under 

726 codecs section of the function array in 

727 :file:`_imaging.c`. Python encoders are 

728 registered within the relevant plugins. 

729 :param args: Extra arguments to the encoder. 

730 :returns: A :py:class:`bytes` object. 

731 """ 

732 

733 # may pass tuple instead of argument list 

734 if len(args) == 1 and isinstance(args[0], tuple): 

735 args = args[0] 

736 

737 if encoder_name == "raw" and args == (): 

738 args = self.mode 

739 

740 self.load() 

741 

742 if self.width == 0 or self.height == 0: 

743 return b"" 

744 

745 # unpack data 

746 e = _getencoder(self.mode, encoder_name, args) 

747 e.setimage(self.im) 

748 

749 bufsize = max(65536, self.size[0] * 4) # see RawEncode.c 

750 

751 output = [] 

752 while True: 

753 bytes_consumed, errcode, data = e.encode(bufsize) 

754 output.append(data) 

755 if errcode: 

756 break 

757 if errcode < 0: 

758 msg = f"encoder error {errcode} in tobytes" 

759 raise RuntimeError(msg) 

760 

761 return b"".join(output) 

762 

763 def tobitmap(self, name="image"): 

764 """ 

765 Returns the image converted to an X11 bitmap. 

766 

767 .. note:: This method only works for mode "1" images. 

768 

769 :param name: The name prefix to use for the bitmap variables. 

770 :returns: A string containing an X11 bitmap. 

771 :raises ValueError: If the mode is not "1" 

772 """ 

773 

774 self.load() 

775 if self.mode != "1": 

776 msg = "not a bitmap" 

777 raise ValueError(msg) 

778 data = self.tobytes("xbm") 

779 return b"".join( 

780 [ 

781 f"#define {name}_width {self.size[0]}\n".encode("ascii"), 

782 f"#define {name}_height {self.size[1]}\n".encode("ascii"), 

783 f"static char {name}_bits[] = { \n".encode("ascii"), 

784 data, 

785 b"};", 

786 ] 

787 ) 

788 

789 def frombytes(self, data, decoder_name="raw", *args): 

790 """ 

791 Loads this image with pixel data from a bytes object. 

792 

793 This method is similar to the :py:func:`~PIL.Image.frombytes` function, 

794 but loads data into this image instead of creating a new image object. 

795 """ 

796 

797 if self.width == 0 or self.height == 0: 

798 return 

799 

800 # may pass tuple instead of argument list 

801 if len(args) == 1 and isinstance(args[0], tuple): 

802 args = args[0] 

803 

804 # default format 

805 if decoder_name == "raw" and args == (): 

806 args = self.mode 

807 

808 # unpack data 

809 d = _getdecoder(self.mode, decoder_name, args) 

810 d.setimage(self.im) 

811 s = d.decode(data) 

812 

813 if s[0] >= 0: 

814 msg = "not enough image data" 

815 raise ValueError(msg) 

816 if s[1] != 0: 

817 msg = "cannot decode image data" 

818 raise ValueError(msg) 

819 

820 def load(self): 

821 """ 

822 Allocates storage for the image and loads the pixel data. In 

823 normal cases, you don't need to call this method, since the 

824 Image class automatically loads an opened image when it is 

825 accessed for the first time. 

826 

827 If the file associated with the image was opened by Pillow, then this 

828 method will close it. The exception to this is if the image has 

829 multiple frames, in which case the file will be left open for seek 

830 operations. See :ref:`file-handling` for more information. 

831 

832 :returns: An image access object. 

833 :rtype: :ref:`PixelAccess` or :py:class:`PIL.PyAccess` 

834 """ 

835 if self.im is not None and self.palette and self.palette.dirty: 

836 # realize palette 

837 mode, arr = self.palette.getdata() 

838 self.im.putpalette(mode, arr) 

839 self.palette.dirty = 0 

840 self.palette.rawmode = None 

841 if "transparency" in self.info and mode in ("LA", "PA"): 

842 if isinstance(self.info["transparency"], int): 

843 self.im.putpalettealpha(self.info["transparency"], 0) 

844 else: 

845 self.im.putpalettealphas(self.info["transparency"]) 

846 self.palette.mode = "RGBA" 

847 else: 

848 palette_mode = "RGBA" if mode.startswith("RGBA") else "RGB" 

849 self.palette.mode = palette_mode 

850 self.palette.palette = self.im.getpalette(palette_mode, palette_mode) 

851 

852 if self.im is not None: 

853 if cffi and USE_CFFI_ACCESS: 

854 if self.pyaccess: 

855 return self.pyaccess 

856 from . import PyAccess 

857 

858 self.pyaccess = PyAccess.new(self, self.readonly) 

859 if self.pyaccess: 

860 return self.pyaccess 

861 return self.im.pixel_access(self.readonly) 

862 

863 def verify(self): 

864 """ 

865 Verifies the contents of a file. For data read from a file, this 

866 method attempts to determine if the file is broken, without 

867 actually decoding the image data. If this method finds any 

868 problems, it raises suitable exceptions. If you need to load 

869 the image after using this method, you must reopen the image 

870 file. 

871 """ 

872 pass 

873 

874 def convert( 

875 self, mode=None, matrix=None, dither=None, palette=Palette.WEB, colors=256 

876 ): 

877 """ 

878 Returns a converted copy of this image. For the "P" mode, this 

879 method translates pixels through the palette. If mode is 

880 omitted, a mode is chosen so that all information in the image 

881 and the palette can be represented without a palette. 

882 

883 The current version supports all possible conversions between 

884 "L", "RGB" and "CMYK". The ``matrix`` argument only supports "L" 

885 and "RGB". 

886 

887 When translating a color image to grayscale (mode "L"), 

888 the library uses the ITU-R 601-2 luma transform:: 

889 

890 L = R * 299/1000 + G * 587/1000 + B * 114/1000 

891 

892 The default method of converting a grayscale ("L") or "RGB" 

893 image into a bilevel (mode "1") image uses Floyd-Steinberg 

894 dither to approximate the original image luminosity levels. If 

895 dither is ``None``, all values larger than 127 are set to 255 (white), 

896 all other values to 0 (black). To use other thresholds, use the 

897 :py:meth:`~PIL.Image.Image.point` method. 

898 

899 When converting from "RGBA" to "P" without a ``matrix`` argument, 

900 this passes the operation to :py:meth:`~PIL.Image.Image.quantize`, 

901 and ``dither`` and ``palette`` are ignored. 

902 

903 When converting from "PA", if an "RGBA" palette is present, the alpha 

904 channel from the image will be used instead of the values from the palette. 

905 

906 :param mode: The requested mode. See: :ref:`concept-modes`. 

907 :param matrix: An optional conversion matrix. If given, this 

908 should be 4- or 12-tuple containing floating point values. 

909 :param dither: Dithering method, used when converting from 

910 mode "RGB" to "P" or from "RGB" or "L" to "1". 

911 Available methods are :data:`Dither.NONE` or :data:`Dither.FLOYDSTEINBERG` 

912 (default). Note that this is not used when ``matrix`` is supplied. 

913 :param palette: Palette to use when converting from mode "RGB" 

914 to "P". Available palettes are :data:`Palette.WEB` or 

915 :data:`Palette.ADAPTIVE`. 

916 :param colors: Number of colors to use for the :data:`Palette.ADAPTIVE` 

917 palette. Defaults to 256. 

918 :rtype: :py:class:`~PIL.Image.Image` 

919 :returns: An :py:class:`~PIL.Image.Image` object. 

920 """ 

921 

922 self.load() 

923 

924 has_transparency = "transparency" in self.info 

925 if not mode and self.mode == "P": 

926 # determine default mode 

927 if self.palette: 

928 mode = self.palette.mode 

929 else: 

930 mode = "RGB" 

931 if mode == "RGB" and has_transparency: 

932 mode = "RGBA" 

933 if not mode or (mode == self.mode and not matrix): 

934 return self.copy() 

935 

936 if matrix: 

937 # matrix conversion 

938 if mode not in ("L", "RGB"): 

939 msg = "illegal conversion" 

940 raise ValueError(msg) 

941 im = self.im.convert_matrix(mode, matrix) 

942 new_im = self._new(im) 

943 if has_transparency and self.im.bands == 3: 

944 transparency = new_im.info["transparency"] 

945 

946 def convert_transparency(m, v): 

947 v = m[0] * v[0] + m[1] * v[1] + m[2] * v[2] + m[3] * 0.5 

948 return max(0, min(255, int(v))) 

949 

950 if mode == "L": 

951 transparency = convert_transparency(matrix, transparency) 

952 elif len(mode) == 3: 

953 transparency = tuple( 

954 convert_transparency(matrix[i * 4 : i * 4 + 4], transparency) 

955 for i in range(0, len(transparency)) 

956 ) 

957 new_im.info["transparency"] = transparency 

958 return new_im 

959 

960 if mode == "P" and self.mode == "RGBA": 

961 return self.quantize(colors) 

962 

963 trns = None 

964 delete_trns = False 

965 # transparency handling 

966 if has_transparency: 

967 if (self.mode in ("1", "L", "I") and mode in ("LA", "RGBA")) or ( 

968 self.mode == "RGB" and mode == "RGBA" 

969 ): 

970 # Use transparent conversion to promote from transparent 

971 # color to an alpha channel. 

972 new_im = self._new( 

973 self.im.convert_transparent(mode, self.info["transparency"]) 

974 ) 

975 del new_im.info["transparency"] 

976 return new_im 

977 elif self.mode in ("L", "RGB", "P") and mode in ("L", "RGB", "P"): 

978 t = self.info["transparency"] 

979 if isinstance(t, bytes): 

980 # Dragons. This can't be represented by a single color 

981 warnings.warn( 

982 "Palette images with Transparency expressed in bytes should be " 

983 "converted to RGBA images" 

984 ) 

985 delete_trns = True 

986 else: 

987 # get the new transparency color. 

988 # use existing conversions 

989 trns_im = new(self.mode, (1, 1)) 

990 if self.mode == "P": 

991 trns_im.putpalette(self.palette) 

992 if isinstance(t, tuple): 

993 err = "Couldn't allocate a palette color for transparency" 

994 try: 

995 t = trns_im.palette.getcolor(t, self) 

996 except ValueError as e: 

997 if str(e) == "cannot allocate more than 256 colors": 

998 # If all 256 colors are in use, 

999 # then there is no need for transparency 

1000 t = None 

1001 else: 

1002 raise ValueError(err) from e 

1003 if t is None: 

1004 trns = None 

1005 else: 

1006 trns_im.putpixel((0, 0), t) 

1007 

1008 if mode in ("L", "RGB"): 

1009 trns_im = trns_im.convert(mode) 

1010 else: 

1011 # can't just retrieve the palette number, got to do it 

1012 # after quantization. 

1013 trns_im = trns_im.convert("RGB") 

1014 trns = trns_im.getpixel((0, 0)) 

1015 

1016 elif self.mode == "P" and mode in ("LA", "PA", "RGBA"): 

1017 t = self.info["transparency"] 

1018 delete_trns = True 

1019 

1020 if isinstance(t, bytes): 

1021 self.im.putpalettealphas(t) 

1022 elif isinstance(t, int): 

1023 self.im.putpalettealpha(t, 0) 

1024 else: 

1025 msg = "Transparency for P mode should be bytes or int" 

1026 raise ValueError(msg) 

1027 

1028 if mode == "P" and palette == Palette.ADAPTIVE: 

1029 im = self.im.quantize(colors) 

1030 new_im = self._new(im) 

1031 from . import ImagePalette 

1032 

1033 new_im.palette = ImagePalette.ImagePalette( 

1034 "RGB", new_im.im.getpalette("RGB") 

1035 ) 

1036 if delete_trns: 

1037 # This could possibly happen if we requantize to fewer colors. 

1038 # The transparency would be totally off in that case. 

1039 del new_im.info["transparency"] 

1040 if trns is not None: 

1041 try: 

1042 new_im.info["transparency"] = new_im.palette.getcolor(trns, new_im) 

1043 except Exception: 

1044 # if we can't make a transparent color, don't leave the old 

1045 # transparency hanging around to mess us up. 

1046 del new_im.info["transparency"] 

1047 warnings.warn("Couldn't allocate palette entry for transparency") 

1048 return new_im 

1049 

1050 if "LAB" in (self.mode, mode): 

1051 other_mode = mode if self.mode == "LAB" else self.mode 

1052 if other_mode in ("RGB", "RGBA", "RGBX"): 

1053 from . import ImageCms 

1054 

1055 srgb = ImageCms.createProfile("sRGB") 

1056 lab = ImageCms.createProfile("LAB") 

1057 profiles = [lab, srgb] if self.mode == "LAB" else [srgb, lab] 

1058 transform = ImageCms.buildTransform( 

1059 profiles[0], profiles[1], self.mode, mode 

1060 ) 

1061 return transform.apply(self) 

1062 

1063 # colorspace conversion 

1064 if dither is None: 

1065 dither = Dither.FLOYDSTEINBERG 

1066 

1067 try: 

1068 im = self.im.convert(mode, dither) 

1069 except ValueError: 

1070 try: 

1071 # normalize source image and try again 

1072 modebase = getmodebase(self.mode) 

1073 if modebase == self.mode: 

1074 raise 

1075 im = self.im.convert(modebase) 

1076 im = im.convert(mode, dither) 

1077 except KeyError as e: 

1078 msg = "illegal conversion" 

1079 raise ValueError(msg) from e 

1080 

1081 new_im = self._new(im) 

1082 if mode == "P" and palette != Palette.ADAPTIVE: 

1083 from . import ImagePalette 

1084 

1085 new_im.palette = ImagePalette.ImagePalette("RGB", im.getpalette("RGB")) 

1086 if delete_trns: 

1087 # crash fail if we leave a bytes transparency in an rgb/l mode. 

1088 del new_im.info["transparency"] 

1089 if trns is not None: 

1090 if new_im.mode == "P": 

1091 try: 

1092 new_im.info["transparency"] = new_im.palette.getcolor(trns, new_im) 

1093 except ValueError as e: 

1094 del new_im.info["transparency"] 

1095 if str(e) != "cannot allocate more than 256 colors": 

1096 # If all 256 colors are in use, 

1097 # then there is no need for transparency 

1098 warnings.warn( 

1099 "Couldn't allocate palette entry for transparency" 

1100 ) 

1101 else: 

1102 new_im.info["transparency"] = trns 

1103 return new_im 

1104 

1105 def quantize( 

1106 self, 

1107 colors=256, 

1108 method=None, 

1109 kmeans=0, 

1110 palette=None, 

1111 dither=Dither.FLOYDSTEINBERG, 

1112 ): 

1113 """ 

1114 Convert the image to 'P' mode with the specified number 

1115 of colors. 

1116 

1117 :param colors: The desired number of colors, <= 256 

1118 :param method: :data:`Quantize.MEDIANCUT` (median cut), 

1119 :data:`Quantize.MAXCOVERAGE` (maximum coverage), 

1120 :data:`Quantize.FASTOCTREE` (fast octree), 

1121 :data:`Quantize.LIBIMAGEQUANT` (libimagequant; check support 

1122 using :py:func:`PIL.features.check_feature` with 

1123 ``feature="libimagequant"``). 

1124 

1125 By default, :data:`Quantize.MEDIANCUT` will be used. 

1126 

1127 The exception to this is RGBA images. :data:`Quantize.MEDIANCUT` 

1128 and :data:`Quantize.MAXCOVERAGE` do not support RGBA images, so 

1129 :data:`Quantize.FASTOCTREE` is used by default instead. 

1130 :param kmeans: Integer 

1131 :param palette: Quantize to the palette of given 

1132 :py:class:`PIL.Image.Image`. 

1133 :param dither: Dithering method, used when converting from 

1134 mode "RGB" to "P" or from "RGB" or "L" to "1". 

1135 Available methods are :data:`Dither.NONE` or :data:`Dither.FLOYDSTEINBERG` 

1136 (default). 

1137 :returns: A new image 

1138 """ 

1139 

1140 self.load() 

1141 

1142 if method is None: 

1143 # defaults: 

1144 method = Quantize.MEDIANCUT 

1145 if self.mode == "RGBA": 

1146 method = Quantize.FASTOCTREE 

1147 

1148 if self.mode == "RGBA" and method not in ( 

1149 Quantize.FASTOCTREE, 

1150 Quantize.LIBIMAGEQUANT, 

1151 ): 

1152 # Caller specified an invalid mode. 

1153 msg = ( 

1154 "Fast Octree (method == 2) and libimagequant (method == 3) " 

1155 "are the only valid methods for quantizing RGBA images" 

1156 ) 

1157 raise ValueError(msg) 

1158 

1159 if palette: 

1160 # use palette from reference image 

1161 palette.load() 

1162 if palette.mode != "P": 

1163 msg = "bad mode for palette image" 

1164 raise ValueError(msg) 

1165 if self.mode not in {"RGB", "L"}: 

1166 msg = "only RGB or L mode images can be quantized to a palette" 

1167 raise ValueError(msg) 

1168 im = self.im.convert("P", dither, palette.im) 

1169 new_im = self._new(im) 

1170 new_im.palette = palette.palette.copy() 

1171 return new_im 

1172 

1173 im = self._new(self.im.quantize(colors, method, kmeans)) 

1174 

1175 from . import ImagePalette 

1176 

1177 mode = im.im.getpalettemode() 

1178 palette = im.im.getpalette(mode, mode)[: colors * len(mode)] 

1179 im.palette = ImagePalette.ImagePalette(mode, palette) 

1180 

1181 return im 

1182 

1183 def copy(self) -> Image: 

1184 """ 

1185 Copies this image. Use this method if you wish to paste things 

1186 into an image, but still retain the original. 

1187 

1188 :rtype: :py:class:`~PIL.Image.Image` 

1189 :returns: An :py:class:`~PIL.Image.Image` object. 

1190 """ 

1191 self.load() 

1192 return self._new(self.im.copy()) 

1193 

1194 __copy__ = copy 

1195 

1196 def crop(self, box=None) -> Image: 

1197 """ 

1198 Returns a rectangular region from this image. The box is a 

1199 4-tuple defining the left, upper, right, and lower pixel 

1200 coordinate. See :ref:`coordinate-system`. 

1201 

1202 Note: Prior to Pillow 3.4.0, this was a lazy operation. 

1203 

1204 :param box: The crop rectangle, as a (left, upper, right, lower)-tuple. 

1205 :rtype: :py:class:`~PIL.Image.Image` 

1206 :returns: An :py:class:`~PIL.Image.Image` object. 

1207 """ 

1208 

1209 if box is None: 

1210 return self.copy() 

1211 

1212 if box[2] < box[0]: 

1213 msg = "Coordinate 'right' is less than 'left'" 

1214 raise ValueError(msg) 

1215 elif box[3] < box[1]: 

1216 msg = "Coordinate 'lower' is less than 'upper'" 

1217 raise ValueError(msg) 

1218 

1219 self.load() 

1220 return self._new(self._crop(self.im, box)) 

1221 

1222 def _crop(self, im, box): 

1223 """ 

1224 Returns a rectangular region from the core image object im. 

1225 

1226 This is equivalent to calling im.crop((x0, y0, x1, y1)), but 

1227 includes additional sanity checks. 

1228 

1229 :param im: a core image object 

1230 :param box: The crop rectangle, as a (left, upper, right, lower)-tuple. 

1231 :returns: A core image object. 

1232 """ 

1233 

1234 x0, y0, x1, y1 = map(int, map(round, box)) 

1235 

1236 absolute_values = (abs(x1 - x0), abs(y1 - y0)) 

1237 

1238 _decompression_bomb_check(absolute_values) 

1239 

1240 return im.crop((x0, y0, x1, y1)) 

1241 

1242 def draft(self, mode, size): 

1243 """ 

1244 Configures the image file loader so it returns a version of the 

1245 image that as closely as possible matches the given mode and 

1246 size. For example, you can use this method to convert a color 

1247 JPEG to grayscale while loading it. 

1248 

1249 If any changes are made, returns a tuple with the chosen ``mode`` and 

1250 ``box`` with coordinates of the original image within the altered one. 

1251 

1252 Note that this method modifies the :py:class:`~PIL.Image.Image` object 

1253 in place. If the image has already been loaded, this method has no 

1254 effect. 

1255 

1256 Note: This method is not implemented for most images. It is 

1257 currently implemented only for JPEG and MPO images. 

1258 

1259 :param mode: The requested mode. 

1260 :param size: The requested size in pixels, as a 2-tuple: 

1261 (width, height). 

1262 """ 

1263 pass 

1264 

1265 def _expand(self, xmargin, ymargin=None): 

1266 if ymargin is None: 

1267 ymargin = xmargin 

1268 self.load() 

1269 return self._new(self.im.expand(xmargin, ymargin)) 

1270 

1271 def filter(self, filter): 

1272 """ 

1273 Filters this image using the given filter. For a list of 

1274 available filters, see the :py:mod:`~PIL.ImageFilter` module. 

1275 

1276 :param filter: Filter kernel. 

1277 :returns: An :py:class:`~PIL.Image.Image` object.""" 

1278 

1279 from . import ImageFilter 

1280 

1281 self.load() 

1282 

1283 if isinstance(filter, Callable): 

1284 filter = filter() 

1285 if not hasattr(filter, "filter"): 

1286 msg = "filter argument should be ImageFilter.Filter instance or class" 

1287 raise TypeError(msg) 

1288 

1289 multiband = isinstance(filter, ImageFilter.MultibandFilter) 

1290 if self.im.bands == 1 or multiband: 

1291 return self._new(filter.filter(self.im)) 

1292 

1293 ims = [ 

1294 self._new(filter.filter(self.im.getband(c))) for c in range(self.im.bands) 

1295 ] 

1296 return merge(self.mode, ims) 

1297 

1298 def getbands(self): 

1299 """ 

1300 Returns a tuple containing the name of each band in this image. 

1301 For example, ``getbands`` on an RGB image returns ("R", "G", "B"). 

1302 

1303 :returns: A tuple containing band names. 

1304 :rtype: tuple 

1305 """ 

1306 return ImageMode.getmode(self.mode).bands 

1307 

1308 def getbbox(self, *, alpha_only=True): 

1309 """ 

1310 Calculates the bounding box of the non-zero regions in the 

1311 image. 

1312 

1313 :param alpha_only: Optional flag, defaulting to ``True``. 

1314 If ``True`` and the image has an alpha channel, trim transparent pixels. 

1315 Otherwise, trim pixels when all channels are zero. 

1316 Keyword-only argument. 

1317 :returns: The bounding box is returned as a 4-tuple defining the 

1318 left, upper, right, and lower pixel coordinate. See 

1319 :ref:`coordinate-system`. If the image is completely empty, this 

1320 method returns None. 

1321 

1322 """ 

1323 

1324 self.load() 

1325 return self.im.getbbox(alpha_only) 

1326 

1327 def getcolors(self, maxcolors=256): 

1328 """ 

1329 Returns a list of colors used in this image. 

1330 

1331 The colors will be in the image's mode. For example, an RGB image will 

1332 return a tuple of (red, green, blue) color values, and a P image will 

1333 return the index of the color in the palette. 

1334 

1335 :param maxcolors: Maximum number of colors. If this number is 

1336 exceeded, this method returns None. The default limit is 

1337 256 colors. 

1338 :returns: An unsorted list of (count, pixel) values. 

1339 """ 

1340 

1341 self.load() 

1342 if self.mode in ("1", "L", "P"): 

1343 h = self.im.histogram() 

1344 out = [(h[i], i) for i in range(256) if h[i]] 

1345 if len(out) > maxcolors: 

1346 return None 

1347 return out 

1348 return self.im.getcolors(maxcolors) 

1349 

1350 def getdata(self, band=None): 

1351 """ 

1352 Returns the contents of this image as a sequence object 

1353 containing pixel values. The sequence object is flattened, so 

1354 that values for line one follow directly after the values of 

1355 line zero, and so on. 

1356 

1357 Note that the sequence object returned by this method is an 

1358 internal PIL data type, which only supports certain sequence 

1359 operations. To convert it to an ordinary sequence (e.g. for 

1360 printing), use ``list(im.getdata())``. 

1361 

1362 :param band: What band to return. The default is to return 

1363 all bands. To return a single band, pass in the index 

1364 value (e.g. 0 to get the "R" band from an "RGB" image). 

1365 :returns: A sequence-like object. 

1366 """ 

1367 

1368 self.load() 

1369 if band is not None: 

1370 return self.im.getband(band) 

1371 return self.im # could be abused 

1372 

1373 def getextrema(self): 

1374 """ 

1375 Gets the minimum and maximum pixel values for each band in 

1376 the image. 

1377 

1378 :returns: For a single-band image, a 2-tuple containing the 

1379 minimum and maximum pixel value. For a multi-band image, 

1380 a tuple containing one 2-tuple for each band. 

1381 """ 

1382 

1383 self.load() 

1384 if self.im.bands > 1: 

1385 return tuple(self.im.getband(i).getextrema() for i in range(self.im.bands)) 

1386 return self.im.getextrema() 

1387 

1388 def _getxmp(self, xmp_tags): 

1389 def get_name(tag): 

1390 return re.sub("^{[^}]+}", "", tag) 

1391 

1392 def get_value(element): 

1393 value = {get_name(k): v for k, v in element.attrib.items()} 

1394 children = list(element) 

1395 if children: 

1396 for child in children: 

1397 name = get_name(child.tag) 

1398 child_value = get_value(child) 

1399 if name in value: 

1400 if not isinstance(value[name], list): 

1401 value[name] = [value[name]] 

1402 value[name].append(child_value) 

1403 else: 

1404 value[name] = child_value 

1405 elif value: 

1406 if element.text: 

1407 value["text"] = element.text 

1408 else: 

1409 return element.text 

1410 return value 

1411 

1412 if ElementTree is None: 

1413 warnings.warn("XMP data cannot be read without defusedxml dependency") 

1414 return {} 

1415 else: 

1416 root = ElementTree.fromstring(xmp_tags) 

1417 return {get_name(root.tag): get_value(root)} 

1418 

1419 def getexif(self): 

1420 """ 

1421 Gets EXIF data from the image. 

1422 

1423 :returns: an :py:class:`~PIL.Image.Exif` object. 

1424 """ 

1425 if self._exif is None: 

1426 self._exif = Exif() 

1427 self._exif._loaded = False 

1428 elif self._exif._loaded: 

1429 return self._exif 

1430 self._exif._loaded = True 

1431 

1432 exif_info = self.info.get("exif") 

1433 if exif_info is None: 

1434 if "Raw profile type exif" in self.info: 

1435 exif_info = bytes.fromhex( 

1436 "".join(self.info["Raw profile type exif"].split("\n")[3:]) 

1437 ) 

1438 elif hasattr(self, "tag_v2"): 

1439 self._exif.bigtiff = self.tag_v2._bigtiff 

1440 self._exif.endian = self.tag_v2._endian 

1441 self._exif.load_from_fp(self.fp, self.tag_v2._offset) 

1442 if exif_info is not None: 

1443 self._exif.load(exif_info) 

1444 

1445 # XMP tags 

1446 if ExifTags.Base.Orientation not in self._exif: 

1447 xmp_tags = self.info.get("XML:com.adobe.xmp") 

1448 if xmp_tags: 

1449 match = re.search(r'tiff:Orientation(="|>)([0-9])', xmp_tags) 

1450 if match: 

1451 self._exif[ExifTags.Base.Orientation] = int(match[2]) 

1452 

1453 return self._exif 

1454 

1455 def _reload_exif(self): 

1456 if self._exif is None or not self._exif._loaded: 

1457 return 

1458 self._exif._loaded = False 

1459 self.getexif() 

1460 

1461 def get_child_images(self): 

1462 child_images = [] 

1463 exif = self.getexif() 

1464 ifds = [] 

1465 if ExifTags.Base.SubIFDs in exif: 

1466 subifd_offsets = exif[ExifTags.Base.SubIFDs] 

1467 if subifd_offsets: 

1468 if not isinstance(subifd_offsets, tuple): 

1469 subifd_offsets = (subifd_offsets,) 

1470 for subifd_offset in subifd_offsets: 

1471 ifds.append((exif._get_ifd_dict(subifd_offset), subifd_offset)) 

1472 ifd1 = exif.get_ifd(ExifTags.IFD.IFD1) 

1473 if ifd1 and ifd1.get(513): 

1474 ifds.append((ifd1, exif._info.next)) 

1475 

1476 offset = None 

1477 for ifd, ifd_offset in ifds: 

1478 current_offset = self.fp.tell() 

1479 if offset is None: 

1480 offset = current_offset 

1481 

1482 fp = self.fp 

1483 thumbnail_offset = ifd.get(513) 

1484 if thumbnail_offset is not None: 

1485 try: 

1486 thumbnail_offset += self._exif_offset 

1487 except AttributeError: 

1488 pass 

1489 self.fp.seek(thumbnail_offset) 

1490 data = self.fp.read(ifd.get(514)) 

1491 fp = io.BytesIO(data) 

1492 

1493 with open(fp) as im: 

1494 if thumbnail_offset is None: 

1495 im._frame_pos = [ifd_offset] 

1496 im._seek(0) 

1497 im.load() 

1498 child_images.append(im) 

1499 

1500 if offset is not None: 

1501 self.fp.seek(offset) 

1502 return child_images 

1503 

1504 def getim(self): 

1505 """ 

1506 Returns a capsule that points to the internal image memory. 

1507 

1508 :returns: A capsule object. 

1509 """ 

1510 

1511 self.load() 

1512 return self.im.ptr 

1513 

1514 def getpalette(self, rawmode="RGB"): 

1515 """ 

1516 Returns the image palette as a list. 

1517 

1518 :param rawmode: The mode in which to return the palette. ``None`` will 

1519 return the palette in its current mode. 

1520 

1521 .. versionadded:: 9.1.0 

1522 

1523 :returns: A list of color values [r, g, b, ...], or None if the 

1524 image has no palette. 

1525 """ 

1526 

1527 self.load() 

1528 try: 

1529 mode = self.im.getpalettemode() 

1530 except ValueError: 

1531 return None # no palette 

1532 if rawmode is None: 

1533 rawmode = mode 

1534 return list(self.im.getpalette(mode, rawmode)) 

1535 

1536 @property 

1537 def has_transparency_data(self) -> bool: 

1538 """ 

1539 Determine if an image has transparency data, whether in the form of an 

1540 alpha channel, a palette with an alpha channel, or a "transparency" key 

1541 in the info dictionary. 

1542 

1543 Note the image might still appear solid, if all of the values shown 

1544 within are opaque. 

1545 

1546 :returns: A boolean. 

1547 """ 

1548 return ( 

1549 self.mode in ("LA", "La", "PA", "RGBA", "RGBa") 

1550 or (self.mode == "P" and self.palette.mode.endswith("A")) 

1551 or "transparency" in self.info 

1552 ) 

1553 

1554 def apply_transparency(self): 

1555 """ 

1556 If a P mode image has a "transparency" key in the info dictionary, 

1557 remove the key and instead apply the transparency to the palette. 

1558 Otherwise, the image is unchanged. 

1559 """ 

1560 if self.mode != "P" or "transparency" not in self.info: 

1561 return 

1562 

1563 from . import ImagePalette 

1564 

1565 palette = self.getpalette("RGBA") 

1566 transparency = self.info["transparency"] 

1567 if isinstance(transparency, bytes): 

1568 for i, alpha in enumerate(transparency): 

1569 palette[i * 4 + 3] = alpha 

1570 else: 

1571 palette[transparency * 4 + 3] = 0 

1572 self.palette = ImagePalette.ImagePalette("RGBA", bytes(palette)) 

1573 self.palette.dirty = 1 

1574 

1575 del self.info["transparency"] 

1576 

1577 def getpixel(self, xy): 

1578 """ 

1579 Returns the pixel value at a given position. 

1580 

1581 :param xy: The coordinate, given as (x, y). See 

1582 :ref:`coordinate-system`. 

1583 :returns: The pixel value. If the image is a multi-layer image, 

1584 this method returns a tuple. 

1585 """ 

1586 

1587 self.load() 

1588 if self.pyaccess: 

1589 return self.pyaccess.getpixel(xy) 

1590 return self.im.getpixel(tuple(xy)) 

1591 

1592 def getprojection(self): 

1593 """ 

1594 Get projection to x and y axes 

1595 

1596 :returns: Two sequences, indicating where there are non-zero 

1597 pixels along the X-axis and the Y-axis, respectively. 

1598 """ 

1599 

1600 self.load() 

1601 x, y = self.im.getprojection() 

1602 return list(x), list(y) 

1603 

1604 def histogram(self, mask=None, extrema=None): 

1605 """ 

1606 Returns a histogram for the image. The histogram is returned as a 

1607 list of pixel counts, one for each pixel value in the source 

1608 image. Counts are grouped into 256 bins for each band, even if 

1609 the image has more than 8 bits per band. If the image has more 

1610 than one band, the histograms for all bands are concatenated (for 

1611 example, the histogram for an "RGB" image contains 768 values). 

1612 

1613 A bilevel image (mode "1") is treated as a grayscale ("L") image 

1614 by this method. 

1615 

1616 If a mask is provided, the method returns a histogram for those 

1617 parts of the image where the mask image is non-zero. The mask 

1618 image must have the same size as the image, and be either a 

1619 bi-level image (mode "1") or a grayscale image ("L"). 

1620 

1621 :param mask: An optional mask. 

1622 :param extrema: An optional tuple of manually-specified extrema. 

1623 :returns: A list containing pixel counts. 

1624 """ 

1625 self.load() 

1626 if mask: 

1627 mask.load() 

1628 return self.im.histogram((0, 0), mask.im) 

1629 if self.mode in ("I", "F"): 

1630 if extrema is None: 

1631 extrema = self.getextrema() 

1632 return self.im.histogram(extrema) 

1633 return self.im.histogram() 

1634 

1635 def entropy(self, mask=None, extrema=None): 

1636 """ 

1637 Calculates and returns the entropy for the image. 

1638 

1639 A bilevel image (mode "1") is treated as a grayscale ("L") 

1640 image by this method. 

1641 

1642 If a mask is provided, the method employs the histogram for 

1643 those parts of the image where the mask image is non-zero. 

1644 The mask image must have the same size as the image, and be 

1645 either a bi-level image (mode "1") or a grayscale image ("L"). 

1646 

1647 :param mask: An optional mask. 

1648 :param extrema: An optional tuple of manually-specified extrema. 

1649 :returns: A float value representing the image entropy 

1650 """ 

1651 self.load() 

1652 if mask: 

1653 mask.load() 

1654 return self.im.entropy((0, 0), mask.im) 

1655 if self.mode in ("I", "F"): 

1656 if extrema is None: 

1657 extrema = self.getextrema() 

1658 return self.im.entropy(extrema) 

1659 return self.im.entropy() 

1660 

1661 def paste(self, im, box=None, mask=None) -> None: 

1662 """ 

1663 Pastes another image into this image. The box argument is either 

1664 a 2-tuple giving the upper left corner, a 4-tuple defining the 

1665 left, upper, right, and lower pixel coordinate, or None (same as 

1666 (0, 0)). See :ref:`coordinate-system`. If a 4-tuple is given, the size 

1667 of the pasted image must match the size of the region. 

1668 

1669 If the modes don't match, the pasted image is converted to the mode of 

1670 this image (see the :py:meth:`~PIL.Image.Image.convert` method for 

1671 details). 

1672 

1673 Instead of an image, the source can be a integer or tuple 

1674 containing pixel values. The method then fills the region 

1675 with the given color. When creating RGB images, you can 

1676 also use color strings as supported by the ImageColor module. 

1677 

1678 If a mask is given, this method updates only the regions 

1679 indicated by the mask. You can use either "1", "L", "LA", "RGBA" 

1680 or "RGBa" images (if present, the alpha band is used as mask). 

1681 Where the mask is 255, the given image is copied as is. Where 

1682 the mask is 0, the current value is preserved. Intermediate 

1683 values will mix the two images together, including their alpha 

1684 channels if they have them. 

1685 

1686 See :py:meth:`~PIL.Image.Image.alpha_composite` if you want to 

1687 combine images with respect to their alpha channels. 

1688 

1689 :param im: Source image or pixel value (integer or tuple). 

1690 :param box: An optional 4-tuple giving the region to paste into. 

1691 If a 2-tuple is used instead, it's treated as the upper left 

1692 corner. If omitted or None, the source is pasted into the 

1693 upper left corner. 

1694 

1695 If an image is given as the second argument and there is no 

1696 third, the box defaults to (0, 0), and the second argument 

1697 is interpreted as a mask image. 

1698 :param mask: An optional mask image. 

1699 """ 

1700 

1701 if isImageType(box) and mask is None: 

1702 # abbreviated paste(im, mask) syntax 

1703 mask = box 

1704 box = None 

1705 

1706 if box is None: 

1707 box = (0, 0) 

1708 

1709 if len(box) == 2: 

1710 # upper left corner given; get size from image or mask 

1711 if isImageType(im): 

1712 size = im.size 

1713 elif isImageType(mask): 

1714 size = mask.size 

1715 else: 

1716 # FIXME: use self.size here? 

1717 msg = "cannot determine region size; use 4-item box" 

1718 raise ValueError(msg) 

1719 box += (box[0] + size[0], box[1] + size[1]) 

1720 

1721 if isinstance(im, str): 

1722 from . import ImageColor 

1723 

1724 im = ImageColor.getcolor(im, self.mode) 

1725 

1726 elif isImageType(im): 

1727 im.load() 

1728 if self.mode != im.mode: 

1729 if self.mode != "RGB" or im.mode not in ("LA", "RGBA", "RGBa"): 

1730 # should use an adapter for this! 

1731 im = im.convert(self.mode) 

1732 im = im.im 

1733 

1734 self._ensure_mutable() 

1735 

1736 if mask: 

1737 mask.load() 

1738 self.im.paste(im, box, mask.im) 

1739 else: 

1740 self.im.paste(im, box) 

1741 

1742 def alpha_composite(self, im, dest=(0, 0), source=(0, 0)): 

1743 """'In-place' analog of Image.alpha_composite. Composites an image 

1744 onto this image. 

1745 

1746 :param im: image to composite over this one 

1747 :param dest: Optional 2 tuple (left, top) specifying the upper 

1748 left corner in this (destination) image. 

1749 :param source: Optional 2 (left, top) tuple for the upper left 

1750 corner in the overlay source image, or 4 tuple (left, top, right, 

1751 bottom) for the bounds of the source rectangle 

1752 

1753 Performance Note: Not currently implemented in-place in the core layer. 

1754 """ 

1755 

1756 if not isinstance(source, (list, tuple)): 

1757 msg = "Source must be a tuple" 

1758 raise ValueError(msg) 

1759 if not isinstance(dest, (list, tuple)): 

1760 msg = "Destination must be a tuple" 

1761 raise ValueError(msg) 

1762 if len(source) not in (2, 4): 

1763 msg = "Source must be a 2 or 4-tuple" 

1764 raise ValueError(msg) 

1765 if not len(dest) == 2: 

1766 msg = "Destination must be a 2-tuple" 

1767 raise ValueError(msg) 

1768 if min(source) < 0: 

1769 msg = "Source must be non-negative" 

1770 raise ValueError(msg) 

1771 

1772 if len(source) == 2: 

1773 source = source + im.size 

1774 

1775 # over image, crop if it's not the whole thing. 

1776 if source == (0, 0) + im.size: 

1777 overlay = im 

1778 else: 

1779 overlay = im.crop(source) 

1780 

1781 # target for the paste 

1782 box = dest + (dest[0] + overlay.width, dest[1] + overlay.height) 

1783 

1784 # destination image. don't copy if we're using the whole image. 

1785 if box == (0, 0) + self.size: 

1786 background = self 

1787 else: 

1788 background = self.crop(box) 

1789 

1790 result = alpha_composite(background, overlay) 

1791 self.paste(result, box) 

1792 

1793 def point(self, lut, mode=None): 

1794 """ 

1795 Maps this image through a lookup table or function. 

1796 

1797 :param lut: A lookup table, containing 256 (or 65536 if 

1798 self.mode=="I" and mode == "L") values per band in the 

1799 image. A function can be used instead, it should take a 

1800 single argument. The function is called once for each 

1801 possible pixel value, and the resulting table is applied to 

1802 all bands of the image. 

1803 

1804 It may also be an :py:class:`~PIL.Image.ImagePointHandler` 

1805 object:: 

1806 

1807 class Example(Image.ImagePointHandler): 

1808 def point(self, data): 

1809 # Return result 

1810 :param mode: Output mode (default is same as input). In the 

1811 current version, this can only be used if the source image 

1812 has mode "L" or "P", and the output has mode "1" or the 

1813 source image mode is "I" and the output mode is "L". 

1814 :returns: An :py:class:`~PIL.Image.Image` object. 

1815 """ 

1816 

1817 self.load() 

1818 

1819 if isinstance(lut, ImagePointHandler): 

1820 return lut.point(self) 

1821 

1822 if callable(lut): 

1823 # if it isn't a list, it should be a function 

1824 if self.mode in ("I", "I;16", "F"): 

1825 # check if the function can be used with point_transform 

1826 # UNDONE wiredfool -- I think this prevents us from ever doing 

1827 # a gamma function point transform on > 8bit images. 

1828 scale, offset = _getscaleoffset(lut) 

1829 return self._new(self.im.point_transform(scale, offset)) 

1830 # for other modes, convert the function to a table 

1831 lut = [lut(i) for i in range(256)] * self.im.bands 

1832 

1833 if self.mode == "F": 

1834 # FIXME: _imaging returns a confusing error message for this case 

1835 msg = "point operation not supported for this mode" 

1836 raise ValueError(msg) 

1837 

1838 if mode != "F": 

1839 lut = [round(i) for i in lut] 

1840 return self._new(self.im.point(lut, mode)) 

1841 

1842 def putalpha(self, alpha): 

1843 """ 

1844 Adds or replaces the alpha layer in this image. If the image 

1845 does not have an alpha layer, it's converted to "LA" or "RGBA". 

1846 The new layer must be either "L" or "1". 

1847 

1848 :param alpha: The new alpha layer. This can either be an "L" or "1" 

1849 image having the same size as this image, or an integer or 

1850 other color value. 

1851 """ 

1852 

1853 self._ensure_mutable() 

1854 

1855 if self.mode not in ("LA", "PA", "RGBA"): 

1856 # attempt to promote self to a matching alpha mode 

1857 try: 

1858 mode = getmodebase(self.mode) + "A" 

1859 try: 

1860 self.im.setmode(mode) 

1861 except (AttributeError, ValueError) as e: 

1862 # do things the hard way 

1863 im = self.im.convert(mode) 

1864 if im.mode not in ("LA", "PA", "RGBA"): 

1865 msg = "alpha channel could not be added" 

1866 raise ValueError(msg) from e # sanity check 

1867 self.im = im 

1868 self.pyaccess = None 

1869 self._mode = self.im.mode 

1870 except KeyError as e: 

1871 msg = "illegal image mode" 

1872 raise ValueError(msg) from e 

1873 

1874 if self.mode in ("LA", "PA"): 

1875 band = 1 

1876 else: 

1877 band = 3 

1878 

1879 if isImageType(alpha): 

1880 # alpha layer 

1881 if alpha.mode not in ("1", "L"): 

1882 msg = "illegal image mode" 

1883 raise ValueError(msg) 

1884 alpha.load() 

1885 if alpha.mode == "1": 

1886 alpha = alpha.convert("L") 

1887 else: 

1888 # constant alpha 

1889 try: 

1890 self.im.fillband(band, alpha) 

1891 except (AttributeError, ValueError): 

1892 # do things the hard way 

1893 alpha = new("L", self.size, alpha) 

1894 else: 

1895 return 

1896 

1897 self.im.putband(alpha.im, band) 

1898 

1899 def putdata(self, data, scale=1.0, offset=0.0): 

1900 """ 

1901 Copies pixel data from a flattened sequence object into the image. The 

1902 values should start at the upper left corner (0, 0), continue to the 

1903 end of the line, followed directly by the first value of the second 

1904 line, and so on. Data will be read until either the image or the 

1905 sequence ends. The scale and offset values are used to adjust the 

1906 sequence values: **pixel = value*scale + offset**. 

1907 

1908 :param data: A flattened sequence object. 

1909 :param scale: An optional scale value. The default is 1.0. 

1910 :param offset: An optional offset value. The default is 0.0. 

1911 """ 

1912 

1913 self._ensure_mutable() 

1914 

1915 self.im.putdata(data, scale, offset) 

1916 

1917 def putpalette(self, data, rawmode="RGB"): 

1918 """ 

1919 Attaches a palette to this image. The image must be a "P", "PA", "L" 

1920 or "LA" image. 

1921 

1922 The palette sequence must contain at most 256 colors, made up of one 

1923 integer value for each channel in the raw mode. 

1924 For example, if the raw mode is "RGB", then it can contain at most 768 

1925 values, made up of red, green and blue values for the corresponding pixel 

1926 index in the 256 colors. 

1927 If the raw mode is "RGBA", then it can contain at most 1024 values, 

1928 containing red, green, blue and alpha values. 

1929 

1930 Alternatively, an 8-bit string may be used instead of an integer sequence. 

1931 

1932 :param data: A palette sequence (either a list or a string). 

1933 :param rawmode: The raw mode of the palette. Either "RGB", "RGBA", or a mode 

1934 that can be transformed to "RGB" or "RGBA" (e.g. "R", "BGR;15", "RGBA;L"). 

1935 """ 

1936 from . import ImagePalette 

1937 

1938 if self.mode not in ("L", "LA", "P", "PA"): 

1939 msg = "illegal image mode" 

1940 raise ValueError(msg) 

1941 if isinstance(data, ImagePalette.ImagePalette): 

1942 palette = ImagePalette.raw(data.rawmode, data.palette) 

1943 else: 

1944 if not isinstance(data, bytes): 

1945 data = bytes(data) 

1946 palette = ImagePalette.raw(rawmode, data) 

1947 self._mode = "PA" if "A" in self.mode else "P" 

1948 self.palette = palette 

1949 self.palette.mode = "RGB" 

1950 self.load() # install new palette 

1951 

1952 def putpixel(self, xy, value): 

1953 """ 

1954 Modifies the pixel at the given position. The color is given as 

1955 a single numerical value for single-band images, and a tuple for 

1956 multi-band images. In addition to this, RGB and RGBA tuples are 

1957 accepted for P and PA images. 

1958 

1959 Note that this method is relatively slow. For more extensive changes, 

1960 use :py:meth:`~PIL.Image.Image.paste` or the :py:mod:`~PIL.ImageDraw` 

1961 module instead. 

1962 

1963 See: 

1964 

1965 * :py:meth:`~PIL.Image.Image.paste` 

1966 * :py:meth:`~PIL.Image.Image.putdata` 

1967 * :py:mod:`~PIL.ImageDraw` 

1968 

1969 :param xy: The pixel coordinate, given as (x, y). See 

1970 :ref:`coordinate-system`. 

1971 :param value: The pixel value. 

1972 """ 

1973 

1974 if self.readonly: 

1975 self._copy() 

1976 self.load() 

1977 

1978 if self.pyaccess: 

1979 return self.pyaccess.putpixel(xy, value) 

1980 

1981 if ( 

1982 self.mode in ("P", "PA") 

1983 and isinstance(value, (list, tuple)) 

1984 and len(value) in [3, 4] 

1985 ): 

1986 # RGB or RGBA value for a P or PA image 

1987 if self.mode == "PA": 

1988 alpha = value[3] if len(value) == 4 else 255 

1989 value = value[:3] 

1990 value = self.palette.getcolor(value, self) 

1991 if self.mode == "PA": 

1992 value = (value, alpha) 

1993 return self.im.putpixel(xy, value) 

1994 

1995 def remap_palette(self, dest_map, source_palette=None): 

1996 """ 

1997 Rewrites the image to reorder the palette. 

1998 

1999 :param dest_map: A list of indexes into the original palette. 

2000 e.g. ``[1,0]`` would swap a two item palette, and ``list(range(256))`` 

2001 is the identity transform. 

2002 :param source_palette: Bytes or None. 

2003 :returns: An :py:class:`~PIL.Image.Image` object. 

2004 

2005 """ 

2006 from . import ImagePalette 

2007 

2008 if self.mode not in ("L", "P"): 

2009 msg = "illegal image mode" 

2010 raise ValueError(msg) 

2011 

2012 bands = 3 

2013 palette_mode = "RGB" 

2014 if source_palette is None: 

2015 if self.mode == "P": 

2016 self.load() 

2017 palette_mode = self.im.getpalettemode() 

2018 if palette_mode == "RGBA": 

2019 bands = 4 

2020 source_palette = self.im.getpalette(palette_mode, palette_mode) 

2021 else: # L-mode 

2022 source_palette = bytearray(i // 3 for i in range(768)) 

2023 

2024 palette_bytes = b"" 

2025 new_positions = [0] * 256 

2026 

2027 # pick only the used colors from the palette 

2028 for i, oldPosition in enumerate(dest_map): 

2029 palette_bytes += source_palette[ 

2030 oldPosition * bands : oldPosition * bands + bands 

2031 ] 

2032 new_positions[oldPosition] = i 

2033 

2034 # replace the palette color id of all pixel with the new id 

2035 

2036 # Palette images are [0..255], mapped through a 1 or 3 

2037 # byte/color map. We need to remap the whole image 

2038 # from palette 1 to palette 2. New_positions is 

2039 # an array of indexes into palette 1. Palette 2 is 

2040 # palette 1 with any holes removed. 

2041 

2042 # We're going to leverage the convert mechanism to use the 

2043 # C code to remap the image from palette 1 to palette 2, 

2044 # by forcing the source image into 'L' mode and adding a 

2045 # mapping 'L' mode palette, then converting back to 'L' 

2046 # sans palette thus converting the image bytes, then 

2047 # assigning the optimized RGB palette. 

2048 

2049 # perf reference, 9500x4000 gif, w/~135 colors 

2050 # 14 sec prepatch, 1 sec postpatch with optimization forced. 

2051 

2052 mapping_palette = bytearray(new_positions) 

2053 

2054 m_im = self.copy() 

2055 m_im._mode = "P" 

2056 

2057 m_im.palette = ImagePalette.ImagePalette( 

2058 palette_mode, palette=mapping_palette * bands 

2059 ) 

2060 # possibly set palette dirty, then 

2061 # m_im.putpalette(mapping_palette, 'L') # converts to 'P' 

2062 # or just force it. 

2063 # UNDONE -- this is part of the general issue with palettes 

2064 m_im.im.putpalette(palette_mode + ";L", m_im.palette.tobytes()) 

2065 

2066 m_im = m_im.convert("L") 

2067 

2068 m_im.putpalette(palette_bytes, palette_mode) 

2069 m_im.palette = ImagePalette.ImagePalette(palette_mode, palette=palette_bytes) 

2070 

2071 if "transparency" in self.info: 

2072 try: 

2073 m_im.info["transparency"] = dest_map.index(self.info["transparency"]) 

2074 except ValueError: 

2075 if "transparency" in m_im.info: 

2076 del m_im.info["transparency"] 

2077 

2078 return m_im 

2079 

2080 def _get_safe_box(self, size, resample, box): 

2081 """Expands the box so it includes adjacent pixels 

2082 that may be used by resampling with the given resampling filter. 

2083 """ 

2084 filter_support = _filters_support[resample] - 0.5 

2085 scale_x = (box[2] - box[0]) / size[0] 

2086 scale_y = (box[3] - box[1]) / size[1] 

2087 support_x = filter_support * scale_x 

2088 support_y = filter_support * scale_y 

2089 

2090 return ( 

2091 max(0, int(box[0] - support_x)), 

2092 max(0, int(box[1] - support_y)), 

2093 min(self.size[0], math.ceil(box[2] + support_x)), 

2094 min(self.size[1], math.ceil(box[3] + support_y)), 

2095 ) 

2096 

2097 def resize(self, size, resample=None, box=None, reducing_gap=None): 

2098 """ 

2099 Returns a resized copy of this image. 

2100 

2101 :param size: The requested size in pixels, as a 2-tuple: 

2102 (width, height). 

2103 :param resample: An optional resampling filter. This can be 

2104 one of :py:data:`Resampling.NEAREST`, :py:data:`Resampling.BOX`, 

2105 :py:data:`Resampling.BILINEAR`, :py:data:`Resampling.HAMMING`, 

2106 :py:data:`Resampling.BICUBIC` or :py:data:`Resampling.LANCZOS`. 

2107 If the image has mode "1" or "P", it is always set to 

2108 :py:data:`Resampling.NEAREST`. If the image mode specifies a number 

2109 of bits, such as "I;16", then the default filter is 

2110 :py:data:`Resampling.NEAREST`. Otherwise, the default filter is 

2111 :py:data:`Resampling.BICUBIC`. See: :ref:`concept-filters`. 

2112 :param box: An optional 4-tuple of floats providing 

2113 the source image region to be scaled. 

2114 The values must be within (0, 0, width, height) rectangle. 

2115 If omitted or None, the entire source is used. 

2116 :param reducing_gap: Apply optimization by resizing the image 

2117 in two steps. First, reducing the image by integer times 

2118 using :py:meth:`~PIL.Image.Image.reduce`. 

2119 Second, resizing using regular resampling. The last step 

2120 changes size no less than by ``reducing_gap`` times. 

2121 ``reducing_gap`` may be None (no first step is performed) 

2122 or should be greater than 1.0. The bigger ``reducing_gap``, 

2123 the closer the result to the fair resampling. 

2124 The smaller ``reducing_gap``, the faster resizing. 

2125 With ``reducing_gap`` greater or equal to 3.0, the result is 

2126 indistinguishable from fair resampling in most cases. 

2127 The default value is None (no optimization). 

2128 :returns: An :py:class:`~PIL.Image.Image` object. 

2129 """ 

2130 

2131 if resample is None: 

2132 type_special = ";" in self.mode 

2133 resample = Resampling.NEAREST if type_special else Resampling.BICUBIC 

2134 elif resample not in ( 

2135 Resampling.NEAREST, 

2136 Resampling.BILINEAR, 

2137 Resampling.BICUBIC, 

2138 Resampling.LANCZOS, 

2139 Resampling.BOX, 

2140 Resampling.HAMMING, 

2141 ): 

2142 msg = f"Unknown resampling filter ({resample})." 

2143 

2144 filters = [ 

2145 f"{filter[1]} ({filter[0]})" 

2146 for filter in ( 

2147 (Resampling.NEAREST, "Image.Resampling.NEAREST"), 

2148 (Resampling.LANCZOS, "Image.Resampling.LANCZOS"), 

2149 (Resampling.BILINEAR, "Image.Resampling.BILINEAR"), 

2150 (Resampling.BICUBIC, "Image.Resampling.BICUBIC"), 

2151 (Resampling.BOX, "Image.Resampling.BOX"), 

2152 (Resampling.HAMMING, "Image.Resampling.HAMMING"), 

2153 ) 

2154 ] 

2155 msg += " Use " + ", ".join(filters[:-1]) + " or " + filters[-1] 

2156 raise ValueError(msg) 

2157 

2158 if reducing_gap is not None and reducing_gap < 1.0: 

2159 msg = "reducing_gap must be 1.0 or greater" 

2160 raise ValueError(msg) 

2161 

2162 size = tuple(size) 

2163 

2164 self.load() 

2165 if box is None: 

2166 box = (0, 0) + self.size 

2167 else: 

2168 box = tuple(box) 

2169 

2170 if self.size == size and box == (0, 0) + self.size: 

2171 return self.copy() 

2172 

2173 if self.mode in ("1", "P"): 

2174 resample = Resampling.NEAREST 

2175 

2176 if self.mode in ["LA", "RGBA"] and resample != Resampling.NEAREST: 

2177 im = self.convert({"LA": "La", "RGBA": "RGBa"}[self.mode]) 

2178 im = im.resize(size, resample, box) 

2179 return im.convert(self.mode) 

2180 

2181 self.load() 

2182 

2183 if reducing_gap is not None and resample != Resampling.NEAREST: 

2184 factor_x = int((box[2] - box[0]) / size[0] / reducing_gap) or 1 

2185 factor_y = int((box[3] - box[1]) / size[1] / reducing_gap) or 1 

2186 if factor_x > 1 or factor_y > 1: 

2187 reduce_box = self._get_safe_box(size, resample, box) 

2188 factor = (factor_x, factor_y) 

2189 if callable(self.reduce): 

2190 self = self.reduce(factor, box=reduce_box) 

2191 else: 

2192 self = Image.reduce(self, factor, box=reduce_box) 

2193 box = ( 

2194 (box[0] - reduce_box[0]) / factor_x, 

2195 (box[1] - reduce_box[1]) / factor_y, 

2196 (box[2] - reduce_box[0]) / factor_x, 

2197 (box[3] - reduce_box[1]) / factor_y, 

2198 ) 

2199 

2200 return self._new(self.im.resize(size, resample, box)) 

2201 

2202 def reduce(self, factor, box=None): 

2203 """ 

2204 Returns a copy of the image reduced ``factor`` times. 

2205 If the size of the image is not dividable by ``factor``, 

2206 the resulting size will be rounded up. 

2207 

2208 :param factor: A greater than 0 integer or tuple of two integers 

2209 for width and height separately. 

2210 :param box: An optional 4-tuple of ints providing 

2211 the source image region to be reduced. 

2212 The values must be within ``(0, 0, width, height)`` rectangle. 

2213 If omitted or ``None``, the entire source is used. 

2214 """ 

2215 if not isinstance(factor, (list, tuple)): 

2216 factor = (factor, factor) 

2217 

2218 if box is None: 

2219 box = (0, 0) + self.size 

2220 else: 

2221 box = tuple(box) 

2222 

2223 if factor == (1, 1) and box == (0, 0) + self.size: 

2224 return self.copy() 

2225 

2226 if self.mode in ["LA", "RGBA"]: 

2227 im = self.convert({"LA": "La", "RGBA": "RGBa"}[self.mode]) 

2228 im = im.reduce(factor, box) 

2229 return im.convert(self.mode) 

2230 

2231 self.load() 

2232 

2233 return self._new(self.im.reduce(factor, box)) 

2234 

2235 def rotate( 

2236 self, 

2237 angle, 

2238 resample=Resampling.NEAREST, 

2239 expand=0, 

2240 center=None, 

2241 translate=None, 

2242 fillcolor=None, 

2243 ): 

2244 """ 

2245 Returns a rotated copy of this image. This method returns a 

2246 copy of this image, rotated the given number of degrees counter 

2247 clockwise around its centre. 

2248 

2249 :param angle: In degrees counter clockwise. 

2250 :param resample: An optional resampling filter. This can be 

2251 one of :py:data:`Resampling.NEAREST` (use nearest neighbour), 

2252 :py:data:`Resampling.BILINEAR` (linear interpolation in a 2x2 

2253 environment), or :py:data:`Resampling.BICUBIC` (cubic spline 

2254 interpolation in a 4x4 environment). If omitted, or if the image has 

2255 mode "1" or "P", it is set to :py:data:`Resampling.NEAREST`. 

2256 See :ref:`concept-filters`. 

2257 :param expand: Optional expansion flag. If true, expands the output 

2258 image to make it large enough to hold the entire rotated image. 

2259 If false or omitted, make the output image the same size as the 

2260 input image. Note that the expand flag assumes rotation around 

2261 the center and no translation. 

2262 :param center: Optional center of rotation (a 2-tuple). Origin is 

2263 the upper left corner. Default is the center of the image. 

2264 :param translate: An optional post-rotate translation (a 2-tuple). 

2265 :param fillcolor: An optional color for area outside the rotated image. 

2266 :returns: An :py:class:`~PIL.Image.Image` object. 

2267 """ 

2268 

2269 angle = angle % 360.0 

2270 

2271 # Fast paths regardless of filter, as long as we're not 

2272 # translating or changing the center. 

2273 if not (center or translate): 

2274 if angle == 0: 

2275 return self.copy() 

2276 if angle == 180: 

2277 return self.transpose(Transpose.ROTATE_180) 

2278 if angle in (90, 270) and (expand or self.width == self.height): 

2279 return self.transpose( 

2280 Transpose.ROTATE_90 if angle == 90 else Transpose.ROTATE_270 

2281 ) 

2282 

2283 # Calculate the affine matrix. Note that this is the reverse 

2284 # transformation (from destination image to source) because we 

2285 # want to interpolate the (discrete) destination pixel from 

2286 # the local area around the (floating) source pixel. 

2287 

2288 # The matrix we actually want (note that it operates from the right): 

2289 # (1, 0, tx) (1, 0, cx) ( cos a, sin a, 0) (1, 0, -cx) 

2290 # (0, 1, ty) * (0, 1, cy) * (-sin a, cos a, 0) * (0, 1, -cy) 

2291 # (0, 0, 1) (0, 0, 1) ( 0, 0, 1) (0, 0, 1) 

2292 

2293 # The reverse matrix is thus: 

2294 # (1, 0, cx) ( cos -a, sin -a, 0) (1, 0, -cx) (1, 0, -tx) 

2295 # (0, 1, cy) * (-sin -a, cos -a, 0) * (0, 1, -cy) * (0, 1, -ty) 

2296 # (0, 0, 1) ( 0, 0, 1) (0, 0, 1) (0, 0, 1) 

2297 

2298 # In any case, the final translation may be updated at the end to 

2299 # compensate for the expand flag. 

2300 

2301 w, h = self.size 

2302 

2303 if translate is None: 

2304 post_trans = (0, 0) 

2305 else: 

2306 post_trans = translate 

2307 if center is None: 

2308 # FIXME These should be rounded to ints? 

2309 rotn_center = (w / 2.0, h / 2.0) 

2310 else: 

2311 rotn_center = center 

2312 

2313 angle = -math.radians(angle) 

2314 matrix = [ 

2315 round(math.cos(angle), 15), 

2316 round(math.sin(angle), 15), 

2317 0.0, 

2318 round(-math.sin(angle), 15), 

2319 round(math.cos(angle), 15), 

2320 0.0, 

2321 ] 

2322 

2323 def transform(x, y, matrix): 

2324 (a, b, c, d, e, f) = matrix 

2325 return a * x + b * y + c, d * x + e * y + f 

2326 

2327 matrix[2], matrix[5] = transform( 

2328 -rotn_center[0] - post_trans[0], -rotn_center[1] - post_trans[1], matrix 

2329 ) 

2330 matrix[2] += rotn_center[0] 

2331 matrix[5] += rotn_center[1] 

2332 

2333 if expand: 

2334 # calculate output size 

2335 xx = [] 

2336 yy = [] 

2337 for x, y in ((0, 0), (w, 0), (w, h), (0, h)): 

2338 x, y = transform(x, y, matrix) 

2339 xx.append(x) 

2340 yy.append(y) 

2341 nw = math.ceil(max(xx)) - math.floor(min(xx)) 

2342 nh = math.ceil(max(yy)) - math.floor(min(yy)) 

2343 

2344 # We multiply a translation matrix from the right. Because of its 

2345 # special form, this is the same as taking the image of the 

2346 # translation vector as new translation vector. 

2347 matrix[2], matrix[5] = transform(-(nw - w) / 2.0, -(nh - h) / 2.0, matrix) 

2348 w, h = nw, nh 

2349 

2350 return self.transform( 

2351 (w, h), Transform.AFFINE, matrix, resample, fillcolor=fillcolor 

2352 ) 

2353 

2354 def save(self, fp, format=None, **params) -> None: 

2355 """ 

2356 Saves this image under the given filename. If no format is 

2357 specified, the format to use is determined from the filename 

2358 extension, if possible. 

2359 

2360 Keyword options can be used to provide additional instructions 

2361 to the writer. If a writer doesn't recognise an option, it is 

2362 silently ignored. The available options are described in the 

2363 :doc:`image format documentation 

2364 <../handbook/image-file-formats>` for each writer. 

2365 

2366 You can use a file object instead of a filename. In this case, 

2367 you must always specify the format. The file object must 

2368 implement the ``seek``, ``tell``, and ``write`` 

2369 methods, and be opened in binary mode. 

2370 

2371 :param fp: A filename (string), pathlib.Path object or file object. 

2372 :param format: Optional format override. If omitted, the 

2373 format to use is determined from the filename extension. 

2374 If a file object was used instead of a filename, this 

2375 parameter should always be used. 

2376 :param params: Extra parameters to the image writer. 

2377 :returns: None 

2378 :exception ValueError: If the output format could not be determined 

2379 from the file name. Use the format option to solve this. 

2380 :exception OSError: If the file could not be written. The file 

2381 may have been created, and may contain partial data. 

2382 """ 

2383 

2384 filename = "" 

2385 open_fp = False 

2386 if isinstance(fp, Path): 

2387 filename = str(fp) 

2388 open_fp = True 

2389 elif is_path(fp): 

2390 filename = fp 

2391 open_fp = True 

2392 elif fp == sys.stdout: 

2393 try: 

2394 fp = sys.stdout.buffer 

2395 except AttributeError: 

2396 pass 

2397 if not filename and hasattr(fp, "name") and is_path(fp.name): 

2398 # only set the name for metadata purposes 

2399 filename = fp.name 

2400 

2401 # may mutate self! 

2402 self._ensure_mutable() 

2403 

2404 save_all = params.pop("save_all", False) 

2405 self.encoderinfo = params 

2406 self.encoderconfig = () 

2407 

2408 preinit() 

2409 

2410 ext = os.path.splitext(filename)[1].lower() 

2411 

2412 if not format: 

2413 if ext not in EXTENSION: 

2414 init() 

2415 try: 

2416 format = EXTENSION[ext] 

2417 except KeyError as e: 

2418 msg = f"unknown file extension: {ext}" 

2419 raise ValueError(msg) from e 

2420 

2421 if format.upper() not in SAVE: 

2422 init() 

2423 if save_all: 

2424 save_handler = SAVE_ALL[format.upper()] 

2425 else: 

2426 save_handler = SAVE[format.upper()] 

2427 

2428 created = False 

2429 if open_fp: 

2430 created = not os.path.exists(filename) 

2431 if params.get("append", False): 

2432 # Open also for reading ("+"), because TIFF save_all 

2433 # writer needs to go back and edit the written data. 

2434 fp = builtins.open(filename, "r+b") 

2435 else: 

2436 fp = builtins.open(filename, "w+b") 

2437 

2438 try: 

2439 save_handler(self, fp, filename) 

2440 except Exception: 

2441 if open_fp: 

2442 fp.close() 

2443 if created: 

2444 try: 

2445 os.remove(filename) 

2446 except PermissionError: 

2447 pass 

2448 raise 

2449 if open_fp: 

2450 fp.close() 

2451 

2452 def seek(self, frame) -> Image: 

2453 """ 

2454 Seeks to the given frame in this sequence file. If you seek 

2455 beyond the end of the sequence, the method raises an 

2456 ``EOFError`` exception. When a sequence file is opened, the 

2457 library automatically seeks to frame 0. 

2458 

2459 See :py:meth:`~PIL.Image.Image.tell`. 

2460 

2461 If defined, :attr:`~PIL.Image.Image.n_frames` refers to the 

2462 number of available frames. 

2463 

2464 :param frame: Frame number, starting at 0. 

2465 :exception EOFError: If the call attempts to seek beyond the end 

2466 of the sequence. 

2467 """ 

2468 

2469 # overridden by file handlers 

2470 if frame != 0: 

2471 msg = "no more images in file" 

2472 raise EOFError(msg) 

2473 

2474 def show(self, title=None): 

2475 """ 

2476 Displays this image. This method is mainly intended for debugging purposes. 

2477 

2478 This method calls :py:func:`PIL.ImageShow.show` internally. You can use 

2479 :py:func:`PIL.ImageShow.register` to override its default behaviour. 

2480 

2481 The image is first saved to a temporary file. By default, it will be in 

2482 PNG format. 

2483 

2484 On Unix, the image is then opened using the **xdg-open**, **display**, 

2485 **gm**, **eog** or **xv** utility, depending on which one can be found. 

2486 

2487 On macOS, the image is opened with the native Preview application. 

2488 

2489 On Windows, the image is opened with the standard PNG display utility. 

2490 

2491 :param title: Optional title to use for the image window, where possible. 

2492 """ 

2493 

2494 _show(self, title=title) 

2495 

2496 def split(self): 

2497 """ 

2498 Split this image into individual bands. This method returns a 

2499 tuple of individual image bands from an image. For example, 

2500 splitting an "RGB" image creates three new images each 

2501 containing a copy of one of the original bands (red, green, 

2502 blue). 

2503 

2504 If you need only one band, :py:meth:`~PIL.Image.Image.getchannel` 

2505 method can be more convenient and faster. 

2506 

2507 :returns: A tuple containing bands. 

2508 """ 

2509 

2510 self.load() 

2511 if self.im.bands == 1: 

2512 ims = [self.copy()] 

2513 else: 

2514 ims = map(self._new, self.im.split()) 

2515 return tuple(ims) 

2516 

2517 def getchannel(self, channel): 

2518 """ 

2519 Returns an image containing a single channel of the source image. 

2520 

2521 :param channel: What channel to return. Could be index 

2522 (0 for "R" channel of "RGB") or channel name 

2523 ("A" for alpha channel of "RGBA"). 

2524 :returns: An image in "L" mode. 

2525 

2526 .. versionadded:: 4.3.0 

2527 """ 

2528 self.load() 

2529 

2530 if isinstance(channel, str): 

2531 try: 

2532 channel = self.getbands().index(channel) 

2533 except ValueError as e: 

2534 msg = f'The image has no channel "{channel}"' 

2535 raise ValueError(msg) from e 

2536 

2537 return self._new(self.im.getband(channel)) 

2538 

2539 def tell(self) -> int: 

2540 """ 

2541 Returns the current frame number. See :py:meth:`~PIL.Image.Image.seek`. 

2542 

2543 If defined, :attr:`~PIL.Image.Image.n_frames` refers to the 

2544 number of available frames. 

2545 

2546 :returns: Frame number, starting with 0. 

2547 """ 

2548 return 0 

2549 

2550 def thumbnail(self, size, resample=Resampling.BICUBIC, reducing_gap=2.0): 

2551 """ 

2552 Make this image into a thumbnail. This method modifies the 

2553 image to contain a thumbnail version of itself, no larger than 

2554 the given size. This method calculates an appropriate thumbnail 

2555 size to preserve the aspect of the image, calls the 

2556 :py:meth:`~PIL.Image.Image.draft` method to configure the file reader 

2557 (where applicable), and finally resizes the image. 

2558 

2559 Note that this function modifies the :py:class:`~PIL.Image.Image` 

2560 object in place. If you need to use the full resolution image as well, 

2561 apply this method to a :py:meth:`~PIL.Image.Image.copy` of the original 

2562 image. 

2563 

2564 :param size: The requested size in pixels, as a 2-tuple: 

2565 (width, height). 

2566 :param resample: Optional resampling filter. This can be one 

2567 of :py:data:`Resampling.NEAREST`, :py:data:`Resampling.BOX`, 

2568 :py:data:`Resampling.BILINEAR`, :py:data:`Resampling.HAMMING`, 

2569 :py:data:`Resampling.BICUBIC` or :py:data:`Resampling.LANCZOS`. 

2570 If omitted, it defaults to :py:data:`Resampling.BICUBIC`. 

2571 (was :py:data:`Resampling.NEAREST` prior to version 2.5.0). 

2572 See: :ref:`concept-filters`. 

2573 :param reducing_gap: Apply optimization by resizing the image 

2574 in two steps. First, reducing the image by integer times 

2575 using :py:meth:`~PIL.Image.Image.reduce` or 

2576 :py:meth:`~PIL.Image.Image.draft` for JPEG images. 

2577 Second, resizing using regular resampling. The last step 

2578 changes size no less than by ``reducing_gap`` times. 

2579 ``reducing_gap`` may be None (no first step is performed) 

2580 or should be greater than 1.0. The bigger ``reducing_gap``, 

2581 the closer the result to the fair resampling. 

2582 The smaller ``reducing_gap``, the faster resizing. 

2583 With ``reducing_gap`` greater or equal to 3.0, the result is 

2584 indistinguishable from fair resampling in most cases. 

2585 The default value is 2.0 (very close to fair resampling 

2586 while still being faster in many cases). 

2587 :returns: None 

2588 """ 

2589 

2590 provided_size = tuple(map(math.floor, size)) 

2591 

2592 def preserve_aspect_ratio(): 

2593 def round_aspect(number, key): 

2594 return max(min(math.floor(number), math.ceil(number), key=key), 1) 

2595 

2596 x, y = provided_size 

2597 if x >= self.width and y >= self.height: 

2598 return 

2599 

2600 aspect = self.width / self.height 

2601 if x / y >= aspect: 

2602 x = round_aspect(y * aspect, key=lambda n: abs(aspect - n / y)) 

2603 else: 

2604 y = round_aspect( 

2605 x / aspect, key=lambda n: 0 if n == 0 else abs(aspect - x / n) 

2606 ) 

2607 return x, y 

2608 

2609 box = None 

2610 if reducing_gap is not None: 

2611 size = preserve_aspect_ratio() 

2612 if size is None: 

2613 return 

2614 

2615 res = self.draft(None, (size[0] * reducing_gap, size[1] * reducing_gap)) 

2616 if res is not None: 

2617 box = res[1] 

2618 if box is None: 

2619 self.load() 

2620 

2621 # load() may have changed the size of the image 

2622 size = preserve_aspect_ratio() 

2623 if size is None: 

2624 return 

2625 

2626 if self.size != size: 

2627 im = self.resize(size, resample, box=box, reducing_gap=reducing_gap) 

2628 

2629 self.im = im.im 

2630 self._size = size 

2631 self._mode = self.im.mode 

2632 

2633 self.readonly = 0 

2634 self.pyaccess = None 

2635 

2636 # FIXME: the different transform methods need further explanation 

2637 # instead of bloating the method docs, add a separate chapter. 

2638 def transform( 

2639 self, 

2640 size, 

2641 method, 

2642 data=None, 

2643 resample=Resampling.NEAREST, 

2644 fill=1, 

2645 fillcolor=None, 

2646 ) -> Image: 

2647 """ 

2648 Transforms this image. This method creates a new image with the 

2649 given size, and the same mode as the original, and copies data 

2650 to the new image using the given transform. 

2651 

2652 :param size: The output size in pixels, as a 2-tuple: 

2653 (width, height). 

2654 :param method: The transformation method. This is one of 

2655 :py:data:`Transform.EXTENT` (cut out a rectangular subregion), 

2656 :py:data:`Transform.AFFINE` (affine transform), 

2657 :py:data:`Transform.PERSPECTIVE` (perspective transform), 

2658 :py:data:`Transform.QUAD` (map a quadrilateral to a rectangle), or 

2659 :py:data:`Transform.MESH` (map a number of source quadrilaterals 

2660 in one operation). 

2661 

2662 It may also be an :py:class:`~PIL.Image.ImageTransformHandler` 

2663 object:: 

2664 

2665 class Example(Image.ImageTransformHandler): 

2666 def transform(self, size, data, resample, fill=1): 

2667 # Return result 

2668 

2669 It may also be an object with a ``method.getdata`` method 

2670 that returns a tuple supplying new ``method`` and ``data`` values:: 

2671 

2672 class Example: 

2673 def getdata(self): 

2674 method = Image.Transform.EXTENT 

2675 data = (0, 0, 100, 100) 

2676 return method, data 

2677 :param data: Extra data to the transformation method. 

2678 :param resample: Optional resampling filter. It can be one of 

2679 :py:data:`Resampling.NEAREST` (use nearest neighbour), 

2680 :py:data:`Resampling.BILINEAR` (linear interpolation in a 2x2 

2681 environment), or :py:data:`Resampling.BICUBIC` (cubic spline 

2682 interpolation in a 4x4 environment). If omitted, or if the image 

2683 has mode "1" or "P", it is set to :py:data:`Resampling.NEAREST`. 

2684 See: :ref:`concept-filters`. 

2685 :param fill: If ``method`` is an 

2686 :py:class:`~PIL.Image.ImageTransformHandler` object, this is one of 

2687 the arguments passed to it. Otherwise, it is unused. 

2688 :param fillcolor: Optional fill color for the area outside the 

2689 transform in the output image. 

2690 :returns: An :py:class:`~PIL.Image.Image` object. 

2691 """ 

2692 

2693 if self.mode in ("LA", "RGBA") and resample != Resampling.NEAREST: 

2694 return ( 

2695 self.convert({"LA": "La", "RGBA": "RGBa"}[self.mode]) 

2696 .transform(size, method, data, resample, fill, fillcolor) 

2697 .convert(self.mode) 

2698 ) 

2699 

2700 if isinstance(method, ImageTransformHandler): 

2701 return method.transform(size, self, resample=resample, fill=fill) 

2702 

2703 if hasattr(method, "getdata"): 

2704 # compatibility w. old-style transform objects 

2705 method, data = method.getdata() 

2706 

2707 if data is None: 

2708 msg = "missing method data" 

2709 raise ValueError(msg) 

2710 

2711 im = new(self.mode, size, fillcolor) 

2712 if self.mode == "P" and self.palette: 

2713 im.palette = self.palette.copy() 

2714 im.info = self.info.copy() 

2715 if method == Transform.MESH: 

2716 # list of quads 

2717 for box, quad in data: 

2718 im.__transformer( 

2719 box, self, Transform.QUAD, quad, resample, fillcolor is None 

2720 ) 

2721 else: 

2722 im.__transformer( 

2723 (0, 0) + size, self, method, data, resample, fillcolor is None 

2724 ) 

2725 

2726 return im 

2727 

2728 def __transformer( 

2729 self, box, image, method, data, resample=Resampling.NEAREST, fill=1 

2730 ): 

2731 w = box[2] - box[0] 

2732 h = box[3] - box[1] 

2733 

2734 if method == Transform.AFFINE: 

2735 data = data[:6] 

2736 

2737 elif method == Transform.EXTENT: 

2738 # convert extent to an affine transform 

2739 x0, y0, x1, y1 = data 

2740 xs = (x1 - x0) / w 

2741 ys = (y1 - y0) / h 

2742 method = Transform.AFFINE 

2743 data = (xs, 0, x0, 0, ys, y0) 

2744 

2745 elif method == Transform.PERSPECTIVE: 

2746 data = data[:8] 

2747 

2748 elif method == Transform.QUAD: 

2749 # quadrilateral warp. data specifies the four corners 

2750 # given as NW, SW, SE, and NE. 

2751 nw = data[:2] 

2752 sw = data[2:4] 

2753 se = data[4:6] 

2754 ne = data[6:8] 

2755 x0, y0 = nw 

2756 As = 1.0 / w 

2757 At = 1.0 / h 

2758 data = ( 

2759 x0, 

2760 (ne[0] - x0) * As, 

2761 (sw[0] - x0) * At, 

2762 (se[0] - sw[0] - ne[0] + x0) * As * At, 

2763 y0, 

2764 (ne[1] - y0) * As, 

2765 (sw[1] - y0) * At, 

2766 (se[1] - sw[1] - ne[1] + y0) * As * At, 

2767 ) 

2768 

2769 else: 

2770 msg = "unknown transformation method" 

2771 raise ValueError(msg) 

2772 

2773 if resample not in ( 

2774 Resampling.NEAREST, 

2775 Resampling.BILINEAR, 

2776 Resampling.BICUBIC, 

2777 ): 

2778 if resample in (Resampling.BOX, Resampling.HAMMING, Resampling.LANCZOS): 

2779 msg = { 

2780 Resampling.BOX: "Image.Resampling.BOX", 

2781 Resampling.HAMMING: "Image.Resampling.HAMMING", 

2782 Resampling.LANCZOS: "Image.Resampling.LANCZOS", 

2783 }[resample] + f" ({resample}) cannot be used." 

2784 else: 

2785 msg = f"Unknown resampling filter ({resample})." 

2786 

2787 filters = [ 

2788 f"{filter[1]} ({filter[0]})" 

2789 for filter in ( 

2790 (Resampling.NEAREST, "Image.Resampling.NEAREST"), 

2791 (Resampling.BILINEAR, "Image.Resampling.BILINEAR"), 

2792 (Resampling.BICUBIC, "Image.Resampling.BICUBIC"), 

2793 ) 

2794 ] 

2795 msg += " Use " + ", ".join(filters[:-1]) + " or " + filters[-1] 

2796 raise ValueError(msg) 

2797 

2798 image.load() 

2799 

2800 self.load() 

2801 

2802 if image.mode in ("1", "P"): 

2803 resample = Resampling.NEAREST 

2804 

2805 self.im.transform2(box, image.im, method, data, resample, fill) 

2806 

2807 def transpose(self, method): 

2808 """ 

2809 Transpose image (flip or rotate in 90 degree steps) 

2810 

2811 :param method: One of :py:data:`Transpose.FLIP_LEFT_RIGHT`, 

2812 :py:data:`Transpose.FLIP_TOP_BOTTOM`, :py:data:`Transpose.ROTATE_90`, 

2813 :py:data:`Transpose.ROTATE_180`, :py:data:`Transpose.ROTATE_270`, 

2814 :py:data:`Transpose.TRANSPOSE` or :py:data:`Transpose.TRANSVERSE`. 

2815 :returns: Returns a flipped or rotated copy of this image. 

2816 """ 

2817 

2818 self.load() 

2819 return self._new(self.im.transpose(method)) 

2820 

2821 def effect_spread(self, distance): 

2822 """ 

2823 Randomly spread pixels in an image. 

2824 

2825 :param distance: Distance to spread pixels. 

2826 """ 

2827 self.load() 

2828 return self._new(self.im.effect_spread(distance)) 

2829 

2830 def toqimage(self): 

2831 """Returns a QImage copy of this image""" 

2832 from . import ImageQt 

2833 

2834 if not ImageQt.qt_is_installed: 

2835 msg = "Qt bindings are not installed" 

2836 raise ImportError(msg) 

2837 return ImageQt.toqimage(self) 

2838 

2839 def toqpixmap(self): 

2840 """Returns a QPixmap copy of this image""" 

2841 from . import ImageQt 

2842 

2843 if not ImageQt.qt_is_installed: 

2844 msg = "Qt bindings are not installed" 

2845 raise ImportError(msg) 

2846 return ImageQt.toqpixmap(self) 

2847 

2848 

2849# -------------------------------------------------------------------- 

2850# Abstract handlers. 

2851 

2852 

2853class ImagePointHandler: 

2854 """ 

2855 Used as a mixin by point transforms 

2856 (for use with :py:meth:`~PIL.Image.Image.point`) 

2857 """ 

2858 

2859 pass 

2860 

2861 

2862class ImageTransformHandler: 

2863 """ 

2864 Used as a mixin by geometry transforms 

2865 (for use with :py:meth:`~PIL.Image.Image.transform`) 

2866 """ 

2867 

2868 pass 

2869 

2870 

2871# -------------------------------------------------------------------- 

2872# Factories 

2873 

2874# 

2875# Debugging 

2876 

2877 

2878def _wedge(): 

2879 """Create grayscale wedge (for debugging only)""" 

2880 

2881 return Image()._new(core.wedge("L")) 

2882 

2883 

2884def _check_size(size): 

2885 """ 

2886 Common check to enforce type and sanity check on size tuples 

2887 

2888 :param size: Should be a 2 tuple of (width, height) 

2889 :returns: True, or raises a ValueError 

2890 """ 

2891 

2892 if not isinstance(size, (list, tuple)): 

2893 msg = "Size must be a tuple" 

2894 raise ValueError(msg) 

2895 if len(size) != 2: 

2896 msg = "Size must be a tuple of length 2" 

2897 raise ValueError(msg) 

2898 if size[0] < 0 or size[1] < 0: 

2899 msg = "Width and height must be >= 0" 

2900 raise ValueError(msg) 

2901 

2902 return True 

2903 

2904 

2905def new(mode, size, color=0) -> Image: 

2906 """ 

2907 Creates a new image with the given mode and size. 

2908 

2909 :param mode: The mode to use for the new image. See: 

2910 :ref:`concept-modes`. 

2911 :param size: A 2-tuple, containing (width, height) in pixels. 

2912 :param color: What color to use for the image. Default is black. 

2913 If given, this should be a single integer or floating point value 

2914 for single-band modes, and a tuple for multi-band modes (one value 

2915 per band). When creating RGB or HSV images, you can also use color 

2916 strings as supported by the ImageColor module. If the color is 

2917 None, the image is not initialised. 

2918 :returns: An :py:class:`~PIL.Image.Image` object. 

2919 """ 

2920 

2921 _check_size(size) 

2922 

2923 if color is None: 

2924 # don't initialize 

2925 return Image()._new(core.new(mode, size)) 

2926 

2927 if isinstance(color, str): 

2928 # css3-style specifier 

2929 

2930 from . import ImageColor 

2931 

2932 color = ImageColor.getcolor(color, mode) 

2933 

2934 im = Image() 

2935 if mode == "P" and isinstance(color, (list, tuple)) and len(color) in [3, 4]: 

2936 # RGB or RGBA value for a P image 

2937 from . import ImagePalette 

2938 

2939 im.palette = ImagePalette.ImagePalette() 

2940 color = im.palette.getcolor(color) 

2941 return im._new(core.fill(mode, size, color)) 

2942 

2943 

2944def frombytes(mode, size, data, decoder_name="raw", *args) -> Image: 

2945 """ 

2946 Creates a copy of an image memory from pixel data in a buffer. 

2947 

2948 In its simplest form, this function takes three arguments 

2949 (mode, size, and unpacked pixel data). 

2950 

2951 You can also use any pixel decoder supported by PIL. For more 

2952 information on available decoders, see the section 

2953 :ref:`Writing Your Own File Codec <file-codecs>`. 

2954 

2955 Note that this function decodes pixel data only, not entire images. 

2956 If you have an entire image in a string, wrap it in a 

2957 :py:class:`~io.BytesIO` object, and use :py:func:`~PIL.Image.open` to load 

2958 it. 

2959 

2960 :param mode: The image mode. See: :ref:`concept-modes`. 

2961 :param size: The image size. 

2962 :param data: A byte buffer containing raw data for the given mode. 

2963 :param decoder_name: What decoder to use. 

2964 :param args: Additional parameters for the given decoder. 

2965 :returns: An :py:class:`~PIL.Image.Image` object. 

2966 """ 

2967 

2968 _check_size(size) 

2969 

2970 im = new(mode, size) 

2971 if im.width != 0 and im.height != 0: 

2972 # may pass tuple instead of argument list 

2973 if len(args) == 1 and isinstance(args[0], tuple): 

2974 args = args[0] 

2975 

2976 if decoder_name == "raw" and args == (): 

2977 args = mode 

2978 

2979 im.frombytes(data, decoder_name, args) 

2980 return im 

2981 

2982 

2983def frombuffer(mode, size, data, decoder_name="raw", *args): 

2984 """ 

2985 Creates an image memory referencing pixel data in a byte buffer. 

2986 

2987 This function is similar to :py:func:`~PIL.Image.frombytes`, but uses data 

2988 in the byte buffer, where possible. This means that changes to the 

2989 original buffer object are reflected in this image). Not all modes can 

2990 share memory; supported modes include "L", "RGBX", "RGBA", and "CMYK". 

2991 

2992 Note that this function decodes pixel data only, not entire images. 

2993 If you have an entire image file in a string, wrap it in a 

2994 :py:class:`~io.BytesIO` object, and use :py:func:`~PIL.Image.open` to load it. 

2995 

2996 In the current version, the default parameters used for the "raw" decoder 

2997 differs from that used for :py:func:`~PIL.Image.frombytes`. This is a 

2998 bug, and will probably be fixed in a future release. The current release 

2999 issues a warning if you do this; to disable the warning, you should provide 

3000 the full set of parameters. See below for details. 

3001 

3002 :param mode: The image mode. See: :ref:`concept-modes`. 

3003 :param size: The image size. 

3004 :param data: A bytes or other buffer object containing raw 

3005 data for the given mode. 

3006 :param decoder_name: What decoder to use. 

3007 :param args: Additional parameters for the given decoder. For the 

3008 default encoder ("raw"), it's recommended that you provide the 

3009 full set of parameters:: 

3010 

3011 frombuffer(mode, size, data, "raw", mode, 0, 1) 

3012 

3013 :returns: An :py:class:`~PIL.Image.Image` object. 

3014 

3015 .. versionadded:: 1.1.4 

3016 """ 

3017 

3018 _check_size(size) 

3019 

3020 # may pass tuple instead of argument list 

3021 if len(args) == 1 and isinstance(args[0], tuple): 

3022 args = args[0] 

3023 

3024 if decoder_name == "raw": 

3025 if args == (): 

3026 args = mode, 0, 1 

3027 if args[0] in _MAPMODES: 

3028 im = new(mode, (0, 0)) 

3029 im = im._new(core.map_buffer(data, size, decoder_name, 0, args)) 

3030 if mode == "P": 

3031 from . import ImagePalette 

3032 

3033 im.palette = ImagePalette.ImagePalette("RGB", im.im.getpalette("RGB")) 

3034 im.readonly = 1 

3035 return im 

3036 

3037 return frombytes(mode, size, data, decoder_name, args) 

3038 

3039 

3040def fromarray(obj, mode=None): 

3041 """ 

3042 Creates an image memory from an object exporting the array interface 

3043 (using the buffer protocol):: 

3044 

3045 from PIL import Image 

3046 import numpy as np 

3047 a = np.zeros((5, 5)) 

3048 im = Image.fromarray(a) 

3049 

3050 If ``obj`` is not contiguous, then the ``tobytes`` method is called 

3051 and :py:func:`~PIL.Image.frombuffer` is used. 

3052 

3053 In the case of NumPy, be aware that Pillow modes do not always correspond 

3054 to NumPy dtypes. Pillow modes only offer 1-bit pixels, 8-bit pixels, 

3055 32-bit signed integer pixels, and 32-bit floating point pixels. 

3056 

3057 Pillow images can also be converted to arrays:: 

3058 

3059 from PIL import Image 

3060 import numpy as np 

3061 im = Image.open("hopper.jpg") 

3062 a = np.asarray(im) 

3063 

3064 When converting Pillow images to arrays however, only pixel values are 

3065 transferred. This means that P and PA mode images will lose their palette. 

3066 

3067 :param obj: Object with array interface 

3068 :param mode: Optional mode to use when reading ``obj``. Will be determined from 

3069 type if ``None``. 

3070 

3071 This will not be used to convert the data after reading, but will be used to 

3072 change how the data is read:: 

3073 

3074 from PIL import Image 

3075 import numpy as np 

3076 a = np.full((1, 1), 300) 

3077 im = Image.fromarray(a, mode="L") 

3078 im.getpixel((0, 0)) # 44 

3079 im = Image.fromarray(a, mode="RGB") 

3080 im.getpixel((0, 0)) # (44, 1, 0) 

3081 

3082 See: :ref:`concept-modes` for general information about modes. 

3083 :returns: An image object. 

3084 

3085 .. versionadded:: 1.1.6 

3086 """ 

3087 arr = obj.__array_interface__ 

3088 shape = arr["shape"] 

3089 ndim = len(shape) 

3090 strides = arr.get("strides", None) 

3091 if mode is None: 

3092 try: 

3093 typekey = (1, 1) + shape[2:], arr["typestr"] 

3094 except KeyError as e: 

3095 msg = "Cannot handle this data type" 

3096 raise TypeError(msg) from e 

3097 try: 

3098 mode, rawmode = _fromarray_typemap[typekey] 

3099 except KeyError as e: 

3100 typekey_shape, typestr = typekey 

3101 msg = f"Cannot handle this data type: {typekey_shape}, {typestr}" 

3102 raise TypeError(msg) from e 

3103 else: 

3104 rawmode = mode 

3105 if mode in ["1", "L", "I", "P", "F"]: 

3106 ndmax = 2 

3107 elif mode == "RGB": 

3108 ndmax = 3 

3109 else: 

3110 ndmax = 4 

3111 if ndim > ndmax: 

3112 msg = f"Too many dimensions: {ndim} > {ndmax}." 

3113 raise ValueError(msg) 

3114 

3115 size = 1 if ndim == 1 else shape[1], shape[0] 

3116 if strides is not None: 

3117 if hasattr(obj, "tobytes"): 

3118 obj = obj.tobytes() 

3119 else: 

3120 obj = obj.tostring() 

3121 

3122 return frombuffer(mode, size, obj, "raw", rawmode, 0, 1) 

3123 

3124 

3125def fromqimage(im): 

3126 """Creates an image instance from a QImage image""" 

3127 from . import ImageQt 

3128 

3129 if not ImageQt.qt_is_installed: 

3130 msg = "Qt bindings are not installed" 

3131 raise ImportError(msg) 

3132 return ImageQt.fromqimage(im) 

3133 

3134 

3135def fromqpixmap(im): 

3136 """Creates an image instance from a QPixmap image""" 

3137 from . import ImageQt 

3138 

3139 if not ImageQt.qt_is_installed: 

3140 msg = "Qt bindings are not installed" 

3141 raise ImportError(msg) 

3142 return ImageQt.fromqpixmap(im) 

3143 

3144 

3145_fromarray_typemap = { 

3146 # (shape, typestr) => mode, rawmode 

3147 # first two members of shape are set to one 

3148 ((1, 1), "|b1"): ("1", "1;8"), 

3149 ((1, 1), "|u1"): ("L", "L"), 

3150 ((1, 1), "|i1"): ("I", "I;8"), 

3151 ((1, 1), "<u2"): ("I", "I;16"), 

3152 ((1, 1), ">u2"): ("I", "I;16B"), 

3153 ((1, 1), "<i2"): ("I", "I;16S"), 

3154 ((1, 1), ">i2"): ("I", "I;16BS"), 

3155 ((1, 1), "<u4"): ("I", "I;32"), 

3156 ((1, 1), ">u4"): ("I", "I;32B"), 

3157 ((1, 1), "<i4"): ("I", "I;32S"), 

3158 ((1, 1), ">i4"): ("I", "I;32BS"), 

3159 ((1, 1), "<f4"): ("F", "F;32F"), 

3160 ((1, 1), ">f4"): ("F", "F;32BF"), 

3161 ((1, 1), "<f8"): ("F", "F;64F"), 

3162 ((1, 1), ">f8"): ("F", "F;64BF"), 

3163 ((1, 1, 2), "|u1"): ("LA", "LA"), 

3164 ((1, 1, 3), "|u1"): ("RGB", "RGB"), 

3165 ((1, 1, 4), "|u1"): ("RGBA", "RGBA"), 

3166 # shortcuts: 

3167 ((1, 1), _ENDIAN + "i4"): ("I", "I"), 

3168 ((1, 1), _ENDIAN + "f4"): ("F", "F"), 

3169} 

3170 

3171 

3172def _decompression_bomb_check(size): 

3173 if MAX_IMAGE_PIXELS is None: 

3174 return 

3175 

3176 pixels = max(1, size[0]) * max(1, size[1]) 

3177 

3178 if pixels > 2 * MAX_IMAGE_PIXELS: 

3179 msg = ( 

3180 f"Image size ({pixels} pixels) exceeds limit of {2 * MAX_IMAGE_PIXELS} " 

3181 "pixels, could be decompression bomb DOS attack." 

3182 ) 

3183 raise DecompressionBombError(msg) 

3184 

3185 if pixels > MAX_IMAGE_PIXELS: 

3186 warnings.warn( 

3187 f"Image size ({pixels} pixels) exceeds limit of {MAX_IMAGE_PIXELS} pixels, " 

3188 "could be decompression bomb DOS attack.", 

3189 DecompressionBombWarning, 

3190 ) 

3191 

3192 

3193def open(fp, mode="r", formats=None) -> Image: 

3194 """ 

3195 Opens and identifies the given image file. 

3196 

3197 This is a lazy operation; this function identifies the file, but 

3198 the file remains open and the actual image data is not read from 

3199 the file until you try to process the data (or call the 

3200 :py:meth:`~PIL.Image.Image.load` method). See 

3201 :py:func:`~PIL.Image.new`. See :ref:`file-handling`. 

3202 

3203 :param fp: A filename (string), pathlib.Path object or a file object. 

3204 The file object must implement ``file.read``, 

3205 ``file.seek``, and ``file.tell`` methods, 

3206 and be opened in binary mode. The file object will also seek to zero 

3207 before reading. 

3208 :param mode: The mode. If given, this argument must be "r". 

3209 :param formats: A list or tuple of formats to attempt to load the file in. 

3210 This can be used to restrict the set of formats checked. 

3211 Pass ``None`` to try all supported formats. You can print the set of 

3212 available formats by running ``python3 -m PIL`` or using 

3213 the :py:func:`PIL.features.pilinfo` function. 

3214 :returns: An :py:class:`~PIL.Image.Image` object. 

3215 :exception FileNotFoundError: If the file cannot be found. 

3216 :exception PIL.UnidentifiedImageError: If the image cannot be opened and 

3217 identified. 

3218 :exception ValueError: If the ``mode`` is not "r", or if a ``StringIO`` 

3219 instance is used for ``fp``. 

3220 :exception TypeError: If ``formats`` is not ``None``, a list or a tuple. 

3221 """ 

3222 

3223 if mode != "r": 

3224 msg = f"bad mode {repr(mode)}" 

3225 raise ValueError(msg) 

3226 elif isinstance(fp, io.StringIO): 

3227 msg = ( 

3228 "StringIO cannot be used to open an image. " 

3229 "Binary data must be used instead." 

3230 ) 

3231 raise ValueError(msg) 

3232 

3233 if formats is None: 

3234 formats = ID 

3235 elif not isinstance(formats, (list, tuple)): 

3236 msg = "formats must be a list or tuple" 

3237 raise TypeError(msg) 

3238 

3239 exclusive_fp = False 

3240 filename = "" 

3241 if isinstance(fp, Path): 

3242 filename = str(fp.resolve()) 

3243 elif is_path(fp): 

3244 filename = fp 

3245 

3246 if filename: 

3247 fp = builtins.open(filename, "rb") 

3248 exclusive_fp = True 

3249 

3250 try: 

3251 fp.seek(0) 

3252 except (AttributeError, io.UnsupportedOperation): 

3253 fp = io.BytesIO(fp.read()) 

3254 exclusive_fp = True 

3255 

3256 prefix = fp.read(16) 

3257 

3258 preinit() 

3259 

3260 accept_warnings = [] 

3261 

3262 def _open_core(fp, filename, prefix, formats): 

3263 for i in formats: 

3264 i = i.upper() 

3265 if i not in OPEN: 

3266 init() 

3267 try: 

3268 factory, accept = OPEN[i] 

3269 result = not accept or accept(prefix) 

3270 if type(result) in [str, bytes]: 

3271 accept_warnings.append(result) 

3272 elif result: 

3273 fp.seek(0) 

3274 im = factory(fp, filename) 

3275 _decompression_bomb_check(im.size) 

3276 return im 

3277 except (SyntaxError, IndexError, TypeError, struct.error): 

3278 # Leave disabled by default, spams the logs with image 

3279 # opening failures that are entirely expected. 

3280 # logger.debug("", exc_info=True) 

3281 continue 

3282 except BaseException: 

3283 if exclusive_fp: 

3284 fp.close() 

3285 raise 

3286 return None 

3287 

3288 im = _open_core(fp, filename, prefix, formats) 

3289 

3290 if im is None and formats is ID: 

3291 checked_formats = formats.copy() 

3292 if init(): 

3293 im = _open_core( 

3294 fp, 

3295 filename, 

3296 prefix, 

3297 tuple(format for format in formats if format not in checked_formats), 

3298 ) 

3299 

3300 if im: 

3301 im._exclusive_fp = exclusive_fp 

3302 return im 

3303 

3304 if exclusive_fp: 

3305 fp.close() 

3306 for message in accept_warnings: 

3307 warnings.warn(message) 

3308 msg = "cannot identify image file %r" % (filename if filename else fp) 

3309 raise UnidentifiedImageError(msg) 

3310 

3311 

3312# 

3313# Image processing. 

3314 

3315 

3316def alpha_composite(im1, im2): 

3317 """ 

3318 Alpha composite im2 over im1. 

3319 

3320 :param im1: The first image. Must have mode RGBA. 

3321 :param im2: The second image. Must have mode RGBA, and the same size as 

3322 the first image. 

3323 :returns: An :py:class:`~PIL.Image.Image` object. 

3324 """ 

3325 

3326 im1.load() 

3327 im2.load() 

3328 return im1._new(core.alpha_composite(im1.im, im2.im)) 

3329 

3330 

3331def blend(im1, im2, alpha): 

3332 """ 

3333 Creates a new image by interpolating between two input images, using 

3334 a constant alpha:: 

3335 

3336 out = image1 * (1.0 - alpha) + image2 * alpha 

3337 

3338 :param im1: The first image. 

3339 :param im2: The second image. Must have the same mode and size as 

3340 the first image. 

3341 :param alpha: The interpolation alpha factor. If alpha is 0.0, a 

3342 copy of the first image is returned. If alpha is 1.0, a copy of 

3343 the second image is returned. There are no restrictions on the 

3344 alpha value. If necessary, the result is clipped to fit into 

3345 the allowed output range. 

3346 :returns: An :py:class:`~PIL.Image.Image` object. 

3347 """ 

3348 

3349 im1.load() 

3350 im2.load() 

3351 return im1._new(core.blend(im1.im, im2.im, alpha)) 

3352 

3353 

3354def composite(image1, image2, mask): 

3355 """ 

3356 Create composite image by blending images using a transparency mask. 

3357 

3358 :param image1: The first image. 

3359 :param image2: The second image. Must have the same mode and 

3360 size as the first image. 

3361 :param mask: A mask image. This image can have mode 

3362 "1", "L", or "RGBA", and must have the same size as the 

3363 other two images. 

3364 """ 

3365 

3366 image = image2.copy() 

3367 image.paste(image1, None, mask) 

3368 return image 

3369 

3370 

3371def eval(image, *args): 

3372 """ 

3373 Applies the function (which should take one argument) to each pixel 

3374 in the given image. If the image has more than one band, the same 

3375 function is applied to each band. Note that the function is 

3376 evaluated once for each possible pixel value, so you cannot use 

3377 random components or other generators. 

3378 

3379 :param image: The input image. 

3380 :param function: A function object, taking one integer argument. 

3381 :returns: An :py:class:`~PIL.Image.Image` object. 

3382 """ 

3383 

3384 return image.point(args[0]) 

3385 

3386 

3387def merge(mode, bands): 

3388 """ 

3389 Merge a set of single band images into a new multiband image. 

3390 

3391 :param mode: The mode to use for the output image. See: 

3392 :ref:`concept-modes`. 

3393 :param bands: A sequence containing one single-band image for 

3394 each band in the output image. All bands must have the 

3395 same size. 

3396 :returns: An :py:class:`~PIL.Image.Image` object. 

3397 """ 

3398 

3399 if getmodebands(mode) != len(bands) or "*" in mode: 

3400 msg = "wrong number of bands" 

3401 raise ValueError(msg) 

3402 for band in bands[1:]: 

3403 if band.mode != getmodetype(mode): 

3404 msg = "mode mismatch" 

3405 raise ValueError(msg) 

3406 if band.size != bands[0].size: 

3407 msg = "size mismatch" 

3408 raise ValueError(msg) 

3409 for band in bands: 

3410 band.load() 

3411 return bands[0]._new(core.merge(mode, *[b.im for b in bands])) 

3412 

3413 

3414# -------------------------------------------------------------------- 

3415# Plugin registry 

3416 

3417 

3418def register_open(id, factory, accept=None) -> None: 

3419 """ 

3420 Register an image file plugin. This function should not be used 

3421 in application code. 

3422 

3423 :param id: An image format identifier. 

3424 :param factory: An image file factory method. 

3425 :param accept: An optional function that can be used to quickly 

3426 reject images having another format. 

3427 """ 

3428 id = id.upper() 

3429 if id not in ID: 

3430 ID.append(id) 

3431 OPEN[id] = factory, accept 

3432 

3433 

3434def register_mime(id, mimetype): 

3435 """ 

3436 Registers an image MIME type by populating ``Image.MIME``. This function 

3437 should not be used in application code. 

3438 

3439 ``Image.MIME`` provides a mapping from image format identifiers to mime 

3440 formats, but :py:meth:`~PIL.ImageFile.ImageFile.get_format_mimetype` can 

3441 provide a different result for specific images. 

3442 

3443 :param id: An image format identifier. 

3444 :param mimetype: The image MIME type for this format. 

3445 """ 

3446 MIME[id.upper()] = mimetype 

3447 

3448 

3449def register_save(id, driver): 

3450 """ 

3451 Registers an image save function. This function should not be 

3452 used in application code. 

3453 

3454 :param id: An image format identifier. 

3455 :param driver: A function to save images in this format. 

3456 """ 

3457 SAVE[id.upper()] = driver 

3458 

3459 

3460def register_save_all(id, driver): 

3461 """ 

3462 Registers an image function to save all the frames 

3463 of a multiframe format. This function should not be 

3464 used in application code. 

3465 

3466 :param id: An image format identifier. 

3467 :param driver: A function to save images in this format. 

3468 """ 

3469 SAVE_ALL[id.upper()] = driver 

3470 

3471 

3472def register_extension(id, extension) -> None: 

3473 """ 

3474 Registers an image extension. This function should not be 

3475 used in application code. 

3476 

3477 :param id: An image format identifier. 

3478 :param extension: An extension used for this format. 

3479 """ 

3480 EXTENSION[extension.lower()] = id.upper() 

3481 

3482 

3483def register_extensions(id, extensions): 

3484 """ 

3485 Registers image extensions. This function should not be 

3486 used in application code. 

3487 

3488 :param id: An image format identifier. 

3489 :param extensions: A list of extensions used for this format. 

3490 """ 

3491 for extension in extensions: 

3492 register_extension(id, extension) 

3493 

3494 

3495def registered_extensions(): 

3496 """ 

3497 Returns a dictionary containing all file extensions belonging 

3498 to registered plugins 

3499 """ 

3500 init() 

3501 return EXTENSION 

3502 

3503 

3504def register_decoder(name, decoder): 

3505 """ 

3506 Registers an image decoder. This function should not be 

3507 used in application code. 

3508 

3509 :param name: The name of the decoder 

3510 :param decoder: A callable(mode, args) that returns an 

3511 ImageFile.PyDecoder object 

3512 

3513 .. versionadded:: 4.1.0 

3514 """ 

3515 DECODERS[name] = decoder 

3516 

3517 

3518def register_encoder(name, encoder): 

3519 """ 

3520 Registers an image encoder. This function should not be 

3521 used in application code. 

3522 

3523 :param name: The name of the encoder 

3524 :param encoder: A callable(mode, args) that returns an 

3525 ImageFile.PyEncoder object 

3526 

3527 .. versionadded:: 4.1.0 

3528 """ 

3529 ENCODERS[name] = encoder 

3530 

3531 

3532# -------------------------------------------------------------------- 

3533# Simple display support. 

3534 

3535 

3536def _show(image, **options): 

3537 from . import ImageShow 

3538 

3539 ImageShow.show(image, **options) 

3540 

3541 

3542# -------------------------------------------------------------------- 

3543# Effects 

3544 

3545 

3546def effect_mandelbrot(size, extent, quality): 

3547 """ 

3548 Generate a Mandelbrot set covering the given extent. 

3549 

3550 :param size: The requested size in pixels, as a 2-tuple: 

3551 (width, height). 

3552 :param extent: The extent to cover, as a 4-tuple: 

3553 (x0, y0, x1, y1). 

3554 :param quality: Quality. 

3555 """ 

3556 return Image()._new(core.effect_mandelbrot(size, extent, quality)) 

3557 

3558 

3559def effect_noise(size, sigma): 

3560 """ 

3561 Generate Gaussian noise centered around 128. 

3562 

3563 :param size: The requested size in pixels, as a 2-tuple: 

3564 (width, height). 

3565 :param sigma: Standard deviation of noise. 

3566 """ 

3567 return Image()._new(core.effect_noise(size, sigma)) 

3568 

3569 

3570def linear_gradient(mode): 

3571 """ 

3572 Generate 256x256 linear gradient from black to white, top to bottom. 

3573 

3574 :param mode: Input mode. 

3575 """ 

3576 return Image()._new(core.linear_gradient(mode)) 

3577 

3578 

3579def radial_gradient(mode): 

3580 """ 

3581 Generate 256x256 radial gradient from black to white, centre to edge. 

3582 

3583 :param mode: Input mode. 

3584 """ 

3585 return Image()._new(core.radial_gradient(mode)) 

3586 

3587 

3588# -------------------------------------------------------------------- 

3589# Resources 

3590 

3591 

3592def _apply_env_variables(env=None): 

3593 if env is None: 

3594 env = os.environ 

3595 

3596 for var_name, setter in [ 

3597 ("PILLOW_ALIGNMENT", core.set_alignment), 

3598 ("PILLOW_BLOCK_SIZE", core.set_block_size), 

3599 ("PILLOW_BLOCKS_MAX", core.set_blocks_max), 

3600 ]: 

3601 if var_name not in env: 

3602 continue 

3603 

3604 var = env[var_name].lower() 

3605 

3606 units = 1 

3607 for postfix, mul in [("k", 1024), ("m", 1024 * 1024)]: 

3608 if var.endswith(postfix): 

3609 units = mul 

3610 var = var[: -len(postfix)] 

3611 

3612 try: 

3613 var = int(var) * units 

3614 except ValueError: 

3615 warnings.warn(f"{var_name} is not int") 

3616 continue 

3617 

3618 try: 

3619 setter(var) 

3620 except ValueError as e: 

3621 warnings.warn(f"{var_name}: {e}") 

3622 

3623 

3624_apply_env_variables() 

3625atexit.register(core.clear_cache) 

3626 

3627 

3628class Exif(MutableMapping): 

3629 """ 

3630 This class provides read and write access to EXIF image data:: 

3631 

3632 from PIL import Image 

3633 im = Image.open("exif.png") 

3634 exif = im.getexif() # Returns an instance of this class 

3635 

3636 Information can be read and written, iterated over or deleted:: 

3637 

3638 print(exif[274]) # 1 

3639 exif[274] = 2 

3640 for k, v in exif.items(): 

3641 print("Tag", k, "Value", v) # Tag 274 Value 2 

3642 del exif[274] 

3643 

3644 To access information beyond IFD0, :py:meth:`~PIL.Image.Exif.get_ifd` 

3645 returns a dictionary:: 

3646 

3647 from PIL import ExifTags 

3648 im = Image.open("exif_gps.jpg") 

3649 exif = im.getexif() 

3650 gps_ifd = exif.get_ifd(ExifTags.IFD.GPSInfo) 

3651 print(gps_ifd) 

3652 

3653 Other IFDs include ``ExifTags.IFD.Exif``, ``ExifTags.IFD.Makernote``, 

3654 ``ExifTags.IFD.Interop`` and ``ExifTags.IFD.IFD1``. 

3655 

3656 :py:mod:`~PIL.ExifTags` also has enum classes to provide names for data:: 

3657 

3658 print(exif[ExifTags.Base.Software]) # PIL 

3659 print(gps_ifd[ExifTags.GPS.GPSDateStamp]) # 1999:99:99 99:99:99 

3660 """ 

3661 

3662 endian = None 

3663 bigtiff = False 

3664 

3665 def __init__(self): 

3666 self._data = {} 

3667 self._hidden_data = {} 

3668 self._ifds = {} 

3669 self._info = None 

3670 self._loaded_exif = None 

3671 

3672 def _fixup(self, value): 

3673 try: 

3674 if len(value) == 1 and isinstance(value, tuple): 

3675 return value[0] 

3676 except Exception: 

3677 pass 

3678 return value 

3679 

3680 def _fixup_dict(self, src_dict): 

3681 # Helper function 

3682 # returns a dict with any single item tuples/lists as individual values 

3683 return {k: self._fixup(v) for k, v in src_dict.items()} 

3684 

3685 def _get_ifd_dict(self, offset): 

3686 try: 

3687 # an offset pointer to the location of the nested embedded IFD. 

3688 # It should be a long, but may be corrupted. 

3689 self.fp.seek(offset) 

3690 except (KeyError, TypeError): 

3691 pass 

3692 else: 

3693 from . import TiffImagePlugin 

3694 

3695 info = TiffImagePlugin.ImageFileDirectory_v2(self.head) 

3696 info.load(self.fp) 

3697 return self._fixup_dict(info) 

3698 

3699 def _get_head(self): 

3700 version = b"\x2B" if self.bigtiff else b"\x2A" 

3701 if self.endian == "<": 

3702 head = b"II" + version + b"\x00" + o32le(8) 

3703 else: 

3704 head = b"MM\x00" + version + o32be(8) 

3705 if self.bigtiff: 

3706 head += o32le(8) if self.endian == "<" else o32be(8) 

3707 head += b"\x00\x00\x00\x00" 

3708 return head 

3709 

3710 def load(self, data): 

3711 # Extract EXIF information. This is highly experimental, 

3712 # and is likely to be replaced with something better in a future 

3713 # version. 

3714 

3715 # The EXIF record consists of a TIFF file embedded in a JPEG 

3716 # application marker (!). 

3717 if data == self._loaded_exif: 

3718 return 

3719 self._loaded_exif = data 

3720 self._data.clear() 

3721 self._hidden_data.clear() 

3722 self._ifds.clear() 

3723 if data and data.startswith(b"Exif\x00\x00"): 

3724 data = data[6:] 

3725 if not data: 

3726 self._info = None 

3727 return 

3728 

3729 self.fp = io.BytesIO(data) 

3730 self.head = self.fp.read(8) 

3731 # process dictionary 

3732 from . import TiffImagePlugin 

3733 

3734 self._info = TiffImagePlugin.ImageFileDirectory_v2(self.head) 

3735 self.endian = self._info._endian 

3736 self.fp.seek(self._info.next) 

3737 self._info.load(self.fp) 

3738 

3739 def load_from_fp(self, fp, offset=None): 

3740 self._loaded_exif = None 

3741 self._data.clear() 

3742 self._hidden_data.clear() 

3743 self._ifds.clear() 

3744 

3745 # process dictionary 

3746 from . import TiffImagePlugin 

3747 

3748 self.fp = fp 

3749 if offset is not None: 

3750 self.head = self._get_head() 

3751 else: 

3752 self.head = self.fp.read(8) 

3753 self._info = TiffImagePlugin.ImageFileDirectory_v2(self.head) 

3754 if self.endian is None: 

3755 self.endian = self._info._endian 

3756 if offset is None: 

3757 offset = self._info.next 

3758 self.fp.tell() 

3759 self.fp.seek(offset) 

3760 self._info.load(self.fp) 

3761 

3762 def _get_merged_dict(self): 

3763 merged_dict = dict(self) 

3764 

3765 # get EXIF extension 

3766 if ExifTags.IFD.Exif in self: 

3767 ifd = self._get_ifd_dict(self[ExifTags.IFD.Exif]) 

3768 if ifd: 

3769 merged_dict.update(ifd) 

3770 

3771 # GPS 

3772 if ExifTags.IFD.GPSInfo in self: 

3773 merged_dict[ExifTags.IFD.GPSInfo] = self._get_ifd_dict( 

3774 self[ExifTags.IFD.GPSInfo] 

3775 ) 

3776 

3777 return merged_dict 

3778 

3779 def tobytes(self, offset=8): 

3780 from . import TiffImagePlugin 

3781 

3782 head = self._get_head() 

3783 ifd = TiffImagePlugin.ImageFileDirectory_v2(ifh=head) 

3784 for tag, value in self.items(): 

3785 if tag in [ 

3786 ExifTags.IFD.Exif, 

3787 ExifTags.IFD.GPSInfo, 

3788 ] and not isinstance(value, dict): 

3789 value = self.get_ifd(tag) 

3790 if ( 

3791 tag == ExifTags.IFD.Exif 

3792 and ExifTags.IFD.Interop in value 

3793 and not isinstance(value[ExifTags.IFD.Interop], dict) 

3794 ): 

3795 value = value.copy() 

3796 value[ExifTags.IFD.Interop] = self.get_ifd(ExifTags.IFD.Interop) 

3797 ifd[tag] = value 

3798 return b"Exif\x00\x00" + head + ifd.tobytes(offset) 

3799 

3800 def get_ifd(self, tag): 

3801 if tag not in self._ifds: 

3802 if tag == ExifTags.IFD.IFD1: 

3803 if self._info is not None and self._info.next != 0: 

3804 self._ifds[tag] = self._get_ifd_dict(self._info.next) 

3805 elif tag in [ExifTags.IFD.Exif, ExifTags.IFD.GPSInfo]: 

3806 offset = self._hidden_data.get(tag, self.get(tag)) 

3807 if offset is not None: 

3808 self._ifds[tag] = self._get_ifd_dict(offset) 

3809 elif tag in [ExifTags.IFD.Interop, ExifTags.IFD.Makernote]: 

3810 if ExifTags.IFD.Exif not in self._ifds: 

3811 self.get_ifd(ExifTags.IFD.Exif) 

3812 tag_data = self._ifds[ExifTags.IFD.Exif][tag] 

3813 if tag == ExifTags.IFD.Makernote: 

3814 from .TiffImagePlugin import ImageFileDirectory_v2 

3815 

3816 if tag_data[:8] == b"FUJIFILM": 

3817 ifd_offset = i32le(tag_data, 8) 

3818 ifd_data = tag_data[ifd_offset:] 

3819 

3820 makernote = {} 

3821 for i in range(0, struct.unpack("<H", ifd_data[:2])[0]): 

3822 ifd_tag, typ, count, data = struct.unpack( 

3823 "<HHL4s", ifd_data[i * 12 + 2 : (i + 1) * 12 + 2] 

3824 ) 

3825 try: 

3826 ( 

3827 unit_size, 

3828 handler, 

3829 ) = ImageFileDirectory_v2._load_dispatch[typ] 

3830 except KeyError: 

3831 continue 

3832 size = count * unit_size 

3833 if size > 4: 

3834 (offset,) = struct.unpack("<L", data) 

3835 data = ifd_data[offset - 12 : offset + size - 12] 

3836 else: 

3837 data = data[:size] 

3838 

3839 if len(data) != size: 

3840 warnings.warn( 

3841 "Possibly corrupt EXIF MakerNote data. " 

3842 f"Expecting to read {size} bytes but only got " 

3843 f"{len(data)}. Skipping tag {ifd_tag}" 

3844 ) 

3845 continue 

3846 

3847 if not data: 

3848 continue 

3849 

3850 makernote[ifd_tag] = handler( 

3851 ImageFileDirectory_v2(), data, False 

3852 ) 

3853 self._ifds[tag] = dict(self._fixup_dict(makernote)) 

3854 elif self.get(0x010F) == "Nintendo": 

3855 makernote = {} 

3856 for i in range(0, struct.unpack(">H", tag_data[:2])[0]): 

3857 ifd_tag, typ, count, data = struct.unpack( 

3858 ">HHL4s", tag_data[i * 12 + 2 : (i + 1) * 12 + 2] 

3859 ) 

3860 if ifd_tag == 0x1101: 

3861 # CameraInfo 

3862 (offset,) = struct.unpack(">L", data) 

3863 self.fp.seek(offset) 

3864 

3865 camerainfo = {"ModelID": self.fp.read(4)} 

3866 

3867 self.fp.read(4) 

3868 # Seconds since 2000 

3869 camerainfo["TimeStamp"] = i32le(self.fp.read(12)) 

3870 

3871 self.fp.read(4) 

3872 camerainfo["InternalSerialNumber"] = self.fp.read(4) 

3873 

3874 self.fp.read(12) 

3875 parallax = self.fp.read(4) 

3876 handler = ImageFileDirectory_v2._load_dispatch[ 

3877 TiffTags.FLOAT 

3878 ][1] 

3879 camerainfo["Parallax"] = handler( 

3880 ImageFileDirectory_v2(), parallax, False 

3881 ) 

3882 

3883 self.fp.read(4) 

3884 camerainfo["Category"] = self.fp.read(2) 

3885 

3886 makernote = {0x1101: dict(self._fixup_dict(camerainfo))} 

3887 self._ifds[tag] = makernote 

3888 else: 

3889 # Interop 

3890 self._ifds[tag] = self._get_ifd_dict(tag_data) 

3891 ifd = self._ifds.get(tag, {}) 

3892 if tag == ExifTags.IFD.Exif and self._hidden_data: 

3893 ifd = { 

3894 k: v 

3895 for (k, v) in ifd.items() 

3896 if k not in (ExifTags.IFD.Interop, ExifTags.IFD.Makernote) 

3897 } 

3898 return ifd 

3899 

3900 def hide_offsets(self): 

3901 for tag in (ExifTags.IFD.Exif, ExifTags.IFD.GPSInfo): 

3902 if tag in self: 

3903 self._hidden_data[tag] = self[tag] 

3904 del self[tag] 

3905 

3906 def __str__(self): 

3907 if self._info is not None: 

3908 # Load all keys into self._data 

3909 for tag in self._info: 

3910 self[tag] 

3911 

3912 return str(self._data) 

3913 

3914 def __len__(self): 

3915 keys = set(self._data) 

3916 if self._info is not None: 

3917 keys.update(self._info) 

3918 return len(keys) 

3919 

3920 def __getitem__(self, tag): 

3921 if self._info is not None and tag not in self._data and tag in self._info: 

3922 self._data[tag] = self._fixup(self._info[tag]) 

3923 del self._info[tag] 

3924 return self._data[tag] 

3925 

3926 def __contains__(self, tag): 

3927 return tag in self._data or (self._info is not None and tag in self._info) 

3928 

3929 def __setitem__(self, tag, value): 

3930 if self._info is not None and tag in self._info: 

3931 del self._info[tag] 

3932 self._data[tag] = value 

3933 

3934 def __delitem__(self, tag): 

3935 if self._info is not None and tag in self._info: 

3936 del self._info[tag] 

3937 else: 

3938 del self._data[tag] 

3939 

3940 def __iter__(self): 

3941 keys = set(self._data) 

3942 if self._info is not None: 

3943 keys.update(self._info) 

3944 return iter(keys)