We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Alpha channel ignored in tkinter using PIL.Image.open and PIL.ImageTk.PhotoImage for PNGs in palette mode
### What did you do?

I opened a PNG image (palette mode with alpha channel) using pillow and passed it to tkinter.

### What did you expect to happen?

It should work just like using tkinter.PhotoImage.

### What actually happened?

The alpha channel is ignored.

### What are your OS, Python and Pillow versions?

* OS: `5.10.0-17-amd64 #1 SMP Debian 5.10.136-1 (2022-08-13) x86_64 GNU/Linux`
* Python: `Python 3.9.2`
* Pillow: `9.0.1`

I noticed an error when I wanted to include a PNG image in palette mode with alpha channel into a tkinter application.
Since I wanted to resize it before displaying it, I used Pillow.
However if I execute the code below ([reproduce.zip](https://github.com/python-pillow/Pillow/files/9483016/reproduce.zip)) I see this:
![Bildschirmfoto 2022-09-03 18:53:25](https://user-images.githubusercontent.com/4997642/188280682-638eb8c4-8711-409a-9eab-b844a1f71526.png)

It shows the following 3 images:

- The first image is created using `Image.open` and `ImageTk.PhotoImage`, the transparent part is black.
- The second image shows the same image which has been converted to RGBA mode and then saved (also with Pillow), which works.
- The third image shows the `tkinter.PhotoImage` version which also works fine.

Uncommenting the explicit conversion to RGBA also fixes the problem, which is my current workaround.
However I think this should not be necessary.


```python
from tkinter import Tk, Label, PhotoImage

from PIL import Image, ImageTk


root = Tk()
# via Pillow
pil_image = Image.open('loading.png')
print(pil_image.mode)
#pil_image = pil_image.convert('RGBA')
image1 = ImageTk.PhotoImage(pil_image)
Label(root, image=image1).grid(row=0, column=0, padx=5, pady=5)

# using RGBA mode
pil_image_rgba = Image.open('loading_RGBA.png')
print(pil_image_rgba.mode)
image2 = ImageTk.PhotoImage(pil_image_rgba)
Label(root, image=image2).grid(row=0, column=1, padx=5, pady=5)

# using tkinter.PhotoImage
image3 = PhotoImage(file='loading.png')
Label(root, image=image3).grid(row=0, column=2, padx=5, pady=5)
root.mainloop()
```


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `src/PIL/ImageTk.py`
Content:
```
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 
28 import tkinter
29 from io import BytesIO
30 
31 from . import Image
32 from ._deprecate import deprecate
33 
34 # --------------------------------------------------------------------
35 # Check for Tkinter interface hooks
36 
37 _pilbitmap_ok = None
38 
39 
40 def _pilbitmap_check():
41     global _pilbitmap_ok
42     if _pilbitmap_ok is None:
43         try:
44             im = Image.new("1", (1, 1))
45             tkinter.BitmapImage(data=f"PIL:{im.im.id}")
46             _pilbitmap_ok = 1
47         except tkinter.TclError:
48             _pilbitmap_ok = 0
49     return _pilbitmap_ok
50 
51 
52 def _get_image_from_kw(kw):
53     source = None
54     if "file" in kw:
55         source = kw.pop("file")
56     elif "data" in kw:
57         source = BytesIO(kw.pop("data"))
58     if source:
59         return Image.open(source)
60 
61 
62 def _pyimagingtkcall(command, photo, id):
63     tk = photo.tk
64     try:
65         tk.call(command, photo, id)
66     except tkinter.TclError:
67         # activate Tkinter hook
68         # may raise an error if it cannot attach to Tkinter
69         from . import _imagingtk
70 
71         _imagingtk.tkinit(tk.interpaddr())
72         tk.call(command, photo, id)
73 
74 
75 # --------------------------------------------------------------------
76 # PhotoImage
77 
78 
79 class PhotoImage:
80     """
81     A Tkinter-compatible photo image.  This can be used
82     everywhere Tkinter expects an image object.  If the image is an RGBA
83     image, pixels having alpha 0 are treated as transparent.
84 
85     The constructor takes either a PIL image, or a mode and a size.
86     Alternatively, you can use the ``file`` or ``data`` options to initialize
87     the photo image object.
88 
89     :param image: Either a PIL image, or a mode string.  If a mode string is
90                   used, a size must also be given.
91     :param size: If the first argument is a mode string, this defines the size
92                  of the image.
93     :keyword file: A filename to load the image from (using
94                    ``Image.open(file)``).
95     :keyword data: An 8-bit string containing image data (as loaded from an
96                    image file).
97     """
98 
99     def __init__(self, image=None, size=None, **kw):
100 
101         # Tk compatibility: file or data
102         if image is None:
103             image = _get_image_from_kw(kw)
104 
105         if hasattr(image, "mode") and hasattr(image, "size"):
106             # got an image instead of a mode
107             mode = image.mode
108             if mode == "P":
109                 # palette mapped data
110                 image.load()
111                 try:
112                     mode = image.palette.mode
113                 except AttributeError:
114                     mode = "RGB"  # default
115             size = image.size
116             kw["width"], kw["height"] = size
117         else:
118             mode = image
119             image = None
120 
121         if mode not in ["1", "L", "RGB", "RGBA"]:
122             mode = Image.getmodebase(mode)
123 
124         self.__mode = mode
125         self.__size = size
126         self.__photo = tkinter.PhotoImage(**kw)
127         self.tk = self.__photo.tk
128         if image:
129             self.paste(image)
130 
131     def __del__(self):
132         name = self.__photo.name
133         self.__photo.name = None
134         try:
135             self.__photo.tk.call("image", "delete", name)
136         except Exception:
137             pass  # ignore internal errors
138 
139     def __str__(self):
140         """
141         Get the Tkinter photo image identifier.  This method is automatically
142         called by Tkinter whenever a PhotoImage object is passed to a Tkinter
143         method.
144 
145         :return: A Tkinter photo image identifier (a string).
146         """
147         return str(self.__photo)
148 
149     def width(self):
150         """
151         Get the width of the image.
152 
153         :return: The width, in pixels.
154         """
155         return self.__size[0]
156 
157     def height(self):
158         """
159         Get the height of the image.
160 
161         :return: The height, in pixels.
162         """
163         return self.__size[1]
164 
165     def paste(self, im, box=None):
166         """
167         Paste a PIL image into the photo image.  Note that this can
168         be very slow if the photo image is displayed.
169 
170         :param im: A PIL image. The size must match the target region.  If the
171                    mode does not match, the image is converted to the mode of
172                    the bitmap image.
173         :param box: Deprecated. This parameter will be removed in Pillow 10
174                     (2023-07-01).
175         """
176 
177         if box is not None:
178             deprecate("The box parameter", 10, None)
179 
180         # convert to blittable
181         im.load()
182         image = im.im
183         if image.isblock() and im.mode == self.__mode:
184             block = image
185         else:
186             block = image.new_block(self.__mode, im.size)
187             image.convert2(block, image)  # convert directly between buffers
188 
189         _pyimagingtkcall("PyImagingPhoto", self.__photo, block.id)
190 
191 
192 # --------------------------------------------------------------------
193 # BitmapImage
194 
195 
196 class BitmapImage:
197     """
198     A Tkinter-compatible bitmap image.  This can be used everywhere Tkinter
199     expects an image object.
200 
201     The given image must have mode "1".  Pixels having value 0 are treated as
202     transparent.  Options, if any, are passed on to Tkinter.  The most commonly
203     used option is ``foreground``, which is used to specify the color for the
204     non-transparent parts.  See the Tkinter documentation for information on
205     how to specify colours.
206 
207     :param image: A PIL image.
208     """
209 
210     def __init__(self, image=None, **kw):
211 
212         # Tk compatibility: file or data
213         if image is None:
214             image = _get_image_from_kw(kw)
215 
216         self.__mode = image.mode
217         self.__size = image.size
218 
219         if _pilbitmap_check():
220             # fast way (requires the pilbitmap booster patch)
221             image.load()
222             kw["data"] = f"PIL:{image.im.id}"
223             self.__im = image  # must keep a reference
224         else:
225             # slow but safe way
226             kw["data"] = image.tobitmap()
227         self.__photo = tkinter.BitmapImage(**kw)
228 
229     def __del__(self):
230         name = self.__photo.name
231         self.__photo.name = None
232         try:
233             self.__photo.tk.call("image", "delete", name)
234         except Exception:
235             pass  # ignore internal errors
236 
237     def width(self):
238         """
239         Get the width of the image.
240 
241         :return: The width, in pixels.
242         """
243         return self.__size[0]
244 
245     def height(self):
246         """
247         Get the height of the image.
248 
249         :return: The height, in pixels.
250         """
251         return self.__size[1]
252 
253     def __str__(self):
254         """
255         Get the Tkinter bitmap image identifier.  This method is automatically
256         called by Tkinter whenever a BitmapImage object is passed to a Tkinter
257         method.
258 
259         :return: A Tkinter bitmap image identifier (a string).
260         """
261         return str(self.__photo)
262 
263 
264 def getimage(photo):
265     """Copies the contents of a PhotoImage to a PIL image memory."""
266     im = Image.new("RGBA", (photo.width(), photo.height()))
267     block = im.im
268 
269     _pyimagingtkcall("PyImagingPhotoGet", photo, block.id)
270 
271     return im
272 
273 
274 def _show(image, title):
275     """Helper for the Image.show method."""
276 
277     class UI(tkinter.Label):
278         def __init__(self, master, im):
279             if im.mode == "1":
280                 self.image = BitmapImage(im, foreground="white", master=master)
281             else:
282                 self.image = PhotoImage(im, master=master)
283             super().__init__(master, image=self.image, bg="black", bd=0)
284 
285     if not tkinter._default_root:
286         raise OSError("tkinter not initialized")
287     top = tkinter.Toplevel()
288     if title:
289         top.title(title)
290     UI(top, image).pack()
291
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/src/PIL/ImageTk.py b/src/PIL/ImageTk.py
--- a/src/PIL/ImageTk.py
+++ b/src/PIL/ImageTk.py
@@ -107,6 +107,7 @@
             mode = image.mode
             if mode == "P":
                 # palette mapped data
+                image.apply_transparency()
                 image.load()
                 try:
                     mode = image.palette.mode

{"golden_diff": "diff --git a/src/PIL/ImageTk.py b/src/PIL/ImageTk.py\n--- a/src/PIL/ImageTk.py\n+++ b/src/PIL/ImageTk.py\n@@ -107,6 +107,7 @@\n             mode = image.mode\n             if mode == \"P\":\n                 # palette mapped data\n+                image.apply_transparency()\n                 image.load()\n                 try:\n                     mode = image.palette.mode\n", "issue": "Alpha channel ignored in tkinter using PIL.Image.open and PIL.ImageTk.PhotoImage for PNGs in palette mode\n### What did you do?\r\n\r\nI opened a PNG image (palette mode with alpha channel) using pillow and passed it to tkinter.\r\n\r\n### What did you expect to happen?\r\n\r\nIt should work just like using tkinter.PhotoImage.\r\n\r\n### What actually happened?\r\n\r\nThe alpha channel is ignored.\r\n\r\n### What are your OS, Python and Pillow versions?\r\n\r\n* OS: `5.10.0-17-amd64 #1 SMP Debian 5.10.136-1 (2022-08-13) x86_64 GNU/Linux`\r\n* Python: `Python 3.9.2`\r\n* Pillow: `9.0.1`\r\n\r\nI noticed an error when I wanted to include a PNG image in palette mode with alpha channel into a tkinter application.\r\nSince I wanted to resize it before displaying it, I used Pillow.\r\nHowever if I execute the code below ([reproduce.zip](https://github.com/python-pillow/Pillow/files/9483016/reproduce.zip)) I see this:\r\n![Bildschirmfoto 2022-09-03 18:53:25](https://user-images.githubusercontent.com/4997642/188280682-638eb8c4-8711-409a-9eab-b844a1f71526.png)\r\n\r\nIt shows the following 3 images:\r\n\r\n- The first image is created using `Image.open` and `ImageTk.PhotoImage`, the transparent part is black.\r\n- The second image shows the same image which has been converted to RGBA mode and then saved (also with Pillow), which works.\r\n- The third image shows the `tkinter.PhotoImage` version which also works fine.\r\n\r\nUncommenting the explicit conversion to RGBA also fixes the problem, which is my current workaround.\r\nHowever I think this should not be necessary.\r\n\r\n\r\n```python\r\nfrom tkinter import Tk, Label, PhotoImage\r\n\r\nfrom PIL import Image, ImageTk\r\n\r\n\r\nroot = Tk()\r\n# via Pillow\r\npil_image = Image.open('loading.png')\r\nprint(pil_image.mode)\r\n#pil_image = pil_image.convert('RGBA')\r\nimage1 = ImageTk.PhotoImage(pil_image)\r\nLabel(root, image=image1).grid(row=0, column=0, padx=5, pady=5)\r\n\r\n# using RGBA mode\r\npil_image_rgba = Image.open('loading_RGBA.png')\r\nprint(pil_image_rgba.mode)\r\nimage2 = ImageTk.PhotoImage(pil_image_rgba)\r\nLabel(root, image=image2).grid(row=0, column=1, padx=5, pady=5)\r\n\r\n# using tkinter.PhotoImage\r\nimage3 = PhotoImage(file='loading.png')\r\nLabel(root, image=image3).grid(row=0, column=2, padx=5, pady=5)\r\nroot.mainloop()\r\n```\r\n\n", "before_files": [{"content": "#\n# The Python Imaging Library.\n# $Id$\n#\n# a Tk display interface\n#\n# History:\n# 96-04-08 fl   Created\n# 96-09-06 fl   Added getimage method\n# 96-11-01 fl   Rewritten, removed image attribute and crop method\n# 97-05-09 fl   Use PyImagingPaste method instead of image type\n# 97-05-12 fl   Minor tweaks to match the IFUNC95 interface\n# 97-05-17 fl   Support the \"pilbitmap\" booster patch\n# 97-06-05 fl   Added file= and data= argument to image constructors\n# 98-03-09 fl   Added width and height methods to Image classes\n# 98-07-02 fl   Use default mode for \"P\" images without palette attribute\n# 98-07-02 fl   Explicitly destroy Tkinter image objects\n# 99-07-24 fl   Support multiple Tk interpreters (from Greg Couch)\n# 99-07-26 fl   Automatically hook into Tkinter (if possible)\n# 99-08-15 fl   Hook uses _imagingtk instead of _imaging\n#\n# Copyright (c) 1997-1999 by Secret Labs AB\n# Copyright (c) 1996-1997 by Fredrik Lundh\n#\n# See the README file for information on usage and redistribution.\n#\n\nimport tkinter\nfrom io import BytesIO\n\nfrom . import Image\nfrom ._deprecate import deprecate\n\n# --------------------------------------------------------------------\n# Check for Tkinter interface hooks\n\n_pilbitmap_ok = None\n\n\ndef _pilbitmap_check():\n    global _pilbitmap_ok\n    if _pilbitmap_ok is None:\n        try:\n            im = Image.new(\"1\", (1, 1))\n            tkinter.BitmapImage(data=f\"PIL:{im.im.id}\")\n            _pilbitmap_ok = 1\n        except tkinter.TclError:\n            _pilbitmap_ok = 0\n    return _pilbitmap_ok\n\n\ndef _get_image_from_kw(kw):\n    source = None\n    if \"file\" in kw:\n        source = kw.pop(\"file\")\n    elif \"data\" in kw:\n        source = BytesIO(kw.pop(\"data\"))\n    if source:\n        return Image.open(source)\n\n\ndef _pyimagingtkcall(command, photo, id):\n    tk = photo.tk\n    try:\n        tk.call(command, photo, id)\n    except tkinter.TclError:\n        # activate Tkinter hook\n        # may raise an error if it cannot attach to Tkinter\n        from . import _imagingtk\n\n        _imagingtk.tkinit(tk.interpaddr())\n        tk.call(command, photo, id)\n\n\n# --------------------------------------------------------------------\n# PhotoImage\n\n\nclass PhotoImage:\n    \"\"\"\n    A Tkinter-compatible photo image.  This can be used\n    everywhere Tkinter expects an image object.  If the image is an RGBA\n    image, pixels having alpha 0 are treated as transparent.\n\n    The constructor takes either a PIL image, or a mode and a size.\n    Alternatively, you can use the ``file`` or ``data`` options to initialize\n    the photo image object.\n\n    :param image: Either a PIL image, or a mode string.  If a mode string is\n                  used, a size must also be given.\n    :param size: If the first argument is a mode string, this defines the size\n                 of the image.\n    :keyword file: A filename to load the image from (using\n                   ``Image.open(file)``).\n    :keyword data: An 8-bit string containing image data (as loaded from an\n                   image file).\n    \"\"\"\n\n    def __init__(self, image=None, size=None, **kw):\n\n        # Tk compatibility: file or data\n        if image is None:\n            image = _get_image_from_kw(kw)\n\n        if hasattr(image, \"mode\") and hasattr(image, \"size\"):\n            # got an image instead of a mode\n            mode = image.mode\n            if mode == \"P\":\n                # palette mapped data\n                image.load()\n                try:\n                    mode = image.palette.mode\n                except AttributeError:\n                    mode = \"RGB\"  # default\n            size = image.size\n            kw[\"width\"], kw[\"height\"] = size\n        else:\n            mode = image\n            image = None\n\n        if mode not in [\"1\", \"L\", \"RGB\", \"RGBA\"]:\n            mode = Image.getmodebase(mode)\n\n        self.__mode = mode\n        self.__size = size\n        self.__photo = tkinter.PhotoImage(**kw)\n        self.tk = self.__photo.tk\n        if image:\n            self.paste(image)\n\n    def __del__(self):\n        name = self.__photo.name\n        self.__photo.name = None\n        try:\n            self.__photo.tk.call(\"image\", \"delete\", name)\n        except Exception:\n            pass  # ignore internal errors\n\n    def __str__(self):\n        \"\"\"\n        Get the Tkinter photo image identifier.  This method is automatically\n        called by Tkinter whenever a PhotoImage object is passed to a Tkinter\n        method.\n\n        :return: A Tkinter photo image identifier (a string).\n        \"\"\"\n        return str(self.__photo)\n\n    def width(self):\n        \"\"\"\n        Get the width of the image.\n\n        :return: The width, in pixels.\n        \"\"\"\n        return self.__size[0]\n\n    def height(self):\n        \"\"\"\n        Get the height of the image.\n\n        :return: The height, in pixels.\n        \"\"\"\n        return self.__size[1]\n\n    def paste(self, im, box=None):\n        \"\"\"\n        Paste a PIL image into the photo image.  Note that this can\n        be very slow if the photo image is displayed.\n\n        :param im: A PIL image. The size must match the target region.  If the\n                   mode does not match, the image is converted to the mode of\n                   the bitmap image.\n        :param box: Deprecated. This parameter will be removed in Pillow 10\n                    (2023-07-01).\n        \"\"\"\n\n        if box is not None:\n            deprecate(\"The box parameter\", 10, None)\n\n        # convert to blittable\n        im.load()\n        image = im.im\n        if image.isblock() and im.mode == self.__mode:\n            block = image\n        else:\n            block = image.new_block(self.__mode, im.size)\n            image.convert2(block, image)  # convert directly between buffers\n\n        _pyimagingtkcall(\"PyImagingPhoto\", self.__photo, block.id)\n\n\n# --------------------------------------------------------------------\n# BitmapImage\n\n\nclass BitmapImage:\n    \"\"\"\n    A Tkinter-compatible bitmap image.  This can be used everywhere Tkinter\n    expects an image object.\n\n    The given image must have mode \"1\".  Pixels having value 0 are treated as\n    transparent.  Options, if any, are passed on to Tkinter.  The most commonly\n    used option is ``foreground``, which is used to specify the color for the\n    non-transparent parts.  See the Tkinter documentation for information on\n    how to specify colours.\n\n    :param image: A PIL image.\n    \"\"\"\n\n    def __init__(self, image=None, **kw):\n\n        # Tk compatibility: file or data\n        if image is None:\n            image = _get_image_from_kw(kw)\n\n        self.__mode = image.mode\n        self.__size = image.size\n\n        if _pilbitmap_check():\n            # fast way (requires the pilbitmap booster patch)\n            image.load()\n            kw[\"data\"] = f\"PIL:{image.im.id}\"\n            self.__im = image  # must keep a reference\n        else:\n            # slow but safe way\n            kw[\"data\"] = image.tobitmap()\n        self.__photo = tkinter.BitmapImage(**kw)\n\n    def __del__(self):\n        name = self.__photo.name\n        self.__photo.name = None\n        try:\n            self.__photo.tk.call(\"image\", \"delete\", name)\n        except Exception:\n            pass  # ignore internal errors\n\n    def width(self):\n        \"\"\"\n        Get the width of the image.\n\n        :return: The width, in pixels.\n        \"\"\"\n        return self.__size[0]\n\n    def height(self):\n        \"\"\"\n        Get the height of the image.\n\n        :return: The height, in pixels.\n        \"\"\"\n        return self.__size[1]\n\n    def __str__(self):\n        \"\"\"\n        Get the Tkinter bitmap image identifier.  This method is automatically\n        called by Tkinter whenever a BitmapImage object is passed to a Tkinter\n        method.\n\n        :return: A Tkinter bitmap image identifier (a string).\n        \"\"\"\n        return str(self.__photo)\n\n\ndef getimage(photo):\n    \"\"\"Copies the contents of a PhotoImage to a PIL image memory.\"\"\"\n    im = Image.new(\"RGBA\", (photo.width(), photo.height()))\n    block = im.im\n\n    _pyimagingtkcall(\"PyImagingPhotoGet\", photo, block.id)\n\n    return im\n\n\ndef _show(image, title):\n    \"\"\"Helper for the Image.show method.\"\"\"\n\n    class UI(tkinter.Label):\n        def __init__(self, master, im):\n            if im.mode == \"1\":\n                self.image = BitmapImage(im, foreground=\"white\", master=master)\n            else:\n                self.image = PhotoImage(im, master=master)\n            super().__init__(master, image=self.image, bg=\"black\", bd=0)\n\n    if not tkinter._default_root:\n        raise OSError(\"tkinter not initialized\")\n    top = tkinter.Toplevel()\n    if title:\n        top.title(title)\n    UI(top, image).pack()\n", "path": "src/PIL/ImageTk.py"}], "after_files": [{"content": "#\n# The Python Imaging Library.\n# $Id$\n#\n# a Tk display interface\n#\n# History:\n# 96-04-08 fl   Created\n# 96-09-06 fl   Added getimage method\n# 96-11-01 fl   Rewritten, removed image attribute and crop method\n# 97-05-09 fl   Use PyImagingPaste method instead of image type\n# 97-05-12 fl   Minor tweaks to match the IFUNC95 interface\n# 97-05-17 fl   Support the \"pilbitmap\" booster patch\n# 97-06-05 fl   Added file= and data= argument to image constructors\n# 98-03-09 fl   Added width and height methods to Image classes\n# 98-07-02 fl   Use default mode for \"P\" images without palette attribute\n# 98-07-02 fl   Explicitly destroy Tkinter image objects\n# 99-07-24 fl   Support multiple Tk interpreters (from Greg Couch)\n# 99-07-26 fl   Automatically hook into Tkinter (if possible)\n# 99-08-15 fl   Hook uses _imagingtk instead of _imaging\n#\n# Copyright (c) 1997-1999 by Secret Labs AB\n# Copyright (c) 1996-1997 by Fredrik Lundh\n#\n# See the README file for information on usage and redistribution.\n#\n\nimport tkinter\nfrom io import BytesIO\n\nfrom . import Image\nfrom ._deprecate import deprecate\n\n# --------------------------------------------------------------------\n# Check for Tkinter interface hooks\n\n_pilbitmap_ok = None\n\n\ndef _pilbitmap_check():\n    global _pilbitmap_ok\n    if _pilbitmap_ok is None:\n        try:\n            im = Image.new(\"1\", (1, 1))\n            tkinter.BitmapImage(data=f\"PIL:{im.im.id}\")\n            _pilbitmap_ok = 1\n        except tkinter.TclError:\n            _pilbitmap_ok = 0\n    return _pilbitmap_ok\n\n\ndef _get_image_from_kw(kw):\n    source = None\n    if \"file\" in kw:\n        source = kw.pop(\"file\")\n    elif \"data\" in kw:\n        source = BytesIO(kw.pop(\"data\"))\n    if source:\n        return Image.open(source)\n\n\ndef _pyimagingtkcall(command, photo, id):\n    tk = photo.tk\n    try:\n        tk.call(command, photo, id)\n    except tkinter.TclError:\n        # activate Tkinter hook\n        # may raise an error if it cannot attach to Tkinter\n        from . import _imagingtk\n\n        _imagingtk.tkinit(tk.interpaddr())\n        tk.call(command, photo, id)\n\n\n# --------------------------------------------------------------------\n# PhotoImage\n\n\nclass PhotoImage:\n    \"\"\"\n    A Tkinter-compatible photo image.  This can be used\n    everywhere Tkinter expects an image object.  If the image is an RGBA\n    image, pixels having alpha 0 are treated as transparent.\n\n    The constructor takes either a PIL image, or a mode and a size.\n    Alternatively, you can use the ``file`` or ``data`` options to initialize\n    the photo image object.\n\n    :param image: Either a PIL image, or a mode string.  If a mode string is\n                  used, a size must also be given.\n    :param size: If the first argument is a mode string, this defines the size\n                 of the image.\n    :keyword file: A filename to load the image from (using\n                   ``Image.open(file)``).\n    :keyword data: An 8-bit string containing image data (as loaded from an\n                   image file).\n    \"\"\"\n\n    def __init__(self, image=None, size=None, **kw):\n\n        # Tk compatibility: file or data\n        if image is None:\n            image = _get_image_from_kw(kw)\n\n        if hasattr(image, \"mode\") and hasattr(image, \"size\"):\n            # got an image instead of a mode\n            mode = image.mode\n            if mode == \"P\":\n                # palette mapped data\n                image.apply_transparency()\n                image.load()\n                try:\n                    mode = image.palette.mode\n                except AttributeError:\n                    mode = \"RGB\"  # default\n            size = image.size\n            kw[\"width\"], kw[\"height\"] = size\n        else:\n            mode = image\n            image = None\n\n        if mode not in [\"1\", \"L\", \"RGB\", \"RGBA\"]:\n            mode = Image.getmodebase(mode)\n\n        self.__mode = mode\n        self.__size = size\n        self.__photo = tkinter.PhotoImage(**kw)\n        self.tk = self.__photo.tk\n        if image:\n            self.paste(image)\n\n    def __del__(self):\n        name = self.__photo.name\n        self.__photo.name = None\n        try:\n            self.__photo.tk.call(\"image\", \"delete\", name)\n        except Exception:\n            pass  # ignore internal errors\n\n    def __str__(self):\n        \"\"\"\n        Get the Tkinter photo image identifier.  This method is automatically\n        called by Tkinter whenever a PhotoImage object is passed to a Tkinter\n        method.\n\n        :return: A Tkinter photo image identifier (a string).\n        \"\"\"\n        return str(self.__photo)\n\n    def width(self):\n        \"\"\"\n        Get the width of the image.\n\n        :return: The width, in pixels.\n        \"\"\"\n        return self.__size[0]\n\n    def height(self):\n        \"\"\"\n        Get the height of the image.\n\n        :return: The height, in pixels.\n        \"\"\"\n        return self.__size[1]\n\n    def paste(self, im, box=None):\n        \"\"\"\n        Paste a PIL image into the photo image.  Note that this can\n        be very slow if the photo image is displayed.\n\n        :param im: A PIL image. The size must match the target region.  If the\n                   mode does not match, the image is converted to the mode of\n                   the bitmap image.\n        :param box: Deprecated. This parameter will be removed in Pillow 10\n                    (2023-07-01).\n        \"\"\"\n\n        if box is not None:\n            deprecate(\"The box parameter\", 10, None)\n\n        # convert to blittable\n        im.load()\n        image = im.im\n        if image.isblock() and im.mode == self.__mode:\n            block = image\n        else:\n            block = image.new_block(self.__mode, im.size)\n            image.convert2(block, image)  # convert directly between buffers\n\n        _pyimagingtkcall(\"PyImagingPhoto\", self.__photo, block.id)\n\n\n# --------------------------------------------------------------------\n# BitmapImage\n\n\nclass BitmapImage:\n    \"\"\"\n    A Tkinter-compatible bitmap image.  This can be used everywhere Tkinter\n    expects an image object.\n\n    The given image must have mode \"1\".  Pixels having value 0 are treated as\n    transparent.  Options, if any, are passed on to Tkinter.  The most commonly\n    used option is ``foreground``, which is used to specify the color for the\n    non-transparent parts.  See the Tkinter documentation for information on\n    how to specify colours.\n\n    :param image: A PIL image.\n    \"\"\"\n\n    def __init__(self, image=None, **kw):\n\n        # Tk compatibility: file or data\n        if image is None:\n            image = _get_image_from_kw(kw)\n\n        self.__mode = image.mode\n        self.__size = image.size\n\n        if _pilbitmap_check():\n            # fast way (requires the pilbitmap booster patch)\n            image.load()\n            kw[\"data\"] = f\"PIL:{image.im.id}\"\n            self.__im = image  # must keep a reference\n        else:\n            # slow but safe way\n            kw[\"data\"] = image.tobitmap()\n        self.__photo = tkinter.BitmapImage(**kw)\n\n    def __del__(self):\n        name = self.__photo.name\n        self.__photo.name = None\n        try:\n            self.__photo.tk.call(\"image\", \"delete\", name)\n        except Exception:\n            pass  # ignore internal errors\n\n    def width(self):\n        \"\"\"\n        Get the width of the image.\n\n        :return: The width, in pixels.\n        \"\"\"\n        return self.__size[0]\n\n    def height(self):\n        \"\"\"\n        Get the height of the image.\n\n        :return: The height, in pixels.\n        \"\"\"\n        return self.__size[1]\n\n    def __str__(self):\n        \"\"\"\n        Get the Tkinter bitmap image identifier.  This method is automatically\n        called by Tkinter whenever a BitmapImage object is passed to a Tkinter\n        method.\n\n        :return: A Tkinter bitmap image identifier (a string).\n        \"\"\"\n        return str(self.__photo)\n\n\ndef getimage(photo):\n    \"\"\"Copies the contents of a PhotoImage to a PIL image memory.\"\"\"\n    im = Image.new(\"RGBA\", (photo.width(), photo.height()))\n    block = im.im\n\n    _pyimagingtkcall(\"PyImagingPhotoGet\", photo, block.id)\n\n    return im\n\n\ndef _show(image, title):\n    \"\"\"Helper for the Image.show method.\"\"\"\n\n    class UI(tkinter.Label):\n        def __init__(self, master, im):\n            if im.mode == \"1\":\n                self.image = BitmapImage(im, foreground=\"white\", master=master)\n            else:\n                self.image = PhotoImage(im, master=master)\n            super().__init__(master, image=self.image, bg=\"black\", bd=0)\n\n    if not tkinter._default_root:\n        raise OSError(\"tkinter not initialized\")\n    top = tkinter.Toplevel()\n    if title:\n        top.title(title)\n    UI(top, image).pack()\n", "path": "src/PIL/ImageTk.py"}]}