在Tkinter中调整图片大小时遇到​​麻烦

问题描述

我有几个从tkinter窗口上的文件夹循环播放的图像。但是,每张图像都有不同的大小,我无法在代码本身中调整它们的大小

import tkinter as tk
import glob
root = tk.Tk()
root.geometry('600x600')

pics = glob.glob("./Images/*.png")
photos = [tk.PhotoImage.resize(20,20)(file=x) for x in pics]
label = tk.Label()
label.photos = photos
label.counter = 0
def cimage():
    label['image'] = label.photos[label.counter%len(label.photos)]
    label.after(3000,cimage)
    label.counter += 1
label.pack()
cimage()

root.mainloop()

版本2:还尝试了以下操作,并得到了相同的错误

import tkinter as tk
import glob
from PIL import Image,ImageTk
root = tk.Tk()
root.geometry('600x600')

pics = glob.glob("./Images/*.png")
photos=pics.resize((20,20),Image.ANTIALIAS)
photosresized = [tk.PhotoImage(file=x) for x in photos]
label = tk.Label()
label.photosresized = photosresized
label.counter = 0
def changeimage():
    label['image'] = label.photosresized[label.counter%len(label.photosresized)]
    label.after(3000,changeimage)
    label.counter += 1
label.pack()
changeimage()

root.mainloop()

跟踪:

Traceback (most recent call last):
  File "/Users/ad/Documents/Python/Project_tkinter/test1.py",line 85,in <module>
    photos = [tk.PhotoImage.resize(20,20)(file=x) for x in pics]
  File "/Users/ad/Documents/Python/Project_tkinter/test1.py",in <listcomp>
    photos = [tk.PhotoImage.resize(20,20)(file=x) for x in pics]
AttributeError: type object 'PhotoImage' has no attribute 'resize'

第二个版本的跟踪:

Traceback (most recent call last):
  File "/Users/ad/Documents/Python/Project_tkinter/test1.py",line 86,in <module>
    photos=pics.resize((20,Image.ANTIALIAS)
AttributeError: 'list' object has no attribute 'resize'

谢谢大家!

以下是我对Joel Toutloff的代码所做的更改,以在调整大小时保持宽高比

basewidth = 20
for i in pics:
    single_image = Image.open(i)
    wpercent = (basewidth / float(single_image.size[0]))
    hsize = int((float(single_image.size[1]) * float(wpercent)))
    changed_size = single_image.resize((basewidth,hsize),Image.ANTIALIAS)
    pid = ImageTk.PhotoImage(single_image.resize((basewidth,Image.ANTIALIAS))
    photosresized.append(pid)

解决方法

您应该使用PIL.Image.resize()函数来调整图像大小:

import glob
import tkinter as tk
from PIL import Image,ImageTk

root = tk.Tk()
root.geometry('600x600')

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

label.counter = 0

pics = glob.glob("./Images/*.png")
label.photosresized = [ImageTk.PhotoImage(Image.open(x).resize((20,20),Image.ANTIALIAS)) for x in pics]

def changeimage():
    label['image'] = label.photosresized[label.counter%len(label.photosresized)]
    label.counter += 1
    label.after(3000,changeimage)

changeimage()

root.mainloop()
,

因此glob.glob为您提供了文件名列表,因此您将必须使用“ pics [0]”之类的文件进行访问,但这也只会为您提供文件名,而不是实际的图像。 您需要先将图像实际加载到活动内存中,然后才能使用它们:

import tkinter as tk
import glob
from PIL import Image,ImageTk
root = tk.Tk()
root.geometry('600x600')

pics = glob.glob("./Images/*.png")
photosresized = []
for i in pics:
    single_image = Image.open(i)
    changed_size = single_image.resize((20,Image.ANTIALIAS)
    pid = ImageTk.PhotoImage(single_image.resize((20,Image.ANTIALIAS))
    photosresized.append(pid)
label = tk.Label()
label.photosresized = photosresized
label.counter = 0
def changeimage():
    label['image'] = label.photosresized[label.counter%len(label.photosresized)]
    label.after(3000,changeimage)
    label.counter += 1
label.pack()
changeimage()

root.mainloop()

这不会以任何方式更改实际文件。每次使用“ Image.open”将它们加载一次,然后调整它们的大小并将其保存到“照片调整大小”列表中,以便在动画中使用。

还请注意,我将tk.PhotoImage更改为ImageTk.PhotoImage,因为使用PIL是首选。