Funktionierender Prototyp des Serious Games zur Vermittlung von Wissen zu Software-Engineering-Arbeitsmodellen.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

ImageTk.py 8.5KB

1 year ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290
  1. #
  2. # The Python Imaging Library.
  3. # $Id$
  4. #
  5. # a Tk display interface
  6. #
  7. # History:
  8. # 96-04-08 fl Created
  9. # 96-09-06 fl Added getimage method
  10. # 96-11-01 fl Rewritten, removed image attribute and crop method
  11. # 97-05-09 fl Use PyImagingPaste method instead of image type
  12. # 97-05-12 fl Minor tweaks to match the IFUNC95 interface
  13. # 97-05-17 fl Support the "pilbitmap" booster patch
  14. # 97-06-05 fl Added file= and data= argument to image constructors
  15. # 98-03-09 fl Added width and height methods to Image classes
  16. # 98-07-02 fl Use default mode for "P" images without palette attribute
  17. # 98-07-02 fl Explicitly destroy Tkinter image objects
  18. # 99-07-24 fl Support multiple Tk interpreters (from Greg Couch)
  19. # 99-07-26 fl Automatically hook into Tkinter (if possible)
  20. # 99-08-15 fl Hook uses _imagingtk instead of _imaging
  21. #
  22. # Copyright (c) 1997-1999 by Secret Labs AB
  23. # Copyright (c) 1996-1997 by Fredrik Lundh
  24. #
  25. # See the README file for information on usage and redistribution.
  26. #
  27. import tkinter
  28. from io import BytesIO
  29. from . import Image
  30. from ._deprecate import deprecate
  31. # --------------------------------------------------------------------
  32. # Check for Tkinter interface hooks
  33. _pilbitmap_ok = None
  34. def _pilbitmap_check():
  35. global _pilbitmap_ok
  36. if _pilbitmap_ok is None:
  37. try:
  38. im = Image.new("1", (1, 1))
  39. tkinter.BitmapImage(data=f"PIL:{im.im.id}")
  40. _pilbitmap_ok = 1
  41. except tkinter.TclError:
  42. _pilbitmap_ok = 0
  43. return _pilbitmap_ok
  44. def _get_image_from_kw(kw):
  45. source = None
  46. if "file" in kw:
  47. source = kw.pop("file")
  48. elif "data" in kw:
  49. source = BytesIO(kw.pop("data"))
  50. if source:
  51. return Image.open(source)
  52. def _pyimagingtkcall(command, photo, id):
  53. tk = photo.tk
  54. try:
  55. tk.call(command, photo, id)
  56. except tkinter.TclError:
  57. # activate Tkinter hook
  58. # may raise an error if it cannot attach to Tkinter
  59. from . import _imagingtk
  60. _imagingtk.tkinit(tk.interpaddr())
  61. tk.call(command, photo, id)
  62. # --------------------------------------------------------------------
  63. # PhotoImage
  64. class PhotoImage:
  65. """
  66. A Tkinter-compatible photo image. This can be used
  67. everywhere Tkinter expects an image object. If the image is an RGBA
  68. image, pixels having alpha 0 are treated as transparent.
  69. The constructor takes either a PIL image, or a mode and a size.
  70. Alternatively, you can use the ``file`` or ``data`` options to initialize
  71. the photo image object.
  72. :param image: Either a PIL image, or a mode string. If a mode string is
  73. used, a size must also be given.
  74. :param size: If the first argument is a mode string, this defines the size
  75. of the image.
  76. :keyword file: A filename to load the image from (using
  77. ``Image.open(file)``).
  78. :keyword data: An 8-bit string containing image data (as loaded from an
  79. image file).
  80. """
  81. def __init__(self, image=None, size=None, **kw):
  82. # Tk compatibility: file or data
  83. if image is None:
  84. image = _get_image_from_kw(kw)
  85. if hasattr(image, "mode") and hasattr(image, "size"):
  86. # got an image instead of a mode
  87. mode = image.mode
  88. if mode == "P":
  89. # palette mapped data
  90. image.apply_transparency()
  91. image.load()
  92. try:
  93. mode = image.palette.mode
  94. except AttributeError:
  95. mode = "RGB" # default
  96. size = image.size
  97. kw["width"], kw["height"] = size
  98. else:
  99. mode = image
  100. image = None
  101. if mode not in ["1", "L", "RGB", "RGBA"]:
  102. mode = Image.getmodebase(mode)
  103. self.__mode = mode
  104. self.__size = size
  105. self.__photo = tkinter.PhotoImage(**kw)
  106. self.tk = self.__photo.tk
  107. if image:
  108. self.paste(image)
  109. def __del__(self):
  110. name = self.__photo.name
  111. self.__photo.name = None
  112. try:
  113. self.__photo.tk.call("image", "delete", name)
  114. except Exception:
  115. pass # ignore internal errors
  116. def __str__(self):
  117. """
  118. Get the Tkinter photo image identifier. This method is automatically
  119. called by Tkinter whenever a PhotoImage object is passed to a Tkinter
  120. method.
  121. :return: A Tkinter photo image identifier (a string).
  122. """
  123. return str(self.__photo)
  124. def width(self):
  125. """
  126. Get the width of the image.
  127. :return: The width, in pixels.
  128. """
  129. return self.__size[0]
  130. def height(self):
  131. """
  132. Get the height of the image.
  133. :return: The height, in pixels.
  134. """
  135. return self.__size[1]
  136. def paste(self, im, box=None):
  137. """
  138. Paste a PIL image into the photo image. Note that this can
  139. be very slow if the photo image is displayed.
  140. :param im: A PIL image. The size must match the target region. If the
  141. mode does not match, the image is converted to the mode of
  142. the bitmap image.
  143. :param box: Deprecated. This parameter will be removed in Pillow 10
  144. (2023-07-01).
  145. """
  146. if box is not None:
  147. deprecate("The box parameter", 10, None)
  148. # convert to blittable
  149. im.load()
  150. image = im.im
  151. if image.isblock() and im.mode == self.__mode:
  152. block = image
  153. else:
  154. block = image.new_block(self.__mode, im.size)
  155. image.convert2(block, image) # convert directly between buffers
  156. _pyimagingtkcall("PyImagingPhoto", self.__photo, block.id)
  157. # --------------------------------------------------------------------
  158. # BitmapImage
  159. class BitmapImage:
  160. """
  161. A Tkinter-compatible bitmap image. This can be used everywhere Tkinter
  162. expects an image object.
  163. The given image must have mode "1". Pixels having value 0 are treated as
  164. transparent. Options, if any, are passed on to Tkinter. The most commonly
  165. used option is ``foreground``, which is used to specify the color for the
  166. non-transparent parts. See the Tkinter documentation for information on
  167. how to specify colours.
  168. :param image: A PIL image.
  169. """
  170. def __init__(self, image=None, **kw):
  171. # Tk compatibility: file or data
  172. if image is None:
  173. image = _get_image_from_kw(kw)
  174. self.__mode = image.mode
  175. self.__size = image.size
  176. if _pilbitmap_check():
  177. # fast way (requires the pilbitmap booster patch)
  178. image.load()
  179. kw["data"] = f"PIL:{image.im.id}"
  180. self.__im = image # must keep a reference
  181. else:
  182. # slow but safe way
  183. kw["data"] = image.tobitmap()
  184. self.__photo = tkinter.BitmapImage(**kw)
  185. def __del__(self):
  186. name = self.__photo.name
  187. self.__photo.name = None
  188. try:
  189. self.__photo.tk.call("image", "delete", name)
  190. except Exception:
  191. pass # ignore internal errors
  192. def width(self):
  193. """
  194. Get the width of the image.
  195. :return: The width, in pixels.
  196. """
  197. return self.__size[0]
  198. def height(self):
  199. """
  200. Get the height of the image.
  201. :return: The height, in pixels.
  202. """
  203. return self.__size[1]
  204. def __str__(self):
  205. """
  206. Get the Tkinter bitmap image identifier. This method is automatically
  207. called by Tkinter whenever a BitmapImage object is passed to a Tkinter
  208. method.
  209. :return: A Tkinter bitmap image identifier (a string).
  210. """
  211. return str(self.__photo)
  212. def getimage(photo):
  213. """Copies the contents of a PhotoImage to a PIL image memory."""
  214. im = Image.new("RGBA", (photo.width(), photo.height()))
  215. block = im.im
  216. _pyimagingtkcall("PyImagingPhotoGet", photo, block.id)
  217. return im
  218. def _show(image, title):
  219. """Helper for the Image.show method."""
  220. class UI(tkinter.Label):
  221. def __init__(self, master, im):
  222. if im.mode == "1":
  223. self.image = BitmapImage(im, foreground="white", master=master)
  224. else:
  225. self.image = PhotoImage(im, master=master)
  226. super().__init__(master, image=self.image, bg="black", bd=0)
  227. if not tkinter._default_root:
  228. msg = "tkinter not initialized"
  229. raise OSError(msg)
  230. top = tkinter.Toplevel()
  231. if title:
  232. top.title(title)
  233. UI(top, image).pack()