henry
henry

Reputation: 965

How to Solve Base64 Image Error When UsingTkinter

I would like to display a base64 image using tkinter. I am running python 3 on a jupyter notebook.

I have done the following, based on this question:

  1. I import a PNG image and convert it to base64 format

  2. I try to open it using Tkinter

    import base64
    
    with open("IMAGE.png", "rb") as image_file:
        image_data_base64_encoded_string = base64.b64encode(image_file.read()) 
    
    
    
    import tkinter as tk
    from PIL import ImageTk, Image
    
    root = tk.Tk()
    
    im = ImageTk.PhotoImage(data=image_data_base64_encoded_string)
    
    tk.Label(root, image=im).pack()
    
    root.mainloop()
    

    And I get the error:

    OSError                                   Traceback (most recent call last)
    <ipython-input-34-96dab6b5d11a> in <module>()
          5 root = tk.Tk()
          6 
    ----> 7 im = ImageTk.PhotoImage(data=image_data_base64_encoded_string)
          8 
          9 tk.Label(root, image=im).pack()
    
    ~\Anaconda3\lib\site-packages\PIL\ImageTk.py in __init__(self, image, size, **kw)
         92         # Tk compatibility: file or data
         93         if image is None:
    ---> 94             image = _get_image_from_kw(kw)
         95 
         96         if hasattr(image, "mode") and hasattr(image, "size"):
    
    ~\Anaconda3\lib\site-packages\PIL\ImageTk.py in _get_image_from_kw(kw)
         62         source = BytesIO(kw.pop("data"))
         63     if source:
    ---> 64         return Image.open(source)
         65 
         66 
    
    ~\Anaconda3\lib\site-packages\PIL\Image.py in open(fp, mode)
       2655         warnings.warn(message)
       2656     raise IOError("cannot identify image file %r"
    -> 2657                   % (filename if filename else fp))
       2658 
       2659 #
    
    OSError: cannot identify image file <_io.BytesIO object at 0x000001D476ACF8E0>
    

Anyone knows how to solve this ?

Upvotes: 1

Views: 903

Answers (1)

Kevin
Kevin

Reputation: 76194

It looks like the question you have linked to uses the tkinter.PhotoImage class, which has a different interface from the PIL.ImageTk.PhotoImage class that your code is using. The latter accepts an ordinary bytes object. You don't need to base64 encode it first.

import base64

with open("IMAGE.png", "rb") as image_file:
    image_data = image_file.read()


import tkinter as tk
from PIL import ImageTk, Image

root = tk.Tk()

im = ImageTk.PhotoImage(data=image_data)

tk.Label(root, image=im).pack()

root.mainloop()

Alternatively, keep base64encoding your data, but use tkinter.PhotoImage.

import base64

with open("IMAGE.png", "rb") as image_file:
    image_data_base64_encoded_string = base64.b64encode(image_file.read()) 


import tkinter as tk
from PIL import Image

root = tk.Tk()

im = tk.PhotoImage(data=image_data_base64_encoded_string)

tk.Label(root, image=im).pack()

root.mainloop()

Upvotes: 1

Related Questions