PIL has ImageTk KeyError <PIL.ImageTk.PhotoImage object at 0x0000025A48201690>

I am making a photo display app, to replace the windows default one. I am using Pillow and ImageTk to display them, however my issue is that I am trying to use some code to rotate the image in a different direction. When I run the code I get this issue:

Exception in Tkinter callback
Traceback (most recent call last):
  File "C:\Users\james\AppData\Local\Programs\Python\Python310\lib\tkinter\__init__.py", line 1921, in __call__
    return self.func(*args)
  File "c:\Users\james\OneDrive\Documents\Coding\Python\Apps for Computer\photo_viewer.py", line 51, in rotate_left
    newimg = ImageTk.PhotoImage(img, size=(img.width(), img.height()))
  File "C:\Users\james\AppData\Local\Programs\Python\Python310\lib\site-packages\PIL\ImageTk.py", line 108, in __init__
    mode = Image.getmodebase(mode)
  File "C:\Users\james\AppData\Local\Programs\Python\Python310\lib\site-packages\PIL\Image.py", line 267, in getmodebase
    return ImageMode.getmode(mode).basemode
  File "C:\Users\james\AppData\Local\Programs\Python\Python310\lib\site-packages\PIL\ImageMode.py", line 74, in getmode
    return _modes[mode]
KeyError: <PIL.ImageTk.PhotoImage object at 0x00000277E66616C0>

So, here is a refined version of the code to show you how it works:

import tkinter
from tkinter.filedialog import askopenfile
from PIL import Image, ImageTk

img_exten = r"*.png  *.bmp  *jpeg  *.bmp  *.ico  *.gif  *.jpg"
filetypes = (
    ("Image Files", img_exten),
    ("All Files", "*.*")
)

selected_image = ""
img = ""

root = tkinter.Tk()


def open_image():
    global selected_image
    global img
    try:
        selected_image = askopenfile(title="Open Image", filetypes=filetypes).name
        root.title(selected_image + " - Photos")
        img_temp = Image.open(selected_image)
        ar = img_temp.width / img_temp.height
        height = 540
        width = int(height * ar)
        root.geometry(str(width + 30) + "x" + str(height + 50))
        img_temp = img_temp.resize((width, height), Image.ANTIALIAS)
        img = ImageTk.PhotoImage(img_temp)
        image_area.create_image(1, 1, image=img, anchor="nw")
    except Exception as e:
        print(e)


def rotate_left():
    global img
    newimg = ImageTk.PhotoImage(img, size=(img.width(), img.height()))
    for x in range(img.width()):
        for y in range(img.height()):
            rgb = '#%02x%02x%02x' % img.get(x, y)
            newimg.put(rgb, (x, y))
    newimg.put(rgb (img.height() - y, x))
    img = newimg
    image_area.create_image(1, 1, image=img, anchor="nw")


image_area = tkinter.Canvas(root, width=960, height=540)
image_area.grid(column=1, row=1)


menu_bar = tkinter.Menu(root)
filemenu = tkinter.Menu(menu_bar, tearoff=0)
filemenu.add_command(label="Open", command=open_image)
filemenu.add_command(label="Close", command=close_image)
menu_bar.add_cascade(label="File", menu=filemenu)

toolsmenu = tkinter.Menu(menu_bar, tearoff=0)
toolsmenu.add_command(label="Rotate left", command=rotate_left)
menu_bar.add_cascade(label="Tools", menu=toolsmenu)

root.config(menu=menu_bar)
tkinter.mainloop()
  • James

Solution 1:

Your code does not have a img_temp.rotate anywhere!

In your rotate_left function try making a copy of img_temp then rotate it. This code snippet works for me.

def rotate_left():
    global img
    # pass original image open reference
    global img_temp 
    # make a copy
    extra = img_temp.copy()
    # rotate it
    new = extra.rotate(45, expand = False)
    # self.new.save(new_picture_name)
    # make image
    newimg = ImageTk.PhotoImage(new, size=(img.width(), img.height()))
    # update old image
    img = newimg
    image_area.create_image(1, 1, image=img, anchor="nw")
    # update old image open reference
    img_temp = new