ImageChops.py 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311
  1. #
  2. # The Python Imaging Library.
  3. # $Id$
  4. #
  5. # standard channel operations
  6. #
  7. # History:
  8. # 1996-03-24 fl Created
  9. # 1996-08-13 fl Added logical operations (for "1" images)
  10. # 2000-10-12 fl Added offset method (from Image.py)
  11. #
  12. # Copyright (c) 1997-2000 by Secret Labs AB
  13. # Copyright (c) 1996-2000 by Fredrik Lundh
  14. #
  15. # See the README file for information on usage and redistribution.
  16. #
  17. from __future__ import annotations
  18. from . import Image
  19. def constant(image: Image.Image, value: int) -> Image.Image:
  20. """Fill a channel with a given gray level.
  21. :rtype: :py:class:`~PIL.Image.Image`
  22. """
  23. return Image.new("L", image.size, value)
  24. def duplicate(image: Image.Image) -> Image.Image:
  25. """Copy a channel. Alias for :py:meth:`PIL.Image.Image.copy`.
  26. :rtype: :py:class:`~PIL.Image.Image`
  27. """
  28. return image.copy()
  29. def invert(image: Image.Image) -> Image.Image:
  30. """
  31. Invert an image (channel). ::
  32. out = MAX - image
  33. :rtype: :py:class:`~PIL.Image.Image`
  34. """
  35. image.load()
  36. return image._new(image.im.chop_invert())
  37. def lighter(image1: Image.Image, image2: Image.Image) -> Image.Image:
  38. """
  39. Compares the two images, pixel by pixel, and returns a new image containing
  40. the lighter values. ::
  41. out = max(image1, image2)
  42. :rtype: :py:class:`~PIL.Image.Image`
  43. """
  44. image1.load()
  45. image2.load()
  46. return image1._new(image1.im.chop_lighter(image2.im))
  47. def darker(image1: Image.Image, image2: Image.Image) -> Image.Image:
  48. """
  49. Compares the two images, pixel by pixel, and returns a new image containing
  50. the darker values. ::
  51. out = min(image1, image2)
  52. :rtype: :py:class:`~PIL.Image.Image`
  53. """
  54. image1.load()
  55. image2.load()
  56. return image1._new(image1.im.chop_darker(image2.im))
  57. def difference(image1: Image.Image, image2: Image.Image) -> Image.Image:
  58. """
  59. Returns the absolute value of the pixel-by-pixel difference between the two
  60. images. ::
  61. out = abs(image1 - image2)
  62. :rtype: :py:class:`~PIL.Image.Image`
  63. """
  64. image1.load()
  65. image2.load()
  66. return image1._new(image1.im.chop_difference(image2.im))
  67. def multiply(image1: Image.Image, image2: Image.Image) -> Image.Image:
  68. """
  69. Superimposes two images on top of each other.
  70. If you multiply an image with a solid black image, the result is black. If
  71. you multiply with a solid white image, the image is unaffected. ::
  72. out = image1 * image2 / MAX
  73. :rtype: :py:class:`~PIL.Image.Image`
  74. """
  75. image1.load()
  76. image2.load()
  77. return image1._new(image1.im.chop_multiply(image2.im))
  78. def screen(image1: Image.Image, image2: Image.Image) -> Image.Image:
  79. """
  80. Superimposes two inverted images on top of each other. ::
  81. out = MAX - ((MAX - image1) * (MAX - image2) / MAX)
  82. :rtype: :py:class:`~PIL.Image.Image`
  83. """
  84. image1.load()
  85. image2.load()
  86. return image1._new(image1.im.chop_screen(image2.im))
  87. def soft_light(image1: Image.Image, image2: Image.Image) -> Image.Image:
  88. """
  89. Superimposes two images on top of each other using the Soft Light algorithm
  90. :rtype: :py:class:`~PIL.Image.Image`
  91. """
  92. image1.load()
  93. image2.load()
  94. return image1._new(image1.im.chop_soft_light(image2.im))
  95. def hard_light(image1: Image.Image, image2: Image.Image) -> Image.Image:
  96. """
  97. Superimposes two images on top of each other using the Hard Light algorithm
  98. :rtype: :py:class:`~PIL.Image.Image`
  99. """
  100. image1.load()
  101. image2.load()
  102. return image1._new(image1.im.chop_hard_light(image2.im))
  103. def overlay(image1: Image.Image, image2: Image.Image) -> Image.Image:
  104. """
  105. Superimposes two images on top of each other using the Overlay algorithm
  106. :rtype: :py:class:`~PIL.Image.Image`
  107. """
  108. image1.load()
  109. image2.load()
  110. return image1._new(image1.im.chop_overlay(image2.im))
  111. def add(
  112. image1: Image.Image, image2: Image.Image, scale: float = 1.0, offset: float = 0
  113. ) -> Image.Image:
  114. """
  115. Adds two images, dividing the result by scale and adding the
  116. offset. If omitted, scale defaults to 1.0, and offset to 0.0. ::
  117. out = ((image1 + image2) / scale + offset)
  118. :rtype: :py:class:`~PIL.Image.Image`
  119. """
  120. image1.load()
  121. image2.load()
  122. return image1._new(image1.im.chop_add(image2.im, scale, offset))
  123. def subtract(
  124. image1: Image.Image, image2: Image.Image, scale: float = 1.0, offset: float = 0
  125. ) -> Image.Image:
  126. """
  127. Subtracts two images, dividing the result by scale and adding the offset.
  128. If omitted, scale defaults to 1.0, and offset to 0.0. ::
  129. out = ((image1 - image2) / scale + offset)
  130. :rtype: :py:class:`~PIL.Image.Image`
  131. """
  132. image1.load()
  133. image2.load()
  134. return image1._new(image1.im.chop_subtract(image2.im, scale, offset))
  135. def add_modulo(image1: Image.Image, image2: Image.Image) -> Image.Image:
  136. """Add two images, without clipping the result. ::
  137. out = ((image1 + image2) % MAX)
  138. :rtype: :py:class:`~PIL.Image.Image`
  139. """
  140. image1.load()
  141. image2.load()
  142. return image1._new(image1.im.chop_add_modulo(image2.im))
  143. def subtract_modulo(image1: Image.Image, image2: Image.Image) -> Image.Image:
  144. """Subtract two images, without clipping the result. ::
  145. out = ((image1 - image2) % MAX)
  146. :rtype: :py:class:`~PIL.Image.Image`
  147. """
  148. image1.load()
  149. image2.load()
  150. return image1._new(image1.im.chop_subtract_modulo(image2.im))
  151. def logical_and(image1: Image.Image, image2: Image.Image) -> Image.Image:
  152. """Logical AND between two images.
  153. Both of the images must have mode "1". If you would like to perform a
  154. logical AND on an image with a mode other than "1", try
  155. :py:meth:`~PIL.ImageChops.multiply` instead, using a black-and-white mask
  156. as the second image. ::
  157. out = ((image1 and image2) % MAX)
  158. :rtype: :py:class:`~PIL.Image.Image`
  159. """
  160. image1.load()
  161. image2.load()
  162. return image1._new(image1.im.chop_and(image2.im))
  163. def logical_or(image1: Image.Image, image2: Image.Image) -> Image.Image:
  164. """Logical OR between two images.
  165. Both of the images must have mode "1". ::
  166. out = ((image1 or image2) % MAX)
  167. :rtype: :py:class:`~PIL.Image.Image`
  168. """
  169. image1.load()
  170. image2.load()
  171. return image1._new(image1.im.chop_or(image2.im))
  172. def logical_xor(image1: Image.Image, image2: Image.Image) -> Image.Image:
  173. """Logical XOR between two images.
  174. Both of the images must have mode "1". ::
  175. out = ((bool(image1) != bool(image2)) % MAX)
  176. :rtype: :py:class:`~PIL.Image.Image`
  177. """
  178. image1.load()
  179. image2.load()
  180. return image1._new(image1.im.chop_xor(image2.im))
  181. def blend(image1: Image.Image, image2: Image.Image, alpha: float) -> Image.Image:
  182. """Blend images using constant transparency weight. Alias for
  183. :py:func:`PIL.Image.blend`.
  184. :rtype: :py:class:`~PIL.Image.Image`
  185. """
  186. return Image.blend(image1, image2, alpha)
  187. def composite(
  188. image1: Image.Image, image2: Image.Image, mask: Image.Image
  189. ) -> Image.Image:
  190. """Create composite using transparency mask. Alias for
  191. :py:func:`PIL.Image.composite`.
  192. :rtype: :py:class:`~PIL.Image.Image`
  193. """
  194. return Image.composite(image1, image2, mask)
  195. def offset(image: Image.Image, xoffset: int, yoffset: int | None = None) -> Image.Image:
  196. """Returns a copy of the image where data has been offset by the given
  197. distances. Data wraps around the edges. If ``yoffset`` is omitted, it
  198. is assumed to be equal to ``xoffset``.
  199. :param image: Input image.
  200. :param xoffset: The horizontal distance.
  201. :param yoffset: The vertical distance. If omitted, both
  202. distances are set to the same value.
  203. :rtype: :py:class:`~PIL.Image.Image`
  204. """
  205. if yoffset is None:
  206. yoffset = xoffset
  207. image.load()
  208. return image._new(image.im.offset(xoffset, yoffset))