Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Alpha channel ignored in tkinter using PIL.Image.open and PIL.ImageTk.PhotoImage for PNGs in palette mode #6558

Closed
BenediktO opened this issue Sep 3, 2022 · 2 comments · Fixed by #6559

Comments

@BenediktO
Copy link

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) I see this:
Bildschirmfoto 2022-09-03 18:53:25

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.

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()
@BenediktO BenediktO changed the title Alpha channel ignored in tkinter for PNGs in palette mode Alpha channel ignored in tkinter using PIL.Image.open and PIL.ImageTk.PhotoImage for PNGs in palette mode Sep 4, 2022
@nulano
Copy link
Contributor

nulano commented Sep 4, 2022

Looking at ImageTk.PhotoImage, if it is passed an image with a palette, it automatically converts the image to the mode of the palette before passing it to tkinter:

Pillow/src/PIL/ImageTk.py

Lines 108 to 112 in b6348d9

if mode == "P":
# palette mapped data
image.load()
try:
mode = image.palette.mode

However, your first image is loaded with a palette with mode RGB, not RGBA as you might expect.
This was discussed in #6348, and #6352 added a new function image.apply_transparency() to convert the palette of PNG images from RGB to RGBA in Pillow 9.2.0.

from tkinter import Tk, Label, PhotoImage

from PIL import Image, ImageTk


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

image

@radarhere
Copy link
Member

I've created PR #6559 to resolve this by automatically applying apply_transparency() in ImageTk.PhotoImage.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants