pythonpython-3.xtkinterpython-imaging-libraryphotoimage

Error while converting PIL image to Tkinter image


I'm trying to rotate an image using Pillow:

img = Image.open("./assets/aircraftCarrier/aircraftCarrier0.gif")

img = img.rotate(270)

This rotates the image but when I try to save it Pillow doesn't seem to recognise the file type, even if I put the format type when saving it:

img.save("./tempData/img", "GIF")

It comes up with a file with a blank extension

Now this doesn't really matter as long as tkinter can recognise it with PhotoImage, but that doesn't seem to work either:

img = PhotoImage(img)

label = Label(root, image=img)
label.pack()

I get this error message:

TypeError: __str__ returned non-string (type Image)

I'm not really sure what I've done wrong or if I need to do more processing with Pillow.

Help would be greatly appreciated,

Josh


Full code:

import tkinter as tk
from tkinter import *
import tkinter
from PIL import Image

root = tk.Tk()
root.title("Test")


img = Image.open("./assets/aircraftCarrier/aircraftCarrier0.gif")

img = img.rotate(270)

img.save("./tempData/img", "GIF")

img = PhotoImage(img)

label = Label(root, image=img)
label.pack()

root.mainloop()

Full error message:

Traceback (most recent call last):
  File "C:\Users\Joshlucpoll\Documents\Battleships\test.py", line 19, in <module>
    label = Label(root, image=img)
  File "C:\Users\Joshlucpoll\AppData\Local\Programs\Python\Python37-32\lib\tkinter\__init__.py", line 2766, in __init__
    Widget.__init__(self, master, 'label', cnf, kw)
  File "C:\Users\Joshlucpoll\AppData\Local\Programs\Python\Python37-32\lib\tkinter\__init__.py", line 2299, in __init__
    (widgetName, self._w) + extra + self._options(cnf))
TypeError: __str__ returned non-string (type Image)

Solution

  • Ok, looking into the effbot documentation for PhotoImage there are these lines of code:

    from PIL import Image, ImageTk
    
    image = Image.open("lenna.jpg")
    photo = ImageTk.PhotoImage(image)
    

    and it states:

    If you need to work with other file formats, the Python Imaging Library (PIL) contains classes that lets you load images in over 30 formats, and convert them to Tkinter-compatible image objects

    So it seems you need to add ImageTk before PhotoImage when converting from PIL to Tkinter.

    Eg:

    img = ImageTk.PhotoImage(img)

    Adding this to my program does result in the rotated image to show perfectly.