0

My goal is to display an JPG image from an URL using tkinter python.

This is the stackoverflow link that I used as a reference. But when I try to run the code, I have received a bunch of error such as:

  • KeyError: b'R0l.......
  • AttributeError: 'PhotoImage' object has no attribute '_PhotoImage__photo'

Does anyone have the solution to this?

This is the code:

import tkinter as tk
from PIL import Image, ImageTk
from urllib.request import urlopen
import base64

root = tk.Tk()

URL = "http://www.universeofsymbolism.com/images/ram-spirit-animal.jpg"
u = urlopen(URL)
raw_data = u.read()
u.close()


b64_data = base64.encodestring(raw_data)
photo = ImageTk.PhotoImage(b64_data)

label = tk.Label(image=photo)
label.image = photo
label.pack()

root.mainloop()
2
  • I can't get your example to work for me, but try specifying that you're passing in the data parameter with ImageTk.PhotoImage(data=b64_data). Commented Aug 9, 2016 at 16:56
  • @Hobbes: I add the 'data' parameter and the first error (KeyError) disappears. But then a new error appears (OSError: cannot identify image file <_io.BytesIO object at 0x104deb620>) and the AttributeError: 'PhotoImage' object has no attribute '_PhotoImage__photo' is still there. Commented Aug 9, 2016 at 17:04

2 Answers 2

3

The first error is not specifying the data parameter within ImageTk.PhotoImage(data=b64_data). However, I'm unsure why PhotoImage is unable to read base64 data.

A workaround would be to use BytesIO from the io module. You can pass in the raw data you read from the image into a BytesIO, open it in Image and then pass that into PhotoImage.

I found the code for opening the image from here.

import tkinter as tk
from PIL import Image, ImageTk
from urllib2 import urlopen
from io import BytesIO

root = tk.Tk()

URL = "http://www.universeofsymbolism.com/images/ram-spirit-animal.jpg"
u = urlopen(URL)
raw_data = u.read()
u.close()

im = Image.open(BytesIO(raw_data))
photo = ImageTk.PhotoImage(im)

label = tk.Label(image=photo)
label.image = photo
label.pack()

root.mainloop()

If anybody has a better answer as to why the encoding fails, it would be a more appropriate answer to this question.

Sign up to request clarification or add additional context in comments.

2 Comments

Your code works only if I change 'StringIO' to 'BytesIO'. Thank you very much for this workaround solution.
BytesIO makes a lot more sense in this case. I've edited to reflect that.
3

Very similar but easier than Hobbes' answer, you can directly use the data parameter in the ImageTk.PhotoImage constructor:

import tkinter as tk
from PIL import Image, ImageTk
from urllib.request import urlopen

root = tk.Tk()

URL = "http://www.universeofsymbolism.com/images/ram-spirit-animal.jpg"
u = urlopen(URL)
raw_data = u.read()
u.close()

photo = ImageTk.PhotoImage(data=raw_data) # <-----

label = tk.Label(image=photo)
label.image = photo
label.pack()

root.mainloop()

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.