Coverage for /var/srv/projects/api.amasfac.comuna18.com/tmp/venv/lib/python3.9/site-packages/PIL/Image.py: 25%

1551 statements  

« prev     ^ index     » next       coverage.py v6.4.4, created at 2023-07-17 14:22 -0600

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 

27import atexit 

28import builtins 

29import io 

30import logging 

31import math 

32import os 

33import re 

34import struct 

35import sys 

36import tempfile 

37import warnings 

38from collections.abc import Callable, MutableMapping 

39from enum import IntEnum 

40from pathlib import Path 

41 

42try: 

43 import defusedxml.ElementTree as ElementTree 

44except ImportError: 

45 ElementTree = None 

46 

47# VERSION was removed in Pillow 6.0.0. 

48# PILLOW_VERSION was removed in Pillow 9.0.0. 

49# Use __version__ instead. 

50from . import ImageMode, TiffTags, UnidentifiedImageError, __version__, _plugins 

51from ._binary import i32le, o32be, o32le 

52from ._deprecate import deprecate 

53from ._util import DeferredError, is_path 

54 

55 

56def __getattr__(name): 

57 categories = {"NORMAL": 0, "SEQUENCE": 1, "CONTAINER": 2} 

58 if name in categories: 

59 deprecate("Image categories", 10, "is_animated", plural=True) 

60 return categories[name] 

61 elif name in ("NEAREST", "NONE"): 

62 deprecate(name, 10, "Resampling.NEAREST or Dither.NONE") 

63 return 0 

64 old_resampling = { 

65 "LINEAR": "BILINEAR", 

66 "CUBIC": "BICUBIC", 

67 "ANTIALIAS": "LANCZOS", 

68 } 

69 if name in old_resampling: 

70 deprecate(name, 10, f"Resampling.{old_resampling[name]}") 

71 return Resampling[old_resampling[name]] 

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

73 if name in enum.__members__: 

74 deprecate(name, 10, f"{enum.__name__}.{name}") 

75 return enum[name] 

76 raise AttributeError(f"module '{__name__}' has no attribute '{name}'") 

77 

78 

79logger = logging.getLogger(__name__) 

80 

81 

82class DecompressionBombWarning(RuntimeWarning): 

83 pass 

84 

85 

86class DecompressionBombError(Exception): 

87 pass 

88 

89 

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

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

92 

93 

94try: 

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

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

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

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

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

100 from . import _imaging as core 

101 

102 if __version__ != getattr(core, "PILLOW_VERSION", None): 102 ↛ 103line 102 didn't jump to line 103, because the condition on line 102 was never true

103 raise ImportError( 

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

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

106 f"Pillow version: {__version__}" 

107 ) 

108 

109except ImportError as v: 

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

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

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

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

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

115 # possible. 

116 warnings.warn( 

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

118 RuntimeWarning, 

119 ) 

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

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

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

123 # see docs/porting.rst 

124 raise 

125 

126 

127# works everywhere, win for pypy, not cpython 

128USE_CFFI_ACCESS = hasattr(sys, "pypy_version_info") 

129try: 

130 import cffi 

131except ImportError: 

132 cffi = None 

133 

134 

135def isImageType(t): 

136 """ 

137 Checks if an object is an image object. 

138 

139 .. warning:: 

140 

141 This function is for internal use only. 

142 

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

144 :returns: True if the object is an image 

145 """ 

146 return hasattr(t, "im") 

147 

148 

149# 

150# Constants 

151 

152# transpose 

153class Transpose(IntEnum): 

154 FLIP_LEFT_RIGHT = 0 

155 FLIP_TOP_BOTTOM = 1 

156 ROTATE_90 = 2 

157 ROTATE_180 = 3 

158 ROTATE_270 = 4 

159 TRANSPOSE = 5 

160 TRANSVERSE = 6 

161 

162 

163# transforms (also defined in Imaging.h) 

164class Transform(IntEnum): 

165 AFFINE = 0 

166 EXTENT = 1 

167 PERSPECTIVE = 2 

168 QUAD = 3 

169 MESH = 4 

170 

171 

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

173class Resampling(IntEnum): 

174 NEAREST = 0 

175 BOX = 4 

176 BILINEAR = 2 

177 HAMMING = 5 

178 BICUBIC = 3 

179 LANCZOS = 1 

180 

181 

182_filters_support = { 

183 Resampling.BOX: 0.5, 

184 Resampling.BILINEAR: 1.0, 

185 Resampling.HAMMING: 1.0, 

186 Resampling.BICUBIC: 2.0, 

187 Resampling.LANCZOS: 3.0, 

188} 

189 

190 

191# dithers 

192class Dither(IntEnum): 

193 NONE = 0 

194 ORDERED = 1 # Not yet implemented 

195 RASTERIZE = 2 # Not yet implemented 

196 FLOYDSTEINBERG = 3 # default 

197 

198 

199# palettes/quantizers 

200class Palette(IntEnum): 

201 WEB = 0 

202 ADAPTIVE = 1 

203 

204 

205class Quantize(IntEnum): 

206 MEDIANCUT = 0 

207 MAXCOVERAGE = 1 

208 FASTOCTREE = 2 

209 LIBIMAGEQUANT = 3 

210 

211 

212if hasattr(core, "DEFAULT_STRATEGY"): 212 ↛ 223line 212 didn't jump to line 223, because the condition on line 212 was never false

213 DEFAULT_STRATEGY = core.DEFAULT_STRATEGY 

214 FILTERED = core.FILTERED 

215 HUFFMAN_ONLY = core.HUFFMAN_ONLY 

216 RLE = core.RLE 

217 FIXED = core.FIXED 

218 

219 

220# -------------------------------------------------------------------- 

221# Registries 

222 

223ID = [] 

224OPEN = {} 

225MIME = {} 

226SAVE = {} 

227SAVE_ALL = {} 

228EXTENSION = {} 

229DECODERS = {} 

230ENCODERS = {} 

231 

232# -------------------------------------------------------------------- 

233# Modes 

234 

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

236 

237 

238def _conv_type_shape(im): 

239 m = ImageMode.getmode(im.mode) 

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

241 extra = len(m.bands) 

242 if extra != 1: 

243 shape += (extra,) 

244 return shape, m.typestr 

245 

246 

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

248 

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

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

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

252 

253 

254def getmodebase(mode): 

255 """ 

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

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

258 contain color data. 

259 

260 :param mode: Input mode. 

261 :returns: "L" or "RGB". 

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

263 """ 

264 return ImageMode.getmode(mode).basemode 

265 

266 

267def getmodetype(mode): 

268 """ 

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

270 single-layer mode suitable for storing individual bands. 

271 

272 :param mode: Input mode. 

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

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

275 """ 

276 return ImageMode.getmode(mode).basetype 

277 

278 

279def getmodebandnames(mode): 

280 """ 

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

282 a tuple containing the names of individual bands (use 

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

284 individual band. 

285 

286 :param mode: Input mode. 

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

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

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

290 """ 

291 return ImageMode.getmode(mode).bands 

292 

293 

294def getmodebands(mode): 

295 """ 

296 Gets the number of individual bands for this mode. 

297 

298 :param mode: Input mode. 

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

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

301 """ 

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

303 

304 

305# -------------------------------------------------------------------- 

306# Helpers 

307 

308_initialized = 0 

309 

310 

311def preinit(): 

312 """Explicitly load standard file format drivers.""" 

313 

314 global _initialized 

315 if _initialized >= 1: 

316 return 

317 

318 try: 

319 from . import BmpImagePlugin 

320 

321 assert BmpImagePlugin 

322 except ImportError: 

323 pass 

324 try: 

325 from . import GifImagePlugin 

326 

327 assert GifImagePlugin 

328 except ImportError: 

329 pass 

330 try: 

331 from . import JpegImagePlugin 

332 

333 assert JpegImagePlugin 

334 except ImportError: 

335 pass 

336 try: 

337 from . import PpmImagePlugin 

338 

339 assert PpmImagePlugin 

340 except ImportError: 

341 pass 

342 try: 

343 from . import PngImagePlugin 

344 

345 assert PngImagePlugin 

346 except ImportError: 

347 pass 

348 # try: 

349 # import TiffImagePlugin 

350 # assert TiffImagePlugin 

351 # except ImportError: 

352 # pass 

353 

354 _initialized = 1 

355 

356 

357def init(): 

358 """ 

359 Explicitly initializes the Python Imaging Library. This function 

360 loads all available file format drivers. 

361 """ 

362 

363 global _initialized 

364 if _initialized >= 2: 364 ↛ 365line 364 didn't jump to line 365, because the condition on line 364 was never true

365 return 0 

366 

367 for plugin in _plugins: 

368 try: 

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

370 __import__(f"PIL.{plugin}", globals(), locals(), []) 

371 except ImportError as e: 

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

373 

374 if OPEN or SAVE: 374 ↛ exitline 374 didn't return from function 'init', because the condition on line 374 was never false

375 _initialized = 2 

376 return 1 

377 

378 

379# -------------------------------------------------------------------- 

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

381 

382 

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

384 

385 # tweak arguments 

386 if args is None: 

387 args = () 

388 elif not isinstance(args, tuple): 

389 args = (args,) 

390 

391 try: 

392 decoder = DECODERS[decoder_name] 

393 except KeyError: 

394 pass 

395 else: 

396 return decoder(mode, *args + extra) 

397 

398 try: 

399 # get decoder 

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

401 except AttributeError as e: 

402 raise OSError(f"decoder {decoder_name} not available") from e 

403 return decoder(mode, *args + extra) 

404 

405 

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

407 

408 # tweak arguments 

409 if args is None: 409 ↛ 410line 409 didn't jump to line 410, because the condition on line 409 was never true

410 args = () 

411 elif not isinstance(args, tuple): 411 ↛ 414line 411 didn't jump to line 414, because the condition on line 411 was never false

412 args = (args,) 

413 

414 try: 

415 encoder = ENCODERS[encoder_name] 

416 except KeyError: 

417 pass 

418 else: 

419 return encoder(mode, *args + extra) 

420 

421 try: 

422 # get encoder 

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

424 except AttributeError as e: 

425 raise OSError(f"encoder {encoder_name} not available") from e 

426 return encoder(mode, *args + extra) 

427 

428 

429# -------------------------------------------------------------------- 

430# Simple expression analyzer 

431 

432 

433def coerce_e(value): 

434 deprecate("coerce_e", 10) 

435 return value if isinstance(value, _E) else _E(1, value) 

436 

437 

438# _E(scale, offset) represents the affine transformation scale * x + offset. 

439# The "data" field is named for compatibility with the old implementation, 

440# and should be renamed once coerce_e is removed. 

441class _E: 

442 def __init__(self, scale, data): 

443 self.scale = scale 

444 self.data = data 

445 

446 def __neg__(self): 

447 return _E(-self.scale, -self.data) 

448 

449 def __add__(self, other): 

450 if isinstance(other, _E): 

451 return _E(self.scale + other.scale, self.data + other.data) 

452 return _E(self.scale, self.data + other) 

453 

454 __radd__ = __add__ 

455 

456 def __sub__(self, other): 

457 return self + -other 

458 

459 def __rsub__(self, other): 

460 return other + -self 

461 

462 def __mul__(self, other): 

463 if isinstance(other, _E): 

464 return NotImplemented 

465 return _E(self.scale * other, self.data * other) 

466 

467 __rmul__ = __mul__ 

468 

469 def __truediv__(self, other): 

470 if isinstance(other, _E): 

471 return NotImplemented 

472 return _E(self.scale / other, self.data / other) 

473 

474 

475def _getscaleoffset(expr): 

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

477 return (a.scale, a.data) if isinstance(a, _E) else (0, a) 

478 

479 

480# -------------------------------------------------------------------- 

481# Implementation wrapper 

482 

483 

484class Image: 

485 """ 

486 This class represents an image object. To create 

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

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

489 directly. 

490 

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

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

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

494 """ 

495 

496 format = None 

497 format_description = None 

498 _close_exclusive_fp_after_loading = True 

499 

500 def __init__(self): 

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

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

503 self.im = None 

504 self.mode = "" 

505 self._size = (0, 0) 

506 self.palette = None 

507 self.info = {} 

508 self._category = 0 

509 self.readonly = 0 

510 self.pyaccess = None 

511 self._exif = None 

512 

513 def __getattr__(self, name): 

514 if name == "category": 514 ↛ 515line 514 didn't jump to line 515, because the condition on line 514 was never true

515 deprecate("Image categories", 10, "is_animated", plural=True) 

516 return self._category 

517 raise AttributeError(name) 

518 

519 @property 

520 def width(self): 

521 return self.size[0] 

522 

523 @property 

524 def height(self): 

525 return self.size[1] 

526 

527 @property 

528 def size(self): 

529 return self._size 

530 

531 def _new(self, im): 

532 new = Image() 

533 new.im = im 

534 new.mode = im.mode 

535 new._size = im.size 

536 if im.mode in ("P", "PA"): 536 ↛ 537line 536 didn't jump to line 537, because the condition on line 536 was never true

537 if self.palette: 

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

539 else: 

540 from . import ImagePalette 

541 

542 new.palette = ImagePalette.ImagePalette() 

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

544 return new 

545 

546 # Context manager support 

547 def __enter__(self): 

548 return self 

549 

550 def __exit__(self, *args): 

551 if hasattr(self, "fp") and getattr(self, "_exclusive_fp", False): 

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

553 if self._fp != self.fp: 

554 self._fp.close() 

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

556 if self.fp: 

557 self.fp.close() 

558 self.fp = None 

559 

560 def close(self): 

561 """ 

562 Closes the file pointer, if possible. 

563 

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

565 The image data will be unusable afterward. 

566 

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

568 have not had their file read and closed by the 

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

570 more information. 

571 """ 

572 try: 

573 if getattr(self, "_fp", False): 573 ↛ 574line 573 didn't jump to line 574, because the condition on line 573 was never true

574 if self._fp != self.fp: 

575 self._fp.close() 

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

577 if self.fp: 577 ↛ 578,   577 ↛ 5792 missed branches: 1) line 577 didn't jump to line 578, because the condition on line 577 was never true, 2) line 577 didn't jump to line 579, because the condition on line 577 was never false

578 self.fp.close() 

579 self.fp = None 

580 except Exception as msg: 

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

582 

583 if getattr(self, "map", None): 583 ↛ 584line 583 didn't jump to line 584, because the condition on line 583 was never true

584 self.map = None 

585 

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

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

588 # object is gone. 

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

590 

591 def _copy(self): 

592 self.load() 

593 self.im = self.im.copy() 

594 self.pyaccess = None 

595 self.readonly = 0 

596 

597 def _ensure_mutable(self): 

598 if self.readonly: 598 ↛ 599line 598 didn't jump to line 599, because the condition on line 598 was never true

599 self._copy() 

600 else: 

601 self.load() 

602 

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

604 suffix = "" 

605 if format: 

606 suffix = "." + format 

607 

608 if not file: 

609 f, filename = tempfile.mkstemp(suffix) 

610 os.close(f) 

611 else: 

612 filename = file 

613 if not filename.endswith(suffix): 

614 filename = filename + suffix 

615 

616 self.load() 

617 

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

619 self.im.save_ppm(filename) 

620 else: 

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

622 

623 return filename 

624 

625 def __eq__(self, other): 

626 return ( 

627 self.__class__ is other.__class__ 

628 and self.mode == other.mode 

629 and self.size == other.size 

630 and self.info == other.info 

631 and self._category == other._category 

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

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

634 ) 

635 

636 def __repr__(self): 

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

638 self.__class__.__module__, 

639 self.__class__.__name__, 

640 self.mode, 

641 self.size[0], 

642 self.size[1], 

643 id(self), 

644 ) 

645 

646 def _repr_pretty_(self, p, cycle): 

647 """IPython plain text display support""" 

648 

649 # Same as __repr__ but without unpredicatable id(self), 

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

651 p.text( 

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

653 % ( 

654 self.__class__.__module__, 

655 self.__class__.__name__, 

656 self.mode, 

657 self.size[0], 

658 self.size[1], 

659 ) 

660 ) 

661 

662 def _repr_png_(self): 

663 """iPython display hook support 

664 

665 :returns: png version of the image as bytes 

666 """ 

667 b = io.BytesIO() 

668 try: 

669 self.save(b, "PNG") 

670 except Exception as e: 

671 raise ValueError("Could not save to PNG for display") from e 

672 return b.getvalue() 

673 

674 @property 

675 def __array_interface__(self): 

676 # numpy array interface support 

677 new = {} 

678 shape, typestr = _conv_type_shape(self) 

679 new["shape"] = shape 

680 new["typestr"] = typestr 

681 new["version"] = 3 

682 if self.mode == "1": 

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

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

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

686 else: 

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

688 return new 

689 

690 def __getstate__(self): 

691 return [self.info, self.mode, self.size, self.getpalette(), self.tobytes()] 

692 

693 def __setstate__(self, state): 

694 Image.__init__(self) 

695 self.tile = [] 

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

697 self.info = info 

698 self.mode = mode 

699 self._size = size 

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

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

702 self.putpalette(palette) 

703 self.frombytes(data) 

704 

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

706 """ 

707 Return image as a bytes object. 

708 

709 .. warning:: 

710 

711 This method returns the raw image data from the internal 

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

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

714 data. 

715 

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

717 use the standard "raw" encoder. 

718 :param args: Extra arguments to the encoder. 

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

720 """ 

721 

722 # may pass tuple instead of argument list 

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

724 args = args[0] 

725 

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

727 args = self.mode 

728 

729 self.load() 

730 

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

732 return b"" 

733 

734 # unpack data 

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

736 e.setimage(self.im) 

737 

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

739 

740 data = [] 

741 while True: 

742 l, s, d = e.encode(bufsize) 

743 data.append(d) 

744 if s: 

745 break 

746 if s < 0: 

747 raise RuntimeError(f"encoder error {s} in tobytes") 

748 

749 return b"".join(data) 

750 

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

752 """ 

753 Returns the image converted to an X11 bitmap. 

754 

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

756 

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

758 :returns: A string containing an X11 bitmap. 

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

760 """ 

761 

762 self.load() 

763 if self.mode != "1": 

764 raise ValueError("not a bitmap") 

765 data = self.tobytes("xbm") 

766 return b"".join( 

767 [ 

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

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

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

771 data, 

772 b"};", 

773 ] 

774 ) 

775 

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

777 """ 

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

779 

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

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

782 """ 

783 

784 # may pass tuple instead of argument list 

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

786 args = args[0] 

787 

788 # default format 

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

790 args = self.mode 

791 

792 # unpack data 

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

794 d.setimage(self.im) 

795 s = d.decode(data) 

796 

797 if s[0] >= 0: 

798 raise ValueError("not enough image data") 

799 if s[1] != 0: 

800 raise ValueError("cannot decode image data") 

801 

802 def load(self): 

803 """ 

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

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

806 Image class automatically loads an opened image when it is 

807 accessed for the first time. 

808 

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

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

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

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

813 

814 :returns: An image access object. 

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

816 """ 

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

818 # realize palette 

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

820 self.im.putpalette(mode, arr) 

821 self.palette.dirty = 0 

822 self.palette.rawmode = None 

823 if "transparency" in self.info and mode in ("LA", "PA"): 823 ↛ 824line 823 didn't jump to line 824, because the condition on line 823 was never true

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

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

826 else: 

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

828 self.palette.mode = "RGBA" 

829 else: 

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

831 self.palette.mode = palette_mode 

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

833 

834 if self.im is not None: 834 ↛ exitline 834 didn't return from function 'load', because the condition on line 834 was never false

835 if cffi and USE_CFFI_ACCESS: 835 ↛ 836line 835 didn't jump to line 836, because the condition on line 835 was never true

836 if self.pyaccess: 

837 return self.pyaccess 

838 from . import PyAccess 

839 

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

841 if self.pyaccess: 

842 return self.pyaccess 

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

844 

845 def verify(self): 

846 """ 

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

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

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

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

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

852 file. 

853 """ 

854 pass 

855 

856 def convert( 

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

858 ): 

859 """ 

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

861 method translates pixels through the palette. If mode is 

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

863 and the palette can be represented without a palette. 

864 

865 The current version supports all possible conversions between 

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

867 and "RGB". 

868 

869 When translating a color image to greyscale (mode "L"), 

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

871 

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

873 

874 The default method of converting a greyscale ("L") or "RGB" 

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

876 dither to approximate the original image luminosity levels. If 

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

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

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

880 

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

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

883 and ``dither`` and ``palette`` are ignored. 

884 

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

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

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

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

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

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

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

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

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

894 :data:`Palette.ADAPTIVE`. 

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

896 palette. Defaults to 256. 

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

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

899 """ 

900 

901 self.load() 

902 

903 has_transparency = self.info.get("transparency") is not None 

904 if not mode and self.mode == "P": 904 ↛ 906line 904 didn't jump to line 906, because the condition on line 904 was never true

905 # determine default mode 

906 if self.palette: 

907 mode = self.palette.mode 

908 else: 

909 mode = "RGB" 

910 if mode == "RGB" and has_transparency: 

911 mode = "RGBA" 

912 if not mode or (mode == self.mode and not matrix): 912 ↛ 913line 912 didn't jump to line 913, because the condition on line 912 was never true

913 return self.copy() 

914 

915 if matrix: 915 ↛ 917line 915 didn't jump to line 917, because the condition on line 915 was never true

916 # matrix conversion 

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

918 raise ValueError("illegal conversion") 

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

920 new = self._new(im) 

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

922 transparency = new.info["transparency"] 

923 

924 def convert_transparency(m, v): 

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

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

927 

928 if mode == "L": 

929 transparency = convert_transparency(matrix, transparency) 

930 elif len(mode) == 3: 

931 transparency = tuple( 

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

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

934 ) 

935 new.info["transparency"] = transparency 

936 return new 

937 

938 if mode == "P" and self.mode == "RGBA": 938 ↛ 939line 938 didn't jump to line 939, because the condition on line 938 was never true

939 return self.quantize(colors) 

940 

941 trns = None 

942 delete_trns = False 

943 # transparency handling 

944 if has_transparency: 944 ↛ 945line 944 didn't jump to line 945, because the condition on line 944 was never true

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

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

947 ): 

948 # Use transparent conversion to promote from transparent 

949 # color to an alpha channel. 

950 new_im = self._new( 

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

952 ) 

953 del new_im.info["transparency"] 

954 return new_im 

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

956 t = self.info["transparency"] 

957 if isinstance(t, bytes): 

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

959 warnings.warn( 

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

961 "converted to RGBA images" 

962 ) 

963 delete_trns = True 

964 else: 

965 # get the new transparency color. 

966 # use existing conversions 

967 trns_im = Image()._new(core.new(self.mode, (1, 1))) 

968 if self.mode == "P": 

969 trns_im.putpalette(self.palette) 

970 if isinstance(t, tuple): 

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

972 try: 

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

974 except ValueError as e: 

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

976 # If all 256 colors are in use, 

977 # then there is no need for transparency 

978 t = None 

979 else: 

980 raise ValueError(err) from e 

981 if t is None: 

982 trns = None 

983 else: 

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

985 

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

987 trns_im = trns_im.convert(mode) 

988 else: 

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

990 # after quantization. 

991 trns_im = trns_im.convert("RGB") 

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

993 

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

995 t = self.info["transparency"] 

996 delete_trns = True 

997 

998 if isinstance(t, bytes): 

999 self.im.putpalettealphas(t) 

1000 elif isinstance(t, int): 

1001 self.im.putpalettealpha(t, 0) 

1002 else: 

1003 raise ValueError("Transparency for P mode should be bytes or int") 

1004 

1005 if mode == "P" and palette == Palette.ADAPTIVE: 1005 ↛ 1006line 1005 didn't jump to line 1006, because the condition on line 1005 was never true

1006 im = self.im.quantize(colors) 

1007 new = self._new(im) 

1008 from . import ImagePalette 

1009 

1010 new.palette = ImagePalette.ImagePalette("RGB", new.im.getpalette("RGB")) 

1011 if delete_trns: 

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

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

1014 del new.info["transparency"] 

1015 if trns is not None: 

1016 try: 

1017 new.info["transparency"] = new.palette.getcolor(trns, new) 

1018 except Exception: 

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

1020 # transparency hanging around to mess us up. 

1021 del new.info["transparency"] 

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

1023 return new 

1024 

1025 # colorspace conversion 

1026 if dither is None: 1026 ↛ 1029line 1026 didn't jump to line 1029, because the condition on line 1026 was never false

1027 dither = Dither.FLOYDSTEINBERG 

1028 

1029 try: 

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

1031 except ValueError: 

1032 try: 

1033 # normalize source image and try again 

1034 im = self.im.convert(getmodebase(self.mode)) 

1035 im = im.convert(mode, dither) 

1036 except KeyError as e: 

1037 raise ValueError("illegal conversion") from e 

1038 

1039 new_im = self._new(im) 

1040 if mode == "P" and palette != Palette.ADAPTIVE: 1040 ↛ 1041line 1040 didn't jump to line 1041, because the condition on line 1040 was never true

1041 from . import ImagePalette 

1042 

1043 new_im.palette = ImagePalette.ImagePalette("RGB", list(range(256)) * 3) 

1044 if delete_trns: 1044 ↛ 1046line 1044 didn't jump to line 1046, because the condition on line 1044 was never true

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

1046 del new_im.info["transparency"] 

1047 if trns is not None: 1047 ↛ 1048line 1047 didn't jump to line 1048, because the condition on line 1047 was never true

1048 if new_im.mode == "P": 

1049 try: 

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

1051 except ValueError as e: 

1052 del new_im.info["transparency"] 

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

1054 # If all 256 colors are in use, 

1055 # then there is no need for transparency 

1056 warnings.warn( 

1057 "Couldn't allocate palette entry for transparency" 

1058 ) 

1059 else: 

1060 new_im.info["transparency"] = trns 

1061 return new_im 

1062 

1063 def quantize( 

1064 self, 

1065 colors=256, 

1066 method=None, 

1067 kmeans=0, 

1068 palette=None, 

1069 dither=Dither.FLOYDSTEINBERG, 

1070 ): 

1071 """ 

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

1073 of colors. 

1074 

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

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

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

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

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

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

1081 ``feature="libimagequant"``). 

1082 

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

1084 

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

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

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

1088 :param kmeans: Integer 

1089 :param palette: Quantize to the palette of given 

1090 :py:class:`PIL.Image.Image`. 

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

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

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

1094 (default). 

1095 :returns: A new image 

1096 

1097 """ 

1098 

1099 self.load() 

1100 

1101 if method is None: 

1102 # defaults: 

1103 method = Quantize.MEDIANCUT 

1104 if self.mode == "RGBA": 

1105 method = Quantize.FASTOCTREE 

1106 

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

1108 Quantize.FASTOCTREE, 

1109 Quantize.LIBIMAGEQUANT, 

1110 ): 

1111 # Caller specified an invalid mode. 

1112 raise ValueError( 

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

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

1115 ) 

1116 

1117 if palette: 

1118 # use palette from reference image 

1119 palette.load() 

1120 if palette.mode != "P": 

1121 raise ValueError("bad mode for palette image") 

1122 if self.mode != "RGB" and self.mode != "L": 

1123 raise ValueError( 

1124 "only RGB or L mode images can be quantized to a palette" 

1125 ) 

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

1127 new_im = self._new(im) 

1128 new_im.palette = palette.palette.copy() 

1129 return new_im 

1130 

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

1132 

1133 from . import ImagePalette 

1134 

1135 mode = im.im.getpalettemode() 

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

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

1138 

1139 return im 

1140 

1141 def copy(self): 

1142 """ 

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

1144 into an image, but still retain the original. 

1145 

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

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

1148 """ 

1149 self.load() 

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

1151 

1152 __copy__ = copy 

1153 

1154 def crop(self, box=None): 

1155 """ 

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

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

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

1159 

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

1161 

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

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

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

1165 """ 

1166 

1167 if box is None: 

1168 return self.copy() 

1169 

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

1171 raise ValueError("Coordinate 'right' is less than 'left'") 

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

1173 raise ValueError("Coordinate 'lower' is less than 'upper'") 

1174 

1175 self.load() 

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

1177 

1178 def _crop(self, im, box): 

1179 """ 

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

1181 

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

1183 includes additional sanity checks. 

1184 

1185 :param im: a core image object 

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

1187 :returns: A core image object. 

1188 """ 

1189 

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

1191 

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

1193 

1194 _decompression_bomb_check(absolute_values) 

1195 

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

1197 

1198 def draft(self, mode, size): 

1199 """ 

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

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

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

1203 JPEG to greyscale while loading it. 

1204 

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

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

1207 

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

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

1210 effect. 

1211 

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

1213 currently implemented only for JPEG and MPO images. 

1214 

1215 :param mode: The requested mode. 

1216 :param size: The requested size. 

1217 """ 

1218 pass 

1219 

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

1221 if ymargin is None: 

1222 ymargin = xmargin 

1223 self.load() 

1224 return self._new(self.im.expand(xmargin, ymargin, 0)) 

1225 

1226 def filter(self, filter): 

1227 """ 

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

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

1230 

1231 :param filter: Filter kernel. 

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

1233 

1234 from . import ImageFilter 

1235 

1236 self.load() 

1237 

1238 if isinstance(filter, Callable): 

1239 filter = filter() 

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

1241 raise TypeError( 

1242 "filter argument should be ImageFilter.Filter instance or class" 

1243 ) 

1244 

1245 multiband = isinstance(filter, ImageFilter.MultibandFilter) 

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

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

1248 

1249 ims = [] 

1250 for c in range(self.im.bands): 

1251 ims.append(self._new(filter.filter(self.im.getband(c)))) 

1252 return merge(self.mode, ims) 

1253 

1254 def getbands(self): 

1255 """ 

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

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

1258 

1259 :returns: A tuple containing band names. 

1260 :rtype: tuple 

1261 """ 

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

1263 

1264 def getbbox(self): 

1265 """ 

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

1267 image. 

1268 

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

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

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

1272 method returns None. 

1273 

1274 """ 

1275 

1276 self.load() 

1277 return self.im.getbbox() 

1278 

1279 def getcolors(self, maxcolors=256): 

1280 """ 

1281 Returns a list of colors used in this image. 

1282 

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

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

1285 return the index of the color in the palette. 

1286 

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

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

1289 256 colors. 

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

1291 """ 

1292 

1293 self.load() 

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

1295 h = self.im.histogram() 

1296 out = [] 

1297 for i in range(256): 

1298 if h[i]: 

1299 out.append((h[i], i)) 

1300 if len(out) > maxcolors: 

1301 return None 

1302 return out 

1303 return self.im.getcolors(maxcolors) 

1304 

1305 def getdata(self, band=None): 

1306 """ 

1307 Returns the contents of this image as a sequence object 

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

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

1310 line zero, and so on. 

1311 

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

1313 internal PIL data type, which only supports certain sequence 

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

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

1316 

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

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

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

1320 :returns: A sequence-like object. 

1321 """ 

1322 

1323 self.load() 

1324 if band is not None: 

1325 return self.im.getband(band) 

1326 return self.im # could be abused 

1327 

1328 def getextrema(self): 

1329 """ 

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

1331 the image. 

1332 

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

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

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

1336 """ 

1337 

1338 self.load() 

1339 if self.im.bands > 1: 

1340 extrema = [] 

1341 for i in range(self.im.bands): 

1342 extrema.append(self.im.getband(i).getextrema()) 

1343 return tuple(extrema) 

1344 return self.im.getextrema() 

1345 

1346 def _getxmp(self, xmp_tags): 

1347 def get_name(tag): 

1348 return tag.split("}")[1] 

1349 

1350 def get_value(element): 

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

1352 children = list(element) 

1353 if children: 

1354 for child in children: 

1355 name = get_name(child.tag) 

1356 child_value = get_value(child) 

1357 if name in value: 

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

1359 value[name] = [value[name]] 

1360 value[name].append(child_value) 

1361 else: 

1362 value[name] = child_value 

1363 elif value: 

1364 if element.text: 

1365 value["text"] = element.text 

1366 else: 

1367 return element.text 

1368 return value 

1369 

1370 if ElementTree is None: 

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

1372 return {} 

1373 else: 

1374 root = ElementTree.fromstring(xmp_tags) 

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

1376 

1377 def getexif(self): 

1378 if self._exif is None: 

1379 self._exif = Exif() 

1380 self._exif._loaded = False 

1381 elif self._exif._loaded: 

1382 return self._exif 

1383 self._exif._loaded = True 

1384 

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

1386 if exif_info is None: 

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

1388 exif_info = bytes.fromhex( 

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

1390 ) 

1391 elif hasattr(self, "tag_v2"): 

1392 self._exif.bigtiff = self.tag_v2._bigtiff 

1393 self._exif.endian = self.tag_v2._endian 

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

1395 if exif_info is not None: 

1396 self._exif.load(exif_info) 

1397 

1398 # XMP tags 

1399 if 0x0112 not in self._exif: 

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

1401 if xmp_tags: 

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

1403 if match: 

1404 self._exif[0x0112] = int(match[1]) 

1405 

1406 return self._exif 

1407 

1408 def _reload_exif(self): 

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

1410 return 

1411 self._exif._loaded = False 

1412 self.getexif() 

1413 

1414 def getim(self): 

1415 """ 

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

1417 

1418 :returns: A capsule object. 

1419 """ 

1420 

1421 self.load() 

1422 return self.im.ptr 

1423 

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

1425 """ 

1426 Returns the image palette as a list. 

1427 

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

1429 return the palette in its current mode. 

1430 

1431 .. versionadded:: 9.1.0 

1432 

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

1434 image has no palette. 

1435 """ 

1436 

1437 self.load() 

1438 try: 

1439 mode = self.im.getpalettemode() 

1440 except ValueError: 

1441 return None # no palette 

1442 if rawmode is None: 

1443 rawmode = mode 

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

1445 

1446 def apply_transparency(self): 

1447 """ 

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

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

1450 """ 

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

1452 return 

1453 

1454 from . import ImagePalette 

1455 

1456 palette = self.getpalette("RGBA") 

1457 transparency = self.info["transparency"] 

1458 if isinstance(transparency, bytes): 

1459 for i, alpha in enumerate(transparency): 

1460 palette[i * 4 + 3] = alpha 

1461 else: 

1462 palette[transparency * 4 + 3] = 0 

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

1464 self.palette.dirty = 1 

1465 

1466 del self.info["transparency"] 

1467 

1468 def getpixel(self, xy): 

1469 """ 

1470 Returns the pixel value at a given position. 

1471 

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

1473 :ref:`coordinate-system`. 

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

1475 this method returns a tuple. 

1476 """ 

1477 

1478 self.load() 

1479 if self.pyaccess: 

1480 return self.pyaccess.getpixel(xy) 

1481 return self.im.getpixel(xy) 

1482 

1483 def getprojection(self): 

1484 """ 

1485 Get projection to x and y axes 

1486 

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

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

1489 """ 

1490 

1491 self.load() 

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

1493 return list(x), list(y) 

1494 

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

1496 """ 

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

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

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

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

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

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

1503 

1504 A bilevel image (mode "1") is treated as a greyscale ("L") image 

1505 by this method. 

1506 

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

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

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

1510 bi-level image (mode "1") or a greyscale image ("L"). 

1511 

1512 :param mask: An optional mask. 

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

1514 :returns: A list containing pixel counts. 

1515 """ 

1516 self.load() 

1517 if mask: 

1518 mask.load() 

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

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

1521 if extrema is None: 

1522 extrema = self.getextrema() 

1523 return self.im.histogram(extrema) 

1524 return self.im.histogram() 

1525 

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

1527 """ 

1528 Calculates and returns the entropy for the image. 

1529 

1530 A bilevel image (mode "1") is treated as a greyscale ("L") 

1531 image by this method. 

1532 

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

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

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

1536 either a bi-level image (mode "1") or a greyscale image ("L"). 

1537 

1538 :param mask: An optional mask. 

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

1540 :returns: A float value representing the image entropy 

1541 """ 

1542 self.load() 

1543 if mask: 

1544 mask.load() 

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

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

1547 if extrema is None: 

1548 extrema = self.getextrema() 

1549 return self.im.entropy(extrema) 

1550 return self.im.entropy() 

1551 

1552 def paste(self, im, box=None, mask=None): 

1553 """ 

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

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

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

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

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

1559 

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

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

1562 details). 

1563 

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

1565 containing pixel values. The method then fills the region 

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

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

1568 

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

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

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

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

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

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

1575 channels if they have them. 

1576 

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

1578 combine images with respect to their alpha channels. 

1579 

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

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

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

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

1584 upper left corner. 

1585 

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

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

1588 is interpreted as a mask image. 

1589 :param mask: An optional mask image. 

1590 """ 

1591 

1592 if isImageType(box) and mask is None: 1592 ↛ 1594line 1592 didn't jump to line 1594, because the condition on line 1592 was never true

1593 # abbreviated paste(im, mask) syntax 

1594 mask = box 

1595 box = None 

1596 

1597 if box is None: 1597 ↛ 1600line 1597 didn't jump to line 1600, because the condition on line 1597 was never false

1598 box = (0, 0) 

1599 

1600 if len(box) == 2: 1600 ↛ 1611line 1600 didn't jump to line 1611, because the condition on line 1600 was never false

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

1602 if isImageType(im): 1602 ↛ 1604line 1602 didn't jump to line 1604, because the condition on line 1602 was never false

1603 size = im.size 

1604 elif isImageType(mask): 

1605 size = mask.size 

1606 else: 

1607 # FIXME: use self.size here? 

1608 raise ValueError("cannot determine region size; use 4-item box") 

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

1610 

1611 if isinstance(im, str): 1611 ↛ 1612line 1611 didn't jump to line 1612, because the condition on line 1611 was never true

1612 from . import ImageColor 

1613 

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

1615 

1616 elif isImageType(im): 1616 ↛ 1624line 1616 didn't jump to line 1624, because the condition on line 1616 was never false

1617 im.load() 

1618 if self.mode != im.mode: 1618 ↛ 1622line 1618 didn't jump to line 1622, because the condition on line 1618 was never false

1619 if self.mode != "RGB" or im.mode not in ("LA", "RGBA", "RGBa"): 1619 ↛ 1622line 1619 didn't jump to line 1622, because the condition on line 1619 was never false

1620 # should use an adapter for this! 

1621 im = im.convert(self.mode) 

1622 im = im.im 

1623 

1624 self._ensure_mutable() 

1625 

1626 if mask: 1626 ↛ 1627line 1626 didn't jump to line 1627, because the condition on line 1626 was never true

1627 mask.load() 

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

1629 else: 

1630 self.im.paste(im, box) 

1631 

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

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

1634 onto this image. 

1635 

1636 :param im: image to composite over this one 

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

1638 left corner in this (destination) image. 

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

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

1641 bottom) for the bounds of the source rectangle 

1642 

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

1644 """ 

1645 

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

1647 raise ValueError("Source must be a tuple") 

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

1649 raise ValueError("Destination must be a tuple") 

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

1651 raise ValueError("Source must be a 2 or 4-tuple") 

1652 if not len(dest) == 2: 

1653 raise ValueError("Destination must be a 2-tuple") 

1654 if min(source) < 0: 

1655 raise ValueError("Source must be non-negative") 

1656 

1657 if len(source) == 2: 

1658 source = source + im.size 

1659 

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

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

1662 overlay = im 

1663 else: 

1664 overlay = im.crop(source) 

1665 

1666 # target for the paste 

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

1668 

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

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

1671 background = self 

1672 else: 

1673 background = self.crop(box) 

1674 

1675 result = alpha_composite(background, overlay) 

1676 self.paste(result, box) 

1677 

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

1679 """ 

1680 Maps this image through a lookup table or function. 

1681 

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

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

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

1685 single argument. The function is called once for each 

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

1687 all bands of the image. 

1688 

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

1690 object:: 

1691 

1692 class Example(Image.ImagePointHandler): 

1693 def point(self, data): 

1694 # Return result 

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

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

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

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

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

1700 """ 

1701 

1702 self.load() 

1703 

1704 if isinstance(lut, ImagePointHandler): 

1705 return lut.point(self) 

1706 

1707 if callable(lut): 

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

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

1710 # check if the function can be used with point_transform 

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

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

1713 scale, offset = _getscaleoffset(lut) 

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

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

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

1717 

1718 if self.mode == "F": 

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

1720 raise ValueError("point operation not supported for this mode") 

1721 

1722 if mode != "F": 

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

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

1725 

1726 def putalpha(self, alpha): 

1727 """ 

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

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

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

1731 

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

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

1734 other color value. 

1735 """ 

1736 

1737 self._ensure_mutable() 

1738 

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

1740 # attempt to promote self to a matching alpha mode 

1741 try: 

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

1743 try: 

1744 self.im.setmode(mode) 

1745 except (AttributeError, ValueError) as e: 

1746 # do things the hard way 

1747 im = self.im.convert(mode) 

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

1749 raise ValueError from e # sanity check 

1750 self.im = im 

1751 self.pyaccess = None 

1752 self.mode = self.im.mode 

1753 except KeyError as e: 

1754 raise ValueError("illegal image mode") from e 

1755 

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

1757 band = 1 

1758 else: 

1759 band = 3 

1760 

1761 if isImageType(alpha): 

1762 # alpha layer 

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

1764 raise ValueError("illegal image mode") 

1765 alpha.load() 

1766 if alpha.mode == "1": 

1767 alpha = alpha.convert("L") 

1768 else: 

1769 # constant alpha 

1770 try: 

1771 self.im.fillband(band, alpha) 

1772 except (AttributeError, ValueError): 

1773 # do things the hard way 

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

1775 else: 

1776 return 

1777 

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

1779 

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

1781 """ 

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

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

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

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

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

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

1788 

1789 :param data: A flattened sequence object. 

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

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

1792 """ 

1793 

1794 self._ensure_mutable() 

1795 

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

1797 

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

1799 """ 

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

1801 or "LA" image. 

1802 

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

1804 integer value for each channel in the raw mode. 

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

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

1807 index in the 256 colors. 

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

1809 containing red, green, blue and alpha values. 

1810 

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

1812 

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

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

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

1816 """ 

1817 from . import ImagePalette 

1818 

1819 if self.mode not in ("L", "LA", "P", "PA"): 1819 ↛ 1820line 1819 didn't jump to line 1820, because the condition on line 1819 was never true

1820 raise ValueError("illegal image mode") 

1821 if isinstance(data, ImagePalette.ImagePalette): 1821 ↛ 1822line 1821 didn't jump to line 1822, because the condition on line 1821 was never true

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

1823 else: 

1824 if not isinstance(data, bytes): 1824 ↛ 1826line 1824 didn't jump to line 1826, because the condition on line 1824 was never false

1825 data = bytes(data) 

1826 palette = ImagePalette.raw(rawmode, data) 

1827 self.mode = "PA" if "A" in self.mode else "P" 

1828 self.palette = palette 

1829 self.palette.mode = "RGB" 

1830 self.load() # install new palette 

1831 

1832 def putpixel(self, xy, value): 

1833 """ 

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

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

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

1837 accepted for P images. 

1838 

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

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

1841 module instead. 

1842 

1843 See: 

1844 

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

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

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

1848 

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

1850 :ref:`coordinate-system`. 

1851 :param value: The pixel value. 

1852 """ 

1853 

1854 if self.readonly: 

1855 self._copy() 

1856 self.load() 

1857 

1858 if self.pyaccess: 

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

1860 

1861 if ( 

1862 self.mode == "P" 

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

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

1865 ): 

1866 # RGB or RGBA value for a P image 

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

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

1869 

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

1871 """ 

1872 Rewrites the image to reorder the palette. 

1873 

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

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

1876 is the identity transform. 

1877 :param source_palette: Bytes or None. 

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

1879 

1880 """ 

1881 from . import ImagePalette 

1882 

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

1884 raise ValueError("illegal image mode") 

1885 

1886 bands = 3 

1887 palette_mode = "RGB" 

1888 if source_palette is None: 

1889 if self.mode == "P": 

1890 self.load() 

1891 palette_mode = self.im.getpalettemode() 

1892 if palette_mode == "RGBA": 

1893 bands = 4 

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

1895 else: # L-mode 

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

1897 

1898 palette_bytes = b"" 

1899 new_positions = [0] * 256 

1900 

1901 # pick only the used colors from the palette 

1902 for i, oldPosition in enumerate(dest_map): 

1903 palette_bytes += source_palette[ 

1904 oldPosition * bands : oldPosition * bands + bands 

1905 ] 

1906 new_positions[oldPosition] = i 

1907 

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

1909 

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

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

1912 # from palette 1 to palette 2. New_positions is 

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

1914 # palette 1 with any holes removed. 

1915 

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

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

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

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

1920 # sans palette thus converting the image bytes, then 

1921 # assigning the optimized RGB palette. 

1922 

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

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

1925 

1926 mapping_palette = bytearray(new_positions) 

1927 

1928 m_im = self.copy() 

1929 m_im.mode = "P" 

1930 

1931 m_im.palette = ImagePalette.ImagePalette( 

1932 palette_mode, palette=mapping_palette * bands 

1933 ) 

1934 # possibly set palette dirty, then 

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

1936 # or just force it. 

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

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

1939 

1940 m_im = m_im.convert("L") 

1941 

1942 # Internally, we require 256 palette entries. 

1943 new_palette_bytes = ( 

1944 palette_bytes + ((256 * bands) - len(palette_bytes)) * b"\x00" 

1945 ) 

1946 m_im.putpalette(new_palette_bytes, palette_mode) 

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

1948 

1949 if "transparency" in self.info: 

1950 try: 

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

1952 except ValueError: 

1953 if "transparency" in m_im.info: 

1954 del m_im.info["transparency"] 

1955 

1956 return m_im 

1957 

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

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

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

1961 """ 

1962 filter_support = _filters_support[resample] - 0.5 

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

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

1965 support_x = filter_support * scale_x 

1966 support_y = filter_support * scale_y 

1967 

1968 return ( 

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

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

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

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

1973 ) 

1974 

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

1976 """ 

1977 Returns a resized copy of this image. 

1978 

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

1980 (width, height). 

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

1982 one of :py:data:`PIL.Image.Resampling.NEAREST`, 

1983 :py:data:`PIL.Image.Resampling.BOX`, 

1984 :py:data:`PIL.Image.Resampling.BILINEAR`, 

1985 :py:data:`PIL.Image.Resampling.HAMMING`, 

1986 :py:data:`PIL.Image.Resampling.BICUBIC` or 

1987 :py:data:`PIL.Image.Resampling.LANCZOS`. 

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

1989 :py:data:`PIL.Image.Resampling.NEAREST`. 

1990 If the image mode specifies a number of bits, such as "I;16", then the 

1991 default filter is :py:data:`PIL.Image.Resampling.NEAREST`. 

1992 Otherwise, the default filter is 

1993 :py:data:`PIL.Image.Resampling.BICUBIC`. See: :ref:`concept-filters`. 

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

1995 the source image region to be scaled. 

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

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

1998 :param reducing_gap: Apply optimization by resizing the image 

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

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

2001 Second, resizing using regular resampling. The last step 

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

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

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

2005 the closer the result to the fair resampling. 

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

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

2008 indistinguishable from fair resampling in most cases. 

2009 The default value is None (no optimization). 

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

2011 """ 

2012 

2013 if resample is None: 

2014 type_special = ";" in self.mode 

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

2016 elif resample not in ( 

2017 Resampling.NEAREST, 

2018 Resampling.BILINEAR, 

2019 Resampling.BICUBIC, 

2020 Resampling.LANCZOS, 

2021 Resampling.BOX, 

2022 Resampling.HAMMING, 

2023 ): 

2024 message = f"Unknown resampling filter ({resample})." 

2025 

2026 filters = [ 

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

2028 for filter in ( 

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

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

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

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

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

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

2035 ) 

2036 ] 

2037 raise ValueError( 

2038 message + " Use " + ", ".join(filters[:-1]) + " or " + filters[-1] 

2039 ) 

2040 

2041 if reducing_gap is not None and reducing_gap < 1.0: 

2042 raise ValueError("reducing_gap must be 1.0 or greater") 

2043 

2044 size = tuple(size) 

2045 

2046 self.load() 

2047 if box is None: 

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

2049 else: 

2050 box = tuple(box) 

2051 

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

2053 return self.copy() 

2054 

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

2056 resample = Resampling.NEAREST 

2057 

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

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

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

2061 return im.convert(self.mode) 

2062 

2063 self.load() 

2064 

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

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

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

2068 if factor_x > 1 or factor_y > 1: 

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

2070 factor = (factor_x, factor_y) 

2071 if callable(self.reduce): 

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

2073 else: 

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

2075 box = ( 

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

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

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

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

2080 ) 

2081 

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

2083 

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

2085 """ 

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

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

2088 the resulting size will be rounded up. 

2089 

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

2091 for width and height separately. 

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

2093 the source image region to be reduced. 

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

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

2096 """ 

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

2098 factor = (factor, factor) 

2099 

2100 if box is None: 

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

2102 else: 

2103 box = tuple(box) 

2104 

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

2106 return self.copy() 

2107 

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

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

2110 im = im.reduce(factor, box) 

2111 return im.convert(self.mode) 

2112 

2113 self.load() 

2114 

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

2116 

2117 def rotate( 

2118 self, 

2119 angle, 

2120 resample=Resampling.NEAREST, 

2121 expand=0, 

2122 center=None, 

2123 translate=None, 

2124 fillcolor=None, 

2125 ): 

2126 """ 

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

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

2129 clockwise around its centre. 

2130 

2131 :param angle: In degrees counter clockwise. 

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

2133 one of :py:data:`PIL.Image.Resampling.NEAREST` (use nearest neighbour), 

2134 :py:data:`PIL.Image.BILINEAR` (linear interpolation in a 2x2 

2135 environment), or :py:data:`PIL.Image.Resampling.BICUBIC` 

2136 (cubic spline interpolation in a 4x4 environment). 

2137 If omitted, or if the image has mode "1" or "P", it is 

2138 set to :py:data:`PIL.Image.Resampling.NEAREST`. See :ref:`concept-filters`. 

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

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

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

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

2143 the center and no translation. 

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

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

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

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

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

2149 """ 

2150 

2151 angle = angle % 360.0 

2152 

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

2154 # translating or changing the center. 

2155 if not (center or translate): 

2156 if angle == 0: 

2157 return self.copy() 

2158 if angle == 180: 

2159 return self.transpose(Transpose.ROTATE_180) 

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

2161 return self.transpose( 

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

2163 ) 

2164 

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

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

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

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

2169 

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

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

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

2173 # (0, 0, 1) (0, 0, 1) ( 0, 0, 1) (0, 0, 1) 

2174 

2175 # The reverse matrix is thus: 

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

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

2178 # (0, 0, 1) ( 0, 0, 1) (0, 0, 1) (0, 0, 1) 

2179 

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

2181 # compensate for the expand flag. 

2182 

2183 w, h = self.size 

2184 

2185 if translate is None: 

2186 post_trans = (0, 0) 

2187 else: 

2188 post_trans = translate 

2189 if center is None: 

2190 # FIXME These should be rounded to ints? 

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

2192 else: 

2193 rotn_center = center 

2194 

2195 angle = -math.radians(angle) 

2196 matrix = [ 

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

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

2199 0.0, 

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

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

2202 0.0, 

2203 ] 

2204 

2205 def transform(x, y, matrix): 

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

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

2208 

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

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

2211 ) 

2212 matrix[2] += rotn_center[0] 

2213 matrix[5] += rotn_center[1] 

2214 

2215 if expand: 

2216 # calculate output size 

2217 xx = [] 

2218 yy = [] 

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

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

2221 xx.append(x) 

2222 yy.append(y) 

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

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

2225 

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

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

2228 # translation vector as new translation vector. 

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

2230 w, h = nw, nh 

2231 

2232 return self.transform( 

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

2234 ) 

2235 

2236 def save(self, fp, format=None, **params): 

2237 """ 

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

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

2240 extension, if possible. 

2241 

2242 Keyword options can be used to provide additional instructions 

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

2244 silently ignored. The available options are described in the 

2245 :doc:`image format documentation 

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

2247 

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

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

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

2251 methods, and be opened in binary mode. 

2252 

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

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

2255 format to use is determined from the filename extension. 

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

2257 parameter should always be used. 

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

2259 :returns: None 

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

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

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

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

2264 """ 

2265 

2266 filename = "" 

2267 open_fp = False 

2268 if isinstance(fp, Path): 2268 ↛ 2269line 2268 didn't jump to line 2269, because the condition on line 2268 was never true

2269 filename = str(fp) 

2270 open_fp = True 

2271 elif is_path(fp): 2271 ↛ 2272line 2271 didn't jump to line 2272, because the condition on line 2271 was never true

2272 filename = fp 

2273 open_fp = True 

2274 elif fp == sys.stdout: 2274 ↛ 2275line 2274 didn't jump to line 2275, because the condition on line 2274 was never true

2275 try: 

2276 fp = sys.stdout.buffer 

2277 except AttributeError: 

2278 pass 

2279 if not filename and hasattr(fp, "name") and is_path(fp.name): 2279 ↛ 2281line 2279 didn't jump to line 2281, because the condition on line 2279 was never true

2280 # only set the name for metadata purposes 

2281 filename = fp.name 

2282 

2283 # may mutate self! 

2284 self._ensure_mutable() 

2285 

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

2287 self.encoderinfo = params 

2288 self.encoderconfig = () 

2289 

2290 preinit() 

2291 

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

2293 

2294 if not format: 2294 ↛ 2295line 2294 didn't jump to line 2295, because the condition on line 2294 was never true

2295 if ext not in EXTENSION: 

2296 init() 

2297 try: 

2298 format = EXTENSION[ext] 

2299 except KeyError as e: 

2300 raise ValueError(f"unknown file extension: {ext}") from e 

2301 

2302 if format.upper() not in SAVE: 2302 ↛ 2303line 2302 didn't jump to line 2303, because the condition on line 2302 was never true

2303 init() 

2304 if save_all: 2304 ↛ 2305line 2304 didn't jump to line 2305, because the condition on line 2304 was never true

2305 save_handler = SAVE_ALL[format.upper()] 

2306 else: 

2307 save_handler = SAVE[format.upper()] 

2308 

2309 created = False 

2310 if open_fp: 2310 ↛ 2311line 2310 didn't jump to line 2311, because the condition on line 2310 was never true

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

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

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

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

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

2316 else: 

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

2318 

2319 try: 

2320 save_handler(self, fp, filename) 

2321 except Exception: 

2322 if open_fp: 

2323 fp.close() 

2324 if created: 

2325 try: 

2326 os.remove(filename) 

2327 except PermissionError: 

2328 pass 

2329 raise 

2330 if open_fp: 2330 ↛ 2331line 2330 didn't jump to line 2331, because the condition on line 2330 was never true

2331 fp.close() 

2332 

2333 def seek(self, frame): 

2334 """ 

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

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

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

2338 library automatically seeks to frame 0. 

2339 

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

2341 

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

2343 number of available frames. 

2344 

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

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

2347 of the sequence. 

2348 """ 

2349 

2350 # overridden by file handlers 

2351 if frame != 0: 

2352 raise EOFError 

2353 

2354 def show(self, title=None): 

2355 """ 

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

2357 

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

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

2360 

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

2362 PNG format. 

2363 

2364 On Unix, the image is then opened using the **display**, **eog** or 

2365 **xv** utility, depending on which one can be found. 

2366 

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

2368 

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

2370 

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

2372 """ 

2373 

2374 _show(self, title=title) 

2375 

2376 def split(self): 

2377 """ 

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

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

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

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

2382 blue). 

2383 

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

2385 method can be more convenient and faster. 

2386 

2387 :returns: A tuple containing bands. 

2388 """ 

2389 

2390 self.load() 

2391 if self.im.bands == 1: 

2392 ims = [self.copy()] 

2393 else: 

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

2395 return tuple(ims) 

2396 

2397 def getchannel(self, channel): 

2398 """ 

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

2400 

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

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

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

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

2405 

2406 .. versionadded:: 4.3.0 

2407 """ 

2408 self.load() 

2409 

2410 if isinstance(channel, str): 

2411 try: 

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

2413 except ValueError as e: 

2414 raise ValueError(f'The image has no channel "{channel}"') from e 

2415 

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

2417 

2418 def tell(self): 

2419 """ 

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

2421 

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

2423 number of available frames. 

2424 

2425 :returns: Frame number, starting with 0. 

2426 """ 

2427 return 0 

2428 

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

2430 """ 

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

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

2433 the given size. This method calculates an appropriate thumbnail 

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

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

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

2437 

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

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

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

2441 image. 

2442 

2443 :param size: Requested size. 

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

2445 of :py:data:`PIL.Image.Resampling.NEAREST`, 

2446 :py:data:`PIL.Image.Resampling.BOX`, 

2447 :py:data:`PIL.Image.Resampling.BILINEAR`, 

2448 :py:data:`PIL.Image.Resampling.HAMMING`, 

2449 :py:data:`PIL.Image.Resampling.BICUBIC` or 

2450 :py:data:`PIL.Image.Resampling.LANCZOS`. 

2451 If omitted, it defaults to :py:data:`PIL.Image.Resampling.BICUBIC`. 

2452 (was :py:data:`PIL.Image.Resampling.NEAREST` prior to version 2.5.0). 

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

2454 :param reducing_gap: Apply optimization by resizing the image 

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

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

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

2458 Second, resizing using regular resampling. The last step 

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

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

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

2462 the closer the result to the fair resampling. 

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

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

2465 indistinguishable from fair resampling in most cases. 

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

2467 while still being faster in many cases). 

2468 :returns: None 

2469 """ 

2470 

2471 self.load() 

2472 x, y = map(math.floor, size) 

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

2474 return 

2475 

2476 def round_aspect(number, key): 

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

2478 

2479 # preserve aspect ratio 

2480 aspect = self.width / self.height 

2481 if x / y >= aspect: 

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

2483 else: 

2484 y = round_aspect( 

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

2486 ) 

2487 size = (x, y) 

2488 

2489 box = None 

2490 if reducing_gap is not None: 

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

2492 if res is not None: 

2493 box = res[1] 

2494 

2495 if self.size != size: 

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

2497 

2498 self.im = im.im 

2499 self._size = size 

2500 self.mode = self.im.mode 

2501 

2502 self.readonly = 0 

2503 self.pyaccess = None 

2504 

2505 # FIXME: the different transform methods need further explanation 

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

2507 def transform( 

2508 self, 

2509 size, 

2510 method, 

2511 data=None, 

2512 resample=Resampling.NEAREST, 

2513 fill=1, 

2514 fillcolor=None, 

2515 ): 

2516 """ 

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

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

2519 to the new image using the given transform. 

2520 

2521 :param size: The output size. 

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

2523 :py:data:`PIL.Image.Transform.EXTENT` (cut out a rectangular subregion), 

2524 :py:data:`PIL.Image.Transform.AFFINE` (affine transform), 

2525 :py:data:`PIL.Image.Transform.PERSPECTIVE` (perspective transform), 

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

2527 :py:data:`PIL.Image.Transform.MESH` (map a number of source quadrilaterals 

2528 in one operation). 

2529 

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

2531 object:: 

2532 

2533 class Example(Image.ImageTransformHandler): 

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

2535 # Return result 

2536 

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

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

2539 

2540 class Example: 

2541 def getdata(self): 

2542 method = Image.Transform.EXTENT 

2543 data = (0, 0, 100, 100) 

2544 return method, data 

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

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

2547 :py:data:`PIL.Image.Resampling.NEAREST` (use nearest neighbour), 

2548 :py:data:`PIL.Image.Resampling.BILINEAR` (linear interpolation in a 2x2 

2549 environment), or :py:data:`PIL.Image.BICUBIC` (cubic spline 

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

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

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

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

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

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

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

2557 transform in the output image. 

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

2559 """ 

2560 

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

2562 return ( 

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

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

2565 .convert(self.mode) 

2566 ) 

2567 

2568 if isinstance(method, ImageTransformHandler): 

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

2570 

2571 if hasattr(method, "getdata"): 

2572 # compatibility w. old-style transform objects 

2573 method, data = method.getdata() 

2574 

2575 if data is None: 

2576 raise ValueError("missing method data") 

2577 

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

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

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

2581 im.info = self.info.copy() 

2582 if method == Transform.MESH: 

2583 # list of quads 

2584 for box, quad in data: 

2585 im.__transformer( 

2586 box, self, Transform.QUAD, quad, resample, fillcolor is None 

2587 ) 

2588 else: 

2589 im.__transformer( 

2590 (0, 0) + size, self, method, data, resample, fillcolor is None 

2591 ) 

2592 

2593 return im 

2594 

2595 def __transformer( 

2596 self, box, image, method, data, resample=Resampling.NEAREST, fill=1 

2597 ): 

2598 w = box[2] - box[0] 

2599 h = box[3] - box[1] 

2600 

2601 if method == Transform.AFFINE: 

2602 data = data[:6] 

2603 

2604 elif method == Transform.EXTENT: 

2605 # convert extent to an affine transform 

2606 x0, y0, x1, y1 = data 

2607 xs = (x1 - x0) / w 

2608 ys = (y1 - y0) / h 

2609 method = Transform.AFFINE 

2610 data = (xs, 0, x0, 0, ys, y0) 

2611 

2612 elif method == Transform.PERSPECTIVE: 

2613 data = data[:8] 

2614 

2615 elif method == Transform.QUAD: 

2616 # quadrilateral warp. data specifies the four corners 

2617 # given as NW, SW, SE, and NE. 

2618 nw = data[:2] 

2619 sw = data[2:4] 

2620 se = data[4:6] 

2621 ne = data[6:8] 

2622 x0, y0 = nw 

2623 As = 1.0 / w 

2624 At = 1.0 / h 

2625 data = ( 

2626 x0, 

2627 (ne[0] - x0) * As, 

2628 (sw[0] - x0) * At, 

2629 (se[0] - sw[0] - ne[0] + x0) * As * At, 

2630 y0, 

2631 (ne[1] - y0) * As, 

2632 (sw[1] - y0) * At, 

2633 (se[1] - sw[1] - ne[1] + y0) * As * At, 

2634 ) 

2635 

2636 else: 

2637 raise ValueError("unknown transformation method") 

2638 

2639 if resample not in ( 

2640 Resampling.NEAREST, 

2641 Resampling.BILINEAR, 

2642 Resampling.BICUBIC, 

2643 ): 

2644 if resample in (Resampling.BOX, Resampling.HAMMING, Resampling.LANCZOS): 

2645 message = { 

2646 Resampling.BOX: "Image.Resampling.BOX", 

2647 Resampling.HAMMING: "Image.Resampling.HAMMING", 

2648 Resampling.LANCZOS: "Image.Resampling.LANCZOS", 

2649 }[resample] + f" ({resample}) cannot be used." 

2650 else: 

2651 message = f"Unknown resampling filter ({resample})." 

2652 

2653 filters = [ 

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

2655 for filter in ( 

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

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

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

2659 ) 

2660 ] 

2661 raise ValueError( 

2662 message + " Use " + ", ".join(filters[:-1]) + " or " + filters[-1] 

2663 ) 

2664 

2665 image.load() 

2666 

2667 self.load() 

2668 

2669 if image.mode in ("1", "P"): 

2670 resample = Resampling.NEAREST 

2671 

2672 self.im.transform2(box, image.im, method, data, resample, fill) 

2673 

2674 def transpose(self, method): 

2675 """ 

2676 Transpose image (flip or rotate in 90 degree steps) 

2677 

2678 :param method: One of :py:data:`PIL.Image.Transpose.FLIP_LEFT_RIGHT`, 

2679 :py:data:`PIL.Image.Transpose.FLIP_TOP_BOTTOM`, 

2680 :py:data:`PIL.Image.Transpose.ROTATE_90`, 

2681 :py:data:`PIL.Image.Transpose.ROTATE_180`, 

2682 :py:data:`PIL.Image.Transpose.ROTATE_270`, 

2683 :py:data:`PIL.Image.Transpose.TRANSPOSE` or 

2684 :py:data:`PIL.Image.Transpose.TRANSVERSE`. 

2685 :returns: Returns a flipped or rotated copy of this image. 

2686 """ 

2687 

2688 self.load() 

2689 return self._new(self.im.transpose(method)) 

2690 

2691 def effect_spread(self, distance): 

2692 """ 

2693 Randomly spread pixels in an image. 

2694 

2695 :param distance: Distance to spread pixels. 

2696 """ 

2697 self.load() 

2698 return self._new(self.im.effect_spread(distance)) 

2699 

2700 def toqimage(self): 

2701 """Returns a QImage copy of this image""" 

2702 from . import ImageQt 

2703 

2704 if not ImageQt.qt_is_installed: 

2705 raise ImportError("Qt bindings are not installed") 

2706 return ImageQt.toqimage(self) 

2707 

2708 def toqpixmap(self): 

2709 """Returns a QPixmap copy of this image""" 

2710 from . import ImageQt 

2711 

2712 if not ImageQt.qt_is_installed: 

2713 raise ImportError("Qt bindings are not installed") 

2714 return ImageQt.toqpixmap(self) 

2715 

2716 

2717# -------------------------------------------------------------------- 

2718# Abstract handlers. 

2719 

2720 

2721class ImagePointHandler: 

2722 """ 

2723 Used as a mixin by point transforms 

2724 (for use with :py:meth:`~PIL.Image.Image.point`) 

2725 """ 

2726 

2727 pass 

2728 

2729 

2730class ImageTransformHandler: 

2731 """ 

2732 Used as a mixin by geometry transforms 

2733 (for use with :py:meth:`~PIL.Image.Image.transform`) 

2734 """ 

2735 

2736 pass 

2737 

2738 

2739# -------------------------------------------------------------------- 

2740# Factories 

2741 

2742# 

2743# Debugging 

2744 

2745 

2746def _wedge(): 

2747 """Create greyscale wedge (for debugging only)""" 

2748 

2749 return Image()._new(core.wedge("L")) 

2750 

2751 

2752def _check_size(size): 

2753 """ 

2754 Common check to enforce type and sanity check on size tuples 

2755 

2756 :param size: Should be a 2 tuple of (width, height) 

2757 :returns: True, or raises a ValueError 

2758 """ 

2759 

2760 if not isinstance(size, (list, tuple)): 2760 ↛ 2761line 2760 didn't jump to line 2761, because the condition on line 2760 was never true

2761 raise ValueError("Size must be a tuple") 

2762 if len(size) != 2: 2762 ↛ 2763line 2762 didn't jump to line 2763, because the condition on line 2762 was never true

2763 raise ValueError("Size must be a tuple of length 2") 

2764 if size[0] < 0 or size[1] < 0: 2764 ↛ 2765line 2764 didn't jump to line 2765, because the condition on line 2764 was never true

2765 raise ValueError("Width and height must be >= 0") 

2766 

2767 return True 

2768 

2769 

2770def new(mode, size, color=0): 

2771 """ 

2772 Creates a new image with the given mode and size. 

2773 

2774 :param mode: The mode to use for the new image. See: 

2775 :ref:`concept-modes`. 

2776 :param size: A 2-tuple, containing (width, height) in pixels. 

2777 :param color: What color to use for the image. Default is black. 

2778 If given, this should be a single integer or floating point value 

2779 for single-band modes, and a tuple for multi-band modes (one value 

2780 per band). When creating RGB images, you can also use color 

2781 strings as supported by the ImageColor module. If the color is 

2782 None, the image is not initialised. 

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

2784 """ 

2785 

2786 _check_size(size) 

2787 

2788 if color is None: 2788 ↛ 2790line 2788 didn't jump to line 2790, because the condition on line 2788 was never true

2789 # don't initialize 

2790 return Image()._new(core.new(mode, size)) 

2791 

2792 if isinstance(color, str): 

2793 # css3-style specifier 

2794 

2795 from . import ImageColor 

2796 

2797 color = ImageColor.getcolor(color, mode) 

2798 

2799 im = Image() 

2800 if mode == "P" and isinstance(color, (list, tuple)) and len(color) in [3, 4]: 2800 ↛ 2802line 2800 didn't jump to line 2802, because the condition on line 2800 was never true

2801 # RGB or RGBA value for a P image 

2802 from . import ImagePalette 

2803 

2804 im.palette = ImagePalette.ImagePalette() 

2805 color = im.palette.getcolor(color) 

2806 return im._new(core.fill(mode, size, color)) 

2807 

2808 

2809def frombytes(mode, size, data, decoder_name="raw", *args): 

2810 """ 

2811 Creates a copy of an image memory from pixel data in a buffer. 

2812 

2813 In its simplest form, this function takes three arguments 

2814 (mode, size, and unpacked pixel data). 

2815 

2816 You can also use any pixel decoder supported by PIL. For more 

2817 information on available decoders, see the section 

2818 :ref:`Writing Your Own File Codec <file-codecs>`. 

2819 

2820 Note that this function decodes pixel data only, not entire images. 

2821 If you have an entire image in a string, wrap it in a 

2822 :py:class:`~io.BytesIO` object, and use :py:func:`~PIL.Image.open` to load 

2823 it. 

2824 

2825 :param mode: The image mode. See: :ref:`concept-modes`. 

2826 :param size: The image size. 

2827 :param data: A byte buffer containing raw data for the given mode. 

2828 :param decoder_name: What decoder to use. 

2829 :param args: Additional parameters for the given decoder. 

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

2831 """ 

2832 

2833 _check_size(size) 

2834 

2835 # may pass tuple instead of argument list 

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

2837 args = args[0] 

2838 

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

2840 args = mode 

2841 

2842 im = new(mode, size) 

2843 im.frombytes(data, decoder_name, args) 

2844 return im 

2845 

2846 

2847def frombuffer(mode, size, data, decoder_name="raw", *args): 

2848 """ 

2849 Creates an image memory referencing pixel data in a byte buffer. 

2850 

2851 This function is similar to :py:func:`~PIL.Image.frombytes`, but uses data 

2852 in the byte buffer, where possible. This means that changes to the 

2853 original buffer object are reflected in this image). Not all modes can 

2854 share memory; supported modes include "L", "RGBX", "RGBA", and "CMYK". 

2855 

2856 Note that this function decodes pixel data only, not entire images. 

2857 If you have an entire image file in a string, wrap it in a 

2858 :py:class:`~io.BytesIO` object, and use :py:func:`~PIL.Image.open` to load it. 

2859 

2860 In the current version, the default parameters used for the "raw" decoder 

2861 differs from that used for :py:func:`~PIL.Image.frombytes`. This is a 

2862 bug, and will probably be fixed in a future release. The current release 

2863 issues a warning if you do this; to disable the warning, you should provide 

2864 the full set of parameters. See below for details. 

2865 

2866 :param mode: The image mode. See: :ref:`concept-modes`. 

2867 :param size: The image size. 

2868 :param data: A bytes or other buffer object containing raw 

2869 data for the given mode. 

2870 :param decoder_name: What decoder to use. 

2871 :param args: Additional parameters for the given decoder. For the 

2872 default encoder ("raw"), it's recommended that you provide the 

2873 full set of parameters:: 

2874 

2875 frombuffer(mode, size, data, "raw", mode, 0, 1) 

2876 

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

2878 

2879 .. versionadded:: 1.1.4 

2880 """ 

2881 

2882 _check_size(size) 

2883 

2884 # may pass tuple instead of argument list 

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

2886 args = args[0] 

2887 

2888 if decoder_name == "raw": 

2889 if args == (): 

2890 args = mode, 0, 1 

2891 if args[0] in _MAPMODES: 

2892 im = new(mode, (1, 1)) 

2893 im = im._new(core.map_buffer(data, size, decoder_name, 0, args)) 

2894 if mode == "P": 

2895 from . import ImagePalette 

2896 

2897 im.palette = ImagePalette.ImagePalette("RGB", im.im.getpalette("RGB")) 

2898 im.readonly = 1 

2899 return im 

2900 

2901 return frombytes(mode, size, data, decoder_name, args) 

2902 

2903 

2904def fromarray(obj, mode=None): 

2905 """ 

2906 Creates an image memory from an object exporting the array interface 

2907 (using the buffer protocol). 

2908 

2909 If ``obj`` is not contiguous, then the ``tobytes`` method is called 

2910 and :py:func:`~PIL.Image.frombuffer` is used. 

2911 

2912 If you have an image in NumPy:: 

2913 

2914 from PIL import Image 

2915 import numpy as np 

2916 im = Image.open("hopper.jpg") 

2917 a = np.asarray(im) 

2918 

2919 Then this can be used to convert it to a Pillow image:: 

2920 

2921 im = Image.fromarray(a) 

2922 

2923 :param obj: Object with array interface 

2924 :param mode: Optional mode to use when reading ``obj``. Will be determined from 

2925 type if ``None``. 

2926 

2927 This will not be used to convert the data after reading, but will be used to 

2928 change how the data is read:: 

2929 

2930 from PIL import Image 

2931 import numpy as np 

2932 a = np.full((1, 1), 300) 

2933 im = Image.fromarray(a, mode="L") 

2934 im.getpixel((0, 0)) # 44 

2935 im = Image.fromarray(a, mode="RGB") 

2936 im.getpixel((0, 0)) # (44, 1, 0) 

2937 

2938 See: :ref:`concept-modes` for general information about modes. 

2939 :returns: An image object. 

2940 

2941 .. versionadded:: 1.1.6 

2942 """ 

2943 arr = obj.__array_interface__ 

2944 shape = arr["shape"] 

2945 ndim = len(shape) 

2946 strides = arr.get("strides", None) 

2947 if mode is None: 

2948 try: 

2949 typekey = (1, 1) + shape[2:], arr["typestr"] 

2950 except KeyError as e: 

2951 raise TypeError("Cannot handle this data type") from e 

2952 try: 

2953 mode, rawmode = _fromarray_typemap[typekey] 

2954 except KeyError as e: 

2955 raise TypeError("Cannot handle this data type: %s, %s" % typekey) from e 

2956 else: 

2957 rawmode = mode 

2958 if mode in ["1", "L", "I", "P", "F"]: 

2959 ndmax = 2 

2960 elif mode == "RGB": 

2961 ndmax = 3 

2962 else: 

2963 ndmax = 4 

2964 if ndim > ndmax: 

2965 raise ValueError(f"Too many dimensions: {ndim} > {ndmax}.") 

2966 

2967 size = 1 if ndim == 1 else shape[1], shape[0] 

2968 if strides is not None: 

2969 if hasattr(obj, "tobytes"): 

2970 obj = obj.tobytes() 

2971 else: 

2972 obj = obj.tostring() 

2973 

2974 return frombuffer(mode, size, obj, "raw", rawmode, 0, 1) 

2975 

2976 

2977def fromqimage(im): 

2978 """Creates an image instance from a QImage image""" 

2979 from . import ImageQt 

2980 

2981 if not ImageQt.qt_is_installed: 

2982 raise ImportError("Qt bindings are not installed") 

2983 return ImageQt.fromqimage(im) 

2984 

2985 

2986def fromqpixmap(im): 

2987 """Creates an image instance from a QPixmap image""" 

2988 from . import ImageQt 

2989 

2990 if not ImageQt.qt_is_installed: 

2991 raise ImportError("Qt bindings are not installed") 

2992 return ImageQt.fromqpixmap(im) 

2993 

2994 

2995_fromarray_typemap = { 

2996 # (shape, typestr) => mode, rawmode 

2997 # first two members of shape are set to one 

2998 ((1, 1), "|b1"): ("1", "1;8"), 

2999 ((1, 1), "|u1"): ("L", "L"), 

3000 ((1, 1), "|i1"): ("I", "I;8"), 

3001 ((1, 1), "<u2"): ("I", "I;16"), 

3002 ((1, 1), ">u2"): ("I", "I;16B"), 

3003 ((1, 1), "<i2"): ("I", "I;16S"), 

3004 ((1, 1), ">i2"): ("I", "I;16BS"), 

3005 ((1, 1), "<u4"): ("I", "I;32"), 

3006 ((1, 1), ">u4"): ("I", "I;32B"), 

3007 ((1, 1), "<i4"): ("I", "I;32S"), 

3008 ((1, 1), ">i4"): ("I", "I;32BS"), 

3009 ((1, 1), "<f4"): ("F", "F;32F"), 

3010 ((1, 1), ">f4"): ("F", "F;32BF"), 

3011 ((1, 1), "<f8"): ("F", "F;64F"), 

3012 ((1, 1), ">f8"): ("F", "F;64BF"), 

3013 ((1, 1, 2), "|u1"): ("LA", "LA"), 

3014 ((1, 1, 3), "|u1"): ("RGB", "RGB"), 

3015 ((1, 1, 4), "|u1"): ("RGBA", "RGBA"), 

3016 # shortcuts: 

3017 ((1, 1), _ENDIAN + "i4"): ("I", "I"), 

3018 ((1, 1), _ENDIAN + "f4"): ("F", "F"), 

3019} 

3020 

3021 

3022def _decompression_bomb_check(size): 

3023 if MAX_IMAGE_PIXELS is None: 3023 ↛ 3024line 3023 didn't jump to line 3024, because the condition on line 3023 was never true

3024 return 

3025 

3026 pixels = size[0] * size[1] 

3027 

3028 if pixels > 2 * MAX_IMAGE_PIXELS: 3028 ↛ 3029line 3028 didn't jump to line 3029, because the condition on line 3028 was never true

3029 raise DecompressionBombError( 

3030 f"Image size ({pixels} pixels) exceeds limit of {2 * MAX_IMAGE_PIXELS} " 

3031 "pixels, could be decompression bomb DOS attack." 

3032 ) 

3033 

3034 if pixels > MAX_IMAGE_PIXELS: 3034 ↛ 3035line 3034 didn't jump to line 3035, because the condition on line 3034 was never true

3035 warnings.warn( 

3036 f"Image size ({pixels} pixels) exceeds limit of {MAX_IMAGE_PIXELS} pixels, " 

3037 "could be decompression bomb DOS attack.", 

3038 DecompressionBombWarning, 

3039 ) 

3040 

3041 

3042def open(fp, mode="r", formats=None): 

3043 """ 

3044 Opens and identifies the given image file. 

3045 

3046 This is a lazy operation; this function identifies the file, but 

3047 the file remains open and the actual image data is not read from 

3048 the file until you try to process the data (or call the 

3049 :py:meth:`~PIL.Image.Image.load` method). See 

3050 :py:func:`~PIL.Image.new`. See :ref:`file-handling`. 

3051 

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

3053 The file object must implement ``file.read``, 

3054 ``file.seek``, and ``file.tell`` methods, 

3055 and be opened in binary mode. 

3056 :param mode: The mode. If given, this argument must be "r". 

3057 :param formats: A list or tuple of formats to attempt to load the file in. 

3058 This can be used to restrict the set of formats checked. 

3059 Pass ``None`` to try all supported formats. You can print the set of 

3060 available formats by running ``python3 -m PIL`` or using 

3061 the :py:func:`PIL.features.pilinfo` function. 

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

3063 :exception FileNotFoundError: If the file cannot be found. 

3064 :exception PIL.UnidentifiedImageError: If the image cannot be opened and 

3065 identified. 

3066 :exception ValueError: If the ``mode`` is not "r", or if a ``StringIO`` 

3067 instance is used for ``fp``. 

3068 :exception TypeError: If ``formats`` is not ``None``, a list or a tuple. 

3069 """ 

3070 

3071 if mode != "r": 3071 ↛ 3072line 3071 didn't jump to line 3072, because the condition on line 3071 was never true

3072 raise ValueError(f"bad mode {repr(mode)}") 

3073 elif isinstance(fp, io.StringIO): 3073 ↛ 3074line 3073 didn't jump to line 3074, because the condition on line 3073 was never true

3074 raise ValueError( 

3075 "StringIO cannot be used to open an image. " 

3076 "Binary data must be used instead." 

3077 ) 

3078 

3079 if formats is None: 3079 ↛ 3081line 3079 didn't jump to line 3081, because the condition on line 3079 was never false

3080 formats = ID 

3081 elif not isinstance(formats, (list, tuple)): 

3082 raise TypeError("formats must be a list or tuple") 

3083 

3084 exclusive_fp = False 

3085 filename = "" 

3086 if isinstance(fp, Path): 3086 ↛ 3087line 3086 didn't jump to line 3087, because the condition on line 3086 was never true

3087 filename = str(fp.resolve()) 

3088 elif is_path(fp): 3088 ↛ 3089line 3088 didn't jump to line 3089, because the condition on line 3088 was never true

3089 filename = fp 

3090 

3091 if filename: 3091 ↛ 3092line 3091 didn't jump to line 3092, because the condition on line 3091 was never true

3092 fp = builtins.open(filename, "rb") 

3093 exclusive_fp = True 

3094 

3095 try: 

3096 fp.seek(0) 

3097 except (AttributeError, io.UnsupportedOperation): 

3098 fp = io.BytesIO(fp.read()) 

3099 exclusive_fp = True 

3100 

3101 prefix = fp.read(16) 

3102 

3103 preinit() 

3104 

3105 accept_warnings = [] 

3106 

3107 def _open_core(fp, filename, prefix, formats): 

3108 for i in formats: 3108 ↛ 3131line 3108 didn't jump to line 3131, because the loop on line 3108 didn't complete

3109 i = i.upper() 

3110 if i not in OPEN: 3110 ↛ 3111line 3110 didn't jump to line 3111, because the condition on line 3110 was never true

3111 init() 

3112 try: 

3113 factory, accept = OPEN[i] 

3114 result = not accept or accept(prefix) 

3115 if type(result) in [str, bytes]: 3115 ↛ 3116line 3115 didn't jump to line 3116, because the condition on line 3115 was never true

3116 accept_warnings.append(result) 

3117 elif result: 

3118 fp.seek(0) 

3119 im = factory(fp, filename) 

3120 _decompression_bomb_check(im.size) 

3121 return im 

3122 except (SyntaxError, IndexError, TypeError, struct.error): 

3123 # Leave disabled by default, spams the logs with image 

3124 # opening failures that are entirely expected. 

3125 # logger.debug("", exc_info=True) 

3126 continue 

3127 except BaseException: 

3128 if exclusive_fp: 

3129 fp.close() 

3130 raise 

3131 return None 

3132 

3133 im = _open_core(fp, filename, prefix, formats) 

3134 

3135 if im is None: 3135 ↛ 3136line 3135 didn't jump to line 3136, because the condition on line 3135 was never true

3136 if init(): 

3137 im = _open_core(fp, filename, prefix, formats) 

3138 

3139 if im: 3139 ↛ 3143line 3139 didn't jump to line 3143, because the condition on line 3139 was never false

3140 im._exclusive_fp = exclusive_fp 

3141 return im 

3142 

3143 if exclusive_fp: 

3144 fp.close() 

3145 for message in accept_warnings: 

3146 warnings.warn(message) 

3147 raise UnidentifiedImageError( 

3148 "cannot identify image file %r" % (filename if filename else fp) 

3149 ) 

3150 

3151 

3152# 

3153# Image processing. 

3154 

3155 

3156def alpha_composite(im1, im2): 

3157 """ 

3158 Alpha composite im2 over im1. 

3159 

3160 :param im1: The first image. Must have mode RGBA. 

3161 :param im2: The second image. Must have mode RGBA, and the same size as 

3162 the first image. 

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

3164 """ 

3165 

3166 im1.load() 

3167 im2.load() 

3168 return im1._new(core.alpha_composite(im1.im, im2.im)) 

3169 

3170 

3171def blend(im1, im2, alpha): 

3172 """ 

3173 Creates a new image by interpolating between two input images, using 

3174 a constant alpha:: 

3175 

3176 out = image1 * (1.0 - alpha) + image2 * alpha 

3177 

3178 :param im1: The first image. 

3179 :param im2: The second image. Must have the same mode and size as 

3180 the first image. 

3181 :param alpha: The interpolation alpha factor. If alpha is 0.0, a 

3182 copy of the first image is returned. If alpha is 1.0, a copy of 

3183 the second image is returned. There are no restrictions on the 

3184 alpha value. If necessary, the result is clipped to fit into 

3185 the allowed output range. 

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

3187 """ 

3188 

3189 im1.load() 

3190 im2.load() 

3191 return im1._new(core.blend(im1.im, im2.im, alpha)) 

3192 

3193 

3194def composite(image1, image2, mask): 

3195 """ 

3196 Create composite image by blending images using a transparency mask. 

3197 

3198 :param image1: The first image. 

3199 :param image2: The second image. Must have the same mode and 

3200 size as the first image. 

3201 :param mask: A mask image. This image can have mode 

3202 "1", "L", or "RGBA", and must have the same size as the 

3203 other two images. 

3204 """ 

3205 

3206 image = image2.copy() 

3207 image.paste(image1, None, mask) 

3208 return image 

3209 

3210 

3211def eval(image, *args): 

3212 """ 

3213 Applies the function (which should take one argument) to each pixel 

3214 in the given image. If the image has more than one band, the same 

3215 function is applied to each band. Note that the function is 

3216 evaluated once for each possible pixel value, so you cannot use 

3217 random components or other generators. 

3218 

3219 :param image: The input image. 

3220 :param function: A function object, taking one integer argument. 

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

3222 """ 

3223 

3224 return image.point(args[0]) 

3225 

3226 

3227def merge(mode, bands): 

3228 """ 

3229 Merge a set of single band images into a new multiband image. 

3230 

3231 :param mode: The mode to use for the output image. See: 

3232 :ref:`concept-modes`. 

3233 :param bands: A sequence containing one single-band image for 

3234 each band in the output image. All bands must have the 

3235 same size. 

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

3237 """ 

3238 

3239 if getmodebands(mode) != len(bands) or "*" in mode: 

3240 raise ValueError("wrong number of bands") 

3241 for band in bands[1:]: 

3242 if band.mode != getmodetype(mode): 

3243 raise ValueError("mode mismatch") 

3244 if band.size != bands[0].size: 

3245 raise ValueError("size mismatch") 

3246 for band in bands: 

3247 band.load() 

3248 return bands[0]._new(core.merge(mode, *[b.im for b in bands])) 

3249 

3250 

3251# -------------------------------------------------------------------- 

3252# Plugin registry 

3253 

3254 

3255def register_open(id, factory, accept=None): 

3256 """ 

3257 Register an image file plugin. This function should not be used 

3258 in application code. 

3259 

3260 :param id: An image format identifier. 

3261 :param factory: An image file factory method. 

3262 :param accept: An optional function that can be used to quickly 

3263 reject images having another format. 

3264 """ 

3265 id = id.upper() 

3266 ID.append(id) 

3267 OPEN[id] = factory, accept 

3268 

3269 

3270def register_mime(id, mimetype): 

3271 """ 

3272 Registers an image MIME type. This function should not be used 

3273 in application code. 

3274 

3275 :param id: An image format identifier. 

3276 :param mimetype: The image MIME type for this format. 

3277 """ 

3278 MIME[id.upper()] = mimetype 

3279 

3280 

3281def register_save(id, driver): 

3282 """ 

3283 Registers an image save function. This function should not be 

3284 used in application code. 

3285 

3286 :param id: An image format identifier. 

3287 :param driver: A function to save images in this format. 

3288 """ 

3289 SAVE[id.upper()] = driver 

3290 

3291 

3292def register_save_all(id, driver): 

3293 """ 

3294 Registers an image function to save all the frames 

3295 of a multiframe format. This function should not be 

3296 used in application code. 

3297 

3298 :param id: An image format identifier. 

3299 :param driver: A function to save images in this format. 

3300 """ 

3301 SAVE_ALL[id.upper()] = driver 

3302 

3303 

3304def register_extension(id, extension): 

3305 """ 

3306 Registers an image extension. This function should not be 

3307 used in application code. 

3308 

3309 :param id: An image format identifier. 

3310 :param extension: An extension used for this format. 

3311 """ 

3312 EXTENSION[extension.lower()] = id.upper() 

3313 

3314 

3315def register_extensions(id, extensions): 

3316 """ 

3317 Registers image extensions. This function should not be 

3318 used in application code. 

3319 

3320 :param id: An image format identifier. 

3321 :param extensions: A list of extensions used for this format. 

3322 """ 

3323 for extension in extensions: 

3324 register_extension(id, extension) 

3325 

3326 

3327def registered_extensions(): 

3328 """ 

3329 Returns a dictionary containing all file extensions belonging 

3330 to registered plugins 

3331 """ 

3332 if not EXTENSION: 

3333 init() 

3334 return EXTENSION 

3335 

3336 

3337def register_decoder(name, decoder): 

3338 """ 

3339 Registers an image decoder. This function should not be 

3340 used in application code. 

3341 

3342 :param name: The name of the decoder 

3343 :param decoder: A callable(mode, args) that returns an 

3344 ImageFile.PyDecoder object 

3345 

3346 .. versionadded:: 4.1.0 

3347 """ 

3348 DECODERS[name] = decoder 

3349 

3350 

3351def register_encoder(name, encoder): 

3352 """ 

3353 Registers an image encoder. This function should not be 

3354 used in application code. 

3355 

3356 :param name: The name of the encoder 

3357 :param encoder: A callable(mode, args) that returns an 

3358 ImageFile.PyEncoder object 

3359 

3360 .. versionadded:: 4.1.0 

3361 """ 

3362 ENCODERS[name] = encoder 

3363 

3364 

3365# -------------------------------------------------------------------- 

3366# Simple display support. 

3367 

3368 

3369def _show(image, **options): 

3370 from . import ImageShow 

3371 

3372 ImageShow.show(image, **options) 

3373 

3374 

3375# -------------------------------------------------------------------- 

3376# Effects 

3377 

3378 

3379def effect_mandelbrot(size, extent, quality): 

3380 """ 

3381 Generate a Mandelbrot set covering the given extent. 

3382 

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

3384 (width, height). 

3385 :param extent: The extent to cover, as a 4-tuple: 

3386 (x0, y0, x1, y1). 

3387 :param quality: Quality. 

3388 """ 

3389 return Image()._new(core.effect_mandelbrot(size, extent, quality)) 

3390 

3391 

3392def effect_noise(size, sigma): 

3393 """ 

3394 Generate Gaussian noise centered around 128. 

3395 

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

3397 (width, height). 

3398 :param sigma: Standard deviation of noise. 

3399 """ 

3400 return Image()._new(core.effect_noise(size, sigma)) 

3401 

3402 

3403def linear_gradient(mode): 

3404 """ 

3405 Generate 256x256 linear gradient from black to white, top to bottom. 

3406 

3407 :param mode: Input mode. 

3408 """ 

3409 return Image()._new(core.linear_gradient(mode)) 

3410 

3411 

3412def radial_gradient(mode): 

3413 """ 

3414 Generate 256x256 radial gradient from black to white, centre to edge. 

3415 

3416 :param mode: Input mode. 

3417 """ 

3418 return Image()._new(core.radial_gradient(mode)) 

3419 

3420 

3421# -------------------------------------------------------------------- 

3422# Resources 

3423 

3424 

3425def _apply_env_variables(env=None): 

3426 if env is None: 3426 ↛ 3429line 3426 didn't jump to line 3429, because the condition on line 3426 was never false

3427 env = os.environ 

3428 

3429 for var_name, setter in [ 

3430 ("PILLOW_ALIGNMENT", core.set_alignment), 

3431 ("PILLOW_BLOCK_SIZE", core.set_block_size), 

3432 ("PILLOW_BLOCKS_MAX", core.set_blocks_max), 

3433 ]: 

3434 if var_name not in env: 3434 ↛ 3437line 3434 didn't jump to line 3437, because the condition on line 3434 was never false

3435 continue 

3436 

3437 var = env[var_name].lower() 

3438 

3439 units = 1 

3440 for postfix, mul in [("k", 1024), ("m", 1024 * 1024)]: 

3441 if var.endswith(postfix): 

3442 units = mul 

3443 var = var[: -len(postfix)] 

3444 

3445 try: 

3446 var = int(var) * units 

3447 except ValueError: 

3448 warnings.warn(f"{var_name} is not int") 

3449 continue 

3450 

3451 try: 

3452 setter(var) 

3453 except ValueError as e: 

3454 warnings.warn(f"{var_name}: {e}") 

3455 

3456 

3457_apply_env_variables() 

3458atexit.register(core.clear_cache) 

3459 

3460 

3461class Exif(MutableMapping): 

3462 endian = None 

3463 bigtiff = False 

3464 

3465 def __init__(self): 

3466 self._data = {} 

3467 self._ifds = {} 

3468 self._info = None 

3469 self._loaded_exif = None 

3470 

3471 def _fixup(self, value): 

3472 try: 

3473 if len(value) == 1 and isinstance(value, tuple): 

3474 return value[0] 

3475 except Exception: 

3476 pass 

3477 return value 

3478 

3479 def _fixup_dict(self, src_dict): 

3480 # Helper function 

3481 # returns a dict with any single item tuples/lists as individual values 

3482 return {k: self._fixup(v) for k, v in src_dict.items()} 

3483 

3484 def _get_ifd_dict(self, offset): 

3485 try: 

3486 # an offset pointer to the location of the nested embedded IFD. 

3487 # It should be a long, but may be corrupted. 

3488 self.fp.seek(offset) 

3489 except (KeyError, TypeError): 

3490 pass 

3491 else: 

3492 from . import TiffImagePlugin 

3493 

3494 info = TiffImagePlugin.ImageFileDirectory_v2(self.head) 

3495 info.load(self.fp) 

3496 return self._fixup_dict(info) 

3497 

3498 def _get_head(self): 

3499 version = b"\x2B" if self.bigtiff else b"\x2A" 

3500 if self.endian == "<": 

3501 head = b"II" + version + b"\x00" + o32le(8) 

3502 else: 

3503 head = b"MM\x00" + version + o32be(8) 

3504 if self.bigtiff: 

3505 head += o32le(8) if self.endian == "<" else o32be(8) 

3506 head += b"\x00\x00\x00\x00" 

3507 return head 

3508 

3509 def load(self, data): 

3510 # Extract EXIF information. This is highly experimental, 

3511 # and is likely to be replaced with something better in a future 

3512 # version. 

3513 

3514 # The EXIF record consists of a TIFF file embedded in a JPEG 

3515 # application marker (!). 

3516 if data == self._loaded_exif: 

3517 return 

3518 self._loaded_exif = data 

3519 self._data.clear() 

3520 self._ifds.clear() 

3521 if data and data.startswith(b"Exif\x00\x00"): 

3522 data = data[6:] 

3523 if not data: 

3524 self._info = None 

3525 return 

3526 

3527 self.fp = io.BytesIO(data) 

3528 self.head = self.fp.read(8) 

3529 # process dictionary 

3530 from . import TiffImagePlugin 

3531 

3532 self._info = TiffImagePlugin.ImageFileDirectory_v2(self.head) 

3533 self.endian = self._info._endian 

3534 self.fp.seek(self._info.next) 

3535 self._info.load(self.fp) 

3536 

3537 def load_from_fp(self, fp, offset=None): 

3538 self._loaded_exif = None 

3539 self._data.clear() 

3540 self._ifds.clear() 

3541 

3542 # process dictionary 

3543 from . import TiffImagePlugin 

3544 

3545 self.fp = fp 

3546 if offset is not None: 

3547 self.head = self._get_head() 

3548 else: 

3549 self.head = self.fp.read(8) 

3550 self._info = TiffImagePlugin.ImageFileDirectory_v2(self.head) 

3551 if self.endian is None: 

3552 self.endian = self._info._endian 

3553 if offset is None: 

3554 offset = self._info.next 

3555 self.fp.seek(offset) 

3556 self._info.load(self.fp) 

3557 

3558 def _get_merged_dict(self): 

3559 merged_dict = dict(self) 

3560 

3561 # get EXIF extension 

3562 if 0x8769 in self: 

3563 ifd = self._get_ifd_dict(self[0x8769]) 

3564 if ifd: 

3565 merged_dict.update(ifd) 

3566 

3567 # GPS 

3568 if 0x8825 in self: 

3569 merged_dict[0x8825] = self._get_ifd_dict(self[0x8825]) 

3570 

3571 return merged_dict 

3572 

3573 def tobytes(self, offset=8): 

3574 from . import TiffImagePlugin 

3575 

3576 head = self._get_head() 

3577 ifd = TiffImagePlugin.ImageFileDirectory_v2(ifh=head) 

3578 for tag, value in self.items(): 

3579 if tag in [0x8769, 0x8225, 0x8825] and not isinstance(value, dict): 

3580 value = self.get_ifd(tag) 

3581 if ( 

3582 tag == 0x8769 

3583 and 0xA005 in value 

3584 and not isinstance(value[0xA005], dict) 

3585 ): 

3586 value = value.copy() 

3587 value[0xA005] = self.get_ifd(0xA005) 

3588 ifd[tag] = value 

3589 return b"Exif\x00\x00" + head + ifd.tobytes(offset) 

3590 

3591 def get_ifd(self, tag): 

3592 if tag not in self._ifds: 

3593 if tag in [0x8769, 0x8825]: 

3594 # exif, gpsinfo 

3595 if tag in self: 

3596 self._ifds[tag] = self._get_ifd_dict(self[tag]) 

3597 elif tag in [0xA005, 0x927C]: 

3598 # interop, makernote 

3599 if 0x8769 not in self._ifds: 

3600 self.get_ifd(0x8769) 

3601 tag_data = self._ifds[0x8769][tag] 

3602 if tag == 0x927C: 

3603 # makernote 

3604 from .TiffImagePlugin import ImageFileDirectory_v2 

3605 

3606 if tag_data[:8] == b"FUJIFILM": 

3607 ifd_offset = i32le(tag_data, 8) 

3608 ifd_data = tag_data[ifd_offset:] 

3609 

3610 makernote = {} 

3611 for i in range(0, struct.unpack("<H", ifd_data[:2])[0]): 

3612 ifd_tag, typ, count, data = struct.unpack( 

3613 "<HHL4s", ifd_data[i * 12 + 2 : (i + 1) * 12 + 2] 

3614 ) 

3615 try: 

3616 ( 

3617 unit_size, 

3618 handler, 

3619 ) = ImageFileDirectory_v2._load_dispatch[typ] 

3620 except KeyError: 

3621 continue 

3622 size = count * unit_size 

3623 if size > 4: 

3624 (offset,) = struct.unpack("<L", data) 

3625 data = ifd_data[offset - 12 : offset + size - 12] 

3626 else: 

3627 data = data[:size] 

3628 

3629 if len(data) != size: 

3630 warnings.warn( 

3631 "Possibly corrupt EXIF MakerNote data. " 

3632 f"Expecting to read {size} bytes but only got " 

3633 f"{len(data)}. Skipping tag {ifd_tag}" 

3634 ) 

3635 continue 

3636 

3637 if not data: 

3638 continue 

3639 

3640 makernote[ifd_tag] = handler( 

3641 ImageFileDirectory_v2(), data, False 

3642 ) 

3643 self._ifds[tag] = dict(self._fixup_dict(makernote)) 

3644 elif self.get(0x010F) == "Nintendo": 

3645 makernote = {} 

3646 for i in range(0, struct.unpack(">H", tag_data[:2])[0]): 

3647 ifd_tag, typ, count, data = struct.unpack( 

3648 ">HHL4s", tag_data[i * 12 + 2 : (i + 1) * 12 + 2] 

3649 ) 

3650 if ifd_tag == 0x1101: 

3651 # CameraInfo 

3652 (offset,) = struct.unpack(">L", data) 

3653 self.fp.seek(offset) 

3654 

3655 camerainfo = {"ModelID": self.fp.read(4)} 

3656 

3657 self.fp.read(4) 

3658 # Seconds since 2000 

3659 camerainfo["TimeStamp"] = i32le(self.fp.read(12)) 

3660 

3661 self.fp.read(4) 

3662 camerainfo["InternalSerialNumber"] = self.fp.read(4) 

3663 

3664 self.fp.read(12) 

3665 parallax = self.fp.read(4) 

3666 handler = ImageFileDirectory_v2._load_dispatch[ 

3667 TiffTags.FLOAT 

3668 ][1] 

3669 camerainfo["Parallax"] = handler( 

3670 ImageFileDirectory_v2(), parallax, False 

3671 ) 

3672 

3673 self.fp.read(4) 

3674 camerainfo["Category"] = self.fp.read(2) 

3675 

3676 makernote = {0x1101: dict(self._fixup_dict(camerainfo))} 

3677 self._ifds[tag] = makernote 

3678 else: 

3679 # interop 

3680 self._ifds[tag] = self._get_ifd_dict(tag_data) 

3681 return self._ifds.get(tag, {}) 

3682 

3683 def __str__(self): 

3684 if self._info is not None: 

3685 # Load all keys into self._data 

3686 for tag in self._info.keys(): 

3687 self[tag] 

3688 

3689 return str(self._data) 

3690 

3691 def __len__(self): 

3692 keys = set(self._data) 

3693 if self._info is not None: 

3694 keys.update(self._info) 

3695 return len(keys) 

3696 

3697 def __getitem__(self, tag): 

3698 if self._info is not None and tag not in self._data and tag in self._info: 

3699 self._data[tag] = self._fixup(self._info[tag]) 

3700 del self._info[tag] 

3701 return self._data[tag] 

3702 

3703 def __contains__(self, tag): 

3704 return tag in self._data or (self._info is not None and tag in self._info) 

3705 

3706 def __setitem__(self, tag, value): 

3707 if self._info is not None and tag in self._info: 

3708 del self._info[tag] 

3709 self._data[tag] = value 

3710 

3711 def __delitem__(self, tag): 

3712 if self._info is not None and tag in self._info: 

3713 del self._info[tag] 

3714 else: 

3715 del self._data[tag] 

3716 

3717 def __iter__(self): 

3718 keys = set(self._data) 

3719 if self._info is not None: 

3720 keys.update(self._info) 

3721 return iter(keys)