Tkinter 错误:无法识别图像文件中的数据
- 2025-02-20 09:24:00
- admin 原创
- 99
问题描述:
我正在尝试将 jpg 图像放入 tkinter 画布。tkinter 给了我这个错误:
无法识别图像文件中的数据
我使用文档中的代码:
canv = Canvas(root, width=80, height=80, bg='white')
canv.grid(row=2, column=3)
img = PhotoImage(file="bll.jpg")
canv.create_image(20,20, anchor=NW, image=img)
png 图像也一样。甚至尝试将图像放入标签小部件,但出现同样的错误。出了什么问题?
我在 Mac 上使用 Python 3。Python 文件和图像位于同一个文件夹中。
解决方案 1:
您的代码似乎正确,它在 Windows 7(Python 3.6)上为我运行:
from tkinter import *
root = Tk()
canv = Canvas(root, width=80, height=80, bg='white')
canv.grid(row=2, column=3)
img = PhotoImage(file="bll.jpg")
canv.create_image(20,20, anchor=NW, image=img)
mainloop()
产生这个 tkinter GUI:
此图像为
bll.jpg
:
(imgur 将其转换为bll.png
但这对我来说也有效。)
更多选项:
这个答案提到,tkinter 仅适用于
gif
图像。尝试使用.gif
图像。如果这不起作用,请按照此答案
PIL
中所述使用。
更新:解决方案PIL
:
from tkinter import *
from PIL import ImageTk, Image
root = Tk()
canv = Canvas(root, width=80, height=80, bg='white')
canv.grid(row=2, column=3)
img = ImageTk.PhotoImage(Image.open("bll.jpg")) # PIL solution
canv.create_image(20, 20, anchor=NW, image=img)
mainloop()
解决方案 2:
我遇到了同样的问题。我有 Windows 和 Python 3.6。因此,我找到了两种解决方案,要么使用/转换为.png
图像(使用您使用的相同函数):
photo = PhotoImage('xyz.png')
l = Label(image = photo)
l.pack()
或者如果您只想读取.jpg
文件,那么使用 PIL 库来读取并显示这样的图像:
from PIL import ImageTk, Image
img = ImageTk.PhotoImage(Image.open("xyz.jpg"))
l=Label(image=img)
l.pack()
解决方案 3:
使用以下方式安装 PIL/Pillow:
pip install Pillow
或者:
sudo pip install pillow
from PIL import Image
from PIL import ImageTk
import tkinter
image = Image.open('bll.jpg')
image = image.resize((20, 20))
image = ImageTk.PhotoImage(image)
canv = Canvas(root, width=80, height=80, bg='white')
canv.grid(row=2, column=3)
img = PhotoImage(file=image)
另外,对于 Tkinter 来说,使用 .PNG 而不是 .JPG 更好。
解决方案 4:
直接回答原始问题:Tkinter 目前不支持 JPG 图像,而 PNG 支持依赖于系统的 Tcl/Tk 版本 - 一个用 C 编写的独立库,Python 通过 Tkinter 与其交互(因此有“inter”部分)。这个流行的第三方库pillow
为 Tkinter 类提供了直接替代PhotoImage
,使其能够支持更多图像格式。
Tkinter 支持的图像格式
Tcl /Tk 手册描述了对两种独立图像类型的支持 -bitmap
和photo
- 描述如下:
位图是一种像素可以显示两种颜色或透明的图像。
照片是一种图像,其像素可以显示任何颜色或透明。照片图像以全彩色(每像素 32 位)在内部存储,并在必要时使用抖动显示。
这些在 Tkinter 中分别反映为BitmapImage
和PhotoImage
类。Tkinter支持的格式略微取决于安装的 Tcl/Tk版本。但是,从 3.10 开始,官方 Python 二进制版本中包含 Tcl/Tk 8.6 的线程版本
Python Tkinter 文档主要侧重于解释 Tkinter 在 Tcl/Tk 之上添加的功能。对于大多数事情,用户应该参考 Tcl/Tk 文档(或第三方来源;Python 文档提供了一些建议)并了解界面的一般工作原理。
正如Donal Fellows 在另一个 Stack Overflow 问题上指出的那样,Tcl/Tk 无法处理超过 2GB 的单独内存分配,这在理论上限制了图像大小。
BitmapImage类
Tcl/Tkbitmap
比 s 有更多限制photo
,因此实际上PhotoImage
会更常用。但为了完整性:BitmapImage
支持 BMP (跨平台)、XPM(用于像素图/彩色位图,主要在 X11 上)和 ICO 格式(ICO 是一种主要用于 Windows 图标的特殊位图)。
PhotoImage类
正如 Tcl/Tk 文档中所述,photo
可以从包含原始图像数据的数据字符串创建:
该字符串应该包含二进制数据,或者对于某些格式,包含 base64 编码数据(目前保证支持 PNG 和 GIF 图像)。
PhotoImage
无论 Tcl/Tk 版本是什么,都支持GIF、PPM和PGM图像。
需要Tcl/Tk 版本 8.4来支持透明度。(但是,由于 8.3 分支自 2002 年以来一直未维护,因此几乎可以保证当前支持 Tkinter 的 Python 安装将具有透明度支持。)
Tcl/Tk 版本 8.6增加了对 PNG 图像的支持。如果可能的话,图像将进行伽马校正:
此外,实施应该......[a]允许通过
gAMA
将显示伽马(如果已知)与导入的图像块(如果存在)结合应用-format "png -gamma value"
。
计划 在 Tcl/Tk 8.7(目前为 alpha 版本)中提供SVG 支持(但有一些限制)。如果版权问题能够得到解决,未来可能会包含 JPEG 支持。
此外,还有几种方法可以扩展默认库支持:
TCL 扩展,例如Img和tclimage
使用 Tcl 的 C API 编写的自定义处理程序:参见TkCreatePhotoImageFormat
Python 扩展:pillow支持多种格式,均可使用ImageTk 模块进行转换
验证图像格式
Stack Overflow 上询问的有关 Tkinter 图像支持的许多其他问题,最终都是由于图像格式不符合程序员的期望而导致的。请注意,如果 Tkinter 尚不支持图像格式,则简单地将文件重命名为具有适当的后缀将无济于事。后缀只是提示文件中应包含哪些数据。(底层 Tcl/Tk 库也允许明确指定格式,但主要是从后缀和/或数据本身推断出来的。)
以下是一些验证图像格式的方法:
使用图像编辑程序打开它。(无论如何,以指定格式重新保存图像是迄今为止解决不支持格式问题的最简单方法,因此这通常是最实用的方法。)
使用命令行工具,例如
file
Linux上的命令。以编程方式打开文件并检查前几个字节,例如使用第三方文件类型包。
如果所需图像不受支持,只需使用异常处理(
try
/ )并返回到占位符图像。(无论如何,这可能是必要的,例如,如果图像损坏或丢失。)except
解决方案 5:
另一个替代解决方案:
filename = ImageTk.PhotoImage(Image.open('imagename.jpeg' ))
background_label = tk.Label(self.root, image=filename)
background_label.place(x=0, y=0, relwidth=1, relheight=1)
解决方案 6:
使用 Python 包 Pillow 对我来说很有用。
只需执行 pip install pillow 即可。
然后使用 ImageTk.PhotoImage(Image.open("Your image path goes here...")) 而不是 tkinter.PhotoImage()
解决方案 7:
# in terminal pip install pillow
from tkinter import *
from PIL import Image, ImageTk
a_root = Tk()
# WINDOW SIZING
a_root.geometry("600x400")
a_root.minsize(400, 400)
a_root.maxsize(800, 800)
# for PNG IMG
# photo = PhotoImage(file="mark1.png")
# for JPG IMG
image = Image.open("mark.jpg")
photo = ImageTk.PhotoImage(image)
img_label = Label(image=photo)
img_label.pack()
a_root.mainloop()
解决方案 8:
我遇到了同样的错误。你只需要使用 PNG 文件而不是 jpeg/jpg。如果你没有 png 版本,你可以在这里转换图片 ---> https://cloudconvert.com/
from tkinter import *
root = Tk()
root.geometry("1920x1080")
photo = PhotoImage(file="Akatsuki.png")
label = Label(image=photo)
label.pack()
root.mainloop()
解决方案 9:
您的 Tkinter 版本不支持 jpg。我通过安装内置 8.6.11 Tcl/Tk 的 python 3.10 来修复它。https
://www.python.org/download/mac/tcltk/
解决方案 10:
此错误可能是由于文件路径中的relative file path
或non-English
字符而发生的。因此我创建了这个函数,它在 Windows 和任何类型的文件路径中都运行良好:
def loadrelimages(relativepath):
from PIL import ImageTk, Image
import os
directory_path = os.path.dirname(__file__)
file_path = os.path.join(directory_path, relativepath)
img = ImageTk.PhotoImage(Image.open(file_path.replace('\\', "/")))
return img
例如,加载photo_2021-08-16_18-44-28.jpg
与此代码位于同一目录:
from tkinter import *
import os
def loadrelimages(relativepath):
from PIL import ImageTk, Image
import os
directory_path = os.path.dirname(__file__)
file_path = os.path.join(directory_path, relativepath)
img = ImageTk.PhotoImage(Image.open(file_path.replace('\\',"/")))
return img
root = Tk()
canvas = Canvas(root, width=500, height=500)
canvas.pack()
loadedimage=loadrelimages('photo_2021-08-16_18-44-28.jpg')
canvas.create_image(250, 250, image=loadedimage)
root.mainloop()
解决方案 11:
安装 Python 的 OpenCV 包:
pip install opencv-python
然后尝试一下这个代码:
import cv2
Img = cv2.imread("xxxxx.png")
cv2.imwrite("xxxxx.png",img)
# Your code goes here!
扫码咨询,免费领取项目管理大礼包!