Reputation: 43
I'm have couple of images that are looping from a folder on the tkinter window. However, each image has different sizes and I'm not able to resize them in the code itself
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()
Version 2: Also tried the below and got the same error:
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:
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", line 85, in <listcomp>
photos = [tk.PhotoImage.resize(20,20)(file=x) for x in pics]
AttributeError: type object 'PhotoImage' has no attribute 'resize'
Traceback for the second version:
Traceback (most recent call last):
File "/Users/ad/Documents/Python/Project_tkinter/test1.py", line 86,
in <module>
photos=pics.resize((20,20),Image.ANTIALIAS)
AttributeError: 'list' object has no attribute 'resize'
Thanks all appreciated!
Below is the change I made to Joel Toutloff's code to keep the aspect ratio while resizing
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,hsize),Image.ANTIALIAS))
photosresized.append(pid)
Upvotes: 0
Views: 88
Reputation: 484
So glob.glob gives you a list of filenames so you will have to access it with something like "pics[0]", but that will also just give you the filenames and not the actual image. You need to actually load the images into active memory before you can play with them:
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,20),Image.ANTIALIAS)
pid = ImageTk.PhotoImage(single_image.resize((20,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()
This does not change the actual files in any way. It loads them up each one at a time with "Image.open" and then resizes them and saves them into the 'photosresized' list to be used in the animation.
Also note that I changed tk.PhotoImage to be ImageTk.PhotoImage as using things with PIL are preferred.
Upvotes: 1
Reputation: 46669
You should use PIL.Image.resize()
function to resize the image:
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()
Upvotes: 1