Adding multiple images from a list in Tkinter Python - python

I have a few images that I would like to display. I have tried storing the labels in a list, however when I call pack() only the last png shows like so:
How can I make them all appear?
import os
icons = []
for f in os.listdir():
if f.endswith('.png'):
print(f)
img = Image.open(f)
resized = img.resize((16, 16), Image.ANTIALIAS)
new_img = ImageTk.PhotoImage(resized)
label_img = tk.Label(root, image=new_img)
icons.append(label_img)
label_img.pack()

Related

How to display image in Tkinter on the fly?

I've written a snippet of code to display images in a Tkinter app. However, the image does not display unless I read all of the images before assigning it to the label. Here is my code:
from tkinter import *
from PIL import ImageTk, Image
root = Tk()
root.title("Image Viewer app")
def readImage(image_name):
my_img = Image.open(image_name)
my_img = my_img.resize((640, 360), Image.ANTIALIAS)
my_img = ImageTk.PhotoImage(my_img)
return my_img
frame_lst = list(range(0,120))
img_lst = []
path = "usr/data/images"
start = time.time()
for file in os.listdir(path):
if file.endswith('.jpg'):
filepath = os.path.join(path, file)
img_lst.append(filepath) #print time taken
end = time.time()
print(f"Time taken to read images is {end-start} seconds")
image_displayed = Label(image=readImage(img_lst[0]))
image_displayed.grid(row=0,column=0,columnspan=3)
root.mainloop()
This does not work but if I replace img_lst.append(filepath) with img_lst.append(imageRead(filepath)) and image_displayed = Label(image=readImage(img_lst[0])) with image_displayed = Label(image=img_lst[0]) then it works.
That is, the app does not work when I try to read the image directly without preloading it in memory. Where am I going wrong?
Since there is no variable to store the reference of the image returned by readImage() in the following line:
image_displayed = Label(image=readImage(img_lst[0]))
the image will be garbage collected. Use a variable to store the reference, like below:
image = readImage(img_lst[0]) # save the reference of the image
image_displayed = Label(image=image)

Python pack() function in for loops doesnt seem to wo

I want python to iterate images in a directory and pack that to the GUI
from tkinter import *
from pathlib import Path
from PIL import ImageTk, Image
root = Tk()
images = []
paths = Path("images").glob('**/*.png')
for path in paths:
photo = Image.open(path)
photo.thumbnail((100, 100))
img = ImageTk.PhotoImage(photo)
label = Label(image=img)
images.append(label)
for image in images:
image.pack()
root.mainloop()
But the output is just the last picture on the directory:
here my attempt:
from tkinter import *
from pathlib import Path
from PIL import ImageTk, Image
pippo = Tk()
images = []
paths = Path("images").glob('**/*.png')
for path in paths:
print(path)
photo = Image.open(path)
photo.thumbnail((100, 100))
img = ImageTk.PhotoImage(photo)
images.append(img)
print(images)
for img in images:
label = Label(pippo, image=img)
label.pack(side = 'bottom')
pippo.mainloop()
output starting from three colored circles is:

Display image in tkinter

I don't know why this code is not displaying any image when I run it.
from tkinter import *
import os
root = Tk()
images = os.listdir()
i = 0
for images in images:
if images.endswith(".png"):
photo = PhotoImage(file=images)
label = Label(image=photo)
label.pack()
print("reached here")
root.mainloop()
So basically you need to have PIL installed
pip install PIL
then
from tkinter import *
import os
from PIL import Image, ImageTk
root = Tk()
images = os.listdir()
imglist = [x for x in images if x.lower().endswith(".jpg")]
for index, image in enumerate(imglist): #looping through the imagelist
photo_file = Image.open(image)
photo_file = photo_file.resize((150, 150),Image.ANTIALIAS) #resizing the image
photo = ImageTk.PhotoImage(photo_file) #creating an image instance
label = Label(image=photo)
label.image = photo
label.grid(row=0, column=index) #giving different column value over each iteration
print("reached here with "+image)
root.mainloop()
If you want to use pack() manager, then change
for image in imglist:
....... #same code as before but grid() to
label.pack()
Do let me know if any errors or doubts
Cheers
I played a little and got some results. You can refine it:
from tkinter import *
import os
root = Tk()
images = os.listdir()
imglist = [x for x in images if x.lower().endswith(".png")]
i = 0
photolist = []
labellist= []
for image in imglist:
photo = PhotoImage(file=image)
photolist.append(photo)
label = Label(image=photo)
labellist.append(label)
label.pack()
print("reached here with "+image)
root.mainloop()

tkinter - When resizing color image, it shows up in red scale only

I have the following piece of code:
from tkinter import *
from tkinter import filedialog
from PIL import Image, ImageTk
import cv2
import os
import glob
import numpy as np
image_path = ""
image_list = []
class Proj:
def __init__(self, master):
self.master = master
#GUI height and width
w = 1250
h = 600
# open folder manager to select image folder
image_path = filedialog.askdirectory()
master.geometry("%dx%d%+d%+d" % (w ,h ,0,0))
master.resizable(True,True)
#read in images from folder
self.read_images(master, image_path)
#cv2.imshow('image',cv2.imread(image_list[0], 1))
self.img = cv2.imread(image_list[0])
self.img = Image.fromarray(np.array(self.img).copy())
self.img.thumbnail((w//2, w//2+10))
self.img = ImageTk.PhotoImage(self.img)
image_frame = Frame(master)
image_frame.grid(row = 0, column = 0, columnspan = 3, rowspan = 5)
left_panel = Canvas(image_frame, width=w//2, height=h-70)
left_panel.grid(row=0, column=0, columnspan=4)
imgA_handler = left_panel.create_image((0,0), image = self.img, anchor="nw")
right_panel = Canvas(image_frame, width=w//2, height=h-70)
right_panel.grid(row=0, column=5, columnspan=4)
def read_images(self, master, path):
images = path + '/*.tif'
for img in glob.glob(images): #will only read in tif images
image_list.append(img)
root = Tk()
example = Proj(root)
root.mainloop()
I am reading in color .tif images and then trying to display them in the left_panel. However, when I go to do that, it shows the normal color image only in red scale even though I never extracted just the red signal. I am completely unable to diagnose the issue. How do I fix this issue?
Ultimately, what I want to do is display two images on this GUI. An original image on the left and a modified image on the right. Currently my gui layout is set up as I've coded above. However, if you think there is an easier way to do this, then I'd be interested to hear.
This is because opencv uses BGR instead of RGB. When you are using this line: self.img = Image.fromarray(np.array(self.img).copy()) Blue and Red colors are being swapped. Just before you use the above code, convert the BGR to RGB in opencv and you should be good to go.
self.img = cv2.cvtColor(self.img,cv2.COLOR_BGR2RGB)
I see you are using opencv. Why don't you use the opencv command to resize.
It is very simple and works pretty well.
Take a look at this page:
OpenCV Resize
This is an example to make a image 50% smaller, or instead of the fx and fy, you can put the exact size you want.
thumbnail = cv2.resize(image, (0,0), fx=0.5, fy=0.5)

tkinter: why images are not dysplayed correctly

The code:
from tkinter import *
root = Tk()
f1=Frame(root)
for img,rlf in [ ('woman',RAISED),('mensetmanus',SOLID),
('terminal',SUNKEN), ('escherknot',FLAT),
('calculator',GROOVE),('letters',RIDGE)]:
filename = img + ".gif"
img1 = PhotoImage(file= filename)
Label(f1, image = img1, relief=rlf).pack(side=LEFT,
padx=5)
f1.pack()
root.mainloop()
Could you help me understand why this excerpt produces 5 empty places for images (though borders are drawn correctly according to what was meant), and 1 image. The last image (which is visible) is letters. And it seems to be cropped from than its actual size. My letters.gif contains letters from A to G, but this code displays only from half B to half F.
It does not work, i think, because img1 is overwritten in each loop. You need to keep references to image objects somewhere, so that garbage collector wont trash them:
from tkinter import *
root = Tk()
f1=Frame(root)
img_list = [] #<-- store references to images
for img,rlf in [ ('woman',RAISED),('mensetmanus',SOLID),
('terminal',SUNKEN), ('escherknot',FLAT),
('calculator',GROOVE),('letters',RIDGE)]:
filename = img + ".gif"
img1 = PhotoImage(file= filename)
img_list.append(img1) #<-- store references to images
Label(f1, image = img1, relief=rlf).pack(side=LEFT,
padx=5)
f1.pack()
root.mainloop()

Categories