【问题标题】:How to Solve Base64 Image Error When UsingTkinter使用Tkinter时如何解决Base64图像错误
【发布时间】:2019-04-19 18:42:38
【问题描述】:

我想使用 tkinter 显示 base64 图像。 我在 jupyter notebook 上运行 python 3。

我做了以下,基于this question

  1. 我导入一个 PNG 图像并将其转换为 base64 格式

  2. 我尝试使用 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()
    

    我得到了错误:

    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>
    

有人知道怎么解决吗?

【问题讨论】:

  • 为什么不通过image_file.read()?还是直接输入文件名?
  • 有趣的问题。我注意到即使不涉及 Tkinter,也会发生此错误。 import base64; import io; from PIL import Image; 后跟 with open("output.png", "rb") as image_file: Image.open(io.BytesIO(base64.b64encode(image_file.read()))) 会产生同样的错误。
  • @CristiFati 这只是为了演示,以便人们可以轻松地重现我的问题。实际上,我有很多 base64 图像存储在 pandas 数据框中。

标签: python python-imaging-library


【解决方案1】:

您链接到的问题似乎使用了tkinter.PhotoImage 类,该类与您的代码使用的PIL.ImageTk.PhotoImage 类具有不同的接口。后者接受一个普通的bytes 对象。您不需要先对其进行 base64 编码。

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()

或者,继续对您的数据进行 base64 编码,但使用 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()

【讨论】:

  • 非常感谢您的回答!实际上,我需要使用 base64 字符串,因为我所有的图像都是这样给出的。如果我用 tk.PhotoImage(..) 替换 ImageTk.PhotoImage,我得到错误:TclError: image "pyimage1" doesn't exist
  • 如果我写root = tk.Toplevel()而不是root = tk.Tk(),它似乎可以工作。图像显示..但也打开一个小的空图像。
  • 是的,我认为用 tk.PhotoImage 替换 ImageTk.PhotoImage 不是一个好主意。如果您的数据以 b64 编码开始,您是否尝试过对其进行解码? im = ImageTk.PhotoImage(data=base64.b64decode(image_data))。是的,我认识到这正是链接问题的 OP 所尝试的,但没有成功,但他没有使用您正在使用的相同类。
  • 是的,我能做到。但是我担心解码的计算时间。为什么我不应该只使用ImageTk.PhotoImage(…) 而不是tk.PhotoImage(…)
  • 其实,用 tk.PhotoImage 替换 ImageTk.PhotoImage 可能好的。如果我在我的机器上尝试,它工作正常,没有TclError: image "pyimage1" doesn't exist 可见。我不认为使用root = tk.Toplevel() 与它有任何关系。您可能只需要运行该程序两次即可清除一些不良缓存数据或其他内容。尝试将其改回root = tk.Tk()
猜你喜欢
  • 2016-01-25
  • 2015-02-28
  • 2023-03-06
  • 2021-04-03
  • 2022-06-10
  • 2012-09-15
  • 2011-08-18
  • 1970-01-01
  • 2021-10-09
相关资源
最近更新 更多