I am trying to create a Tkinter to make a window that shows images using a label, then update the image using an update function, but the image that I am trying to show doesn't show up in the Tkinter window, instead, a black screen appears
I have two working code
one that shows an image on the Tkinter window
one what loops a GIF using an update function
I tried to combine them
the code I am working on that doesn't work
#import GUI
from tkinter import *
#change dir
import os
os.chdir("C:/Users/user/Desktop/test image folder/")
#add delay
import time
#import image
from PIL import Image, ImageTk
#set up the window
window = Tk()
#window.title("modify images")
#list of filename
filelist = []
#loop over all files in the working directory
for filename in os.listdir("."):
if not (filename.endswith('.png') or filename.endswith('.jpg')):
continue #skip non-image files and the logo file itself
filelist = filelist + [filename]
#list of filename
print(filelist)
#show first pic
imagefile = filelist[0]
photo = ImageTk.PhotoImage(Image.open(imagefile))
label1 = Label(window, image = photo)
label1.pack()
#update image
def update(ind):
imagefile = filelist[ind]
im = ImageTk.PhotoImage(Image.open(imagefile))
if ind < len(filelist):
ind += 1
else:
ind = 0
label1.configure(image=im)
window.after(2000, update, ind)
window.after(2000, update, 0)
#run the main loop
window.mainloop()
the other code I am trying to combine
1:the one that shows image
import tkinter as tk
from tkinter import *
from PIL import Image, ImageTk # Place this at the end (to avoid any conflicts/errors)
window = tk.Tk()
imagefile = "image.jpg"
img = ImageTk.PhotoImage(Image.open(imagefile))
lbl = tk.Label(window, image = img).pack()
window.mainloop()
print('hi')
2:updates gif
from tkinter import *
#change dir
import os
os.chdir("C:/Users/user/Desktop/Learn Python")
#add delay
import time
##### main:
window = Tk()
##### My Photo
photo1 = [PhotoImage(file="anime.gif", format="gif -index %i" %(i)) for i in range(85)]
#update image
def update(ind):
frame = photo1[ind]
if ind < 84:
ind += 1
else:
ind = 0
label.configure(image=frame)
window.after(80, update, ind)
label = Label(window, bg="black")
label.pack()
window.after(0, update, 0)
#####run the main loop
window.mainloop()
I expect it to show all images in the file one by one
it instead shows only the first image, then the window goes blank
You have problem because there is bug in PhotoImage. If you create it in function and assign to local variable then Garbage Collector removes image from memory and you see empty image. You have to create PhotoImages outside function or you have to assign it to some global variable.
Popular solution is to assign it to label which will display it.
label.im = im
Function:
def update(ind):
imagefile = filelist[ind]
im = ImageTk.PhotoImage(Image.open(imagefile))
if ind < len(filelist):
ind += 1
else:
ind = 0
label1.configure(image=im)
label1.im = im # <-- solution
window.after(2000, update, ind)
Doc: PhotoImage
Related
I have code to display 2x5 images and change them when I click on them. However, the code I wrote does not display any images in the tkinter windows. Why?
Some details:
the URLs are working fine
import tkinter as tk
from PIL import Image, ImageTk
# Create the main window
root = tk.Tk()
# Create a list of images to display
images = ['https://lh3.googleusercontent.com/SsEIJWka3_cYRXXSE8VD3XNOgtOxoZhqW1uB6UFj78eg8gq3G4jAqL4Z_5KwA12aD7Leqp27F653aBkYkRBkEQyeKxfaZPyDx0O8CzWg=s0',
'https://lh3.googleusercontent.com/Bawo7r1nPZV6sJ4OHZJHdKV_4Ky59vquAR7KoUXcNZgx9fqTaOW-QaOM9qoyYhOTAopzjt9OIfW06RMwa-9eJW9KjQw=s0',
'https://lh3.googleusercontent.com/tm1DbZrAP0uBM-OJhLwvKir1Le5LglRF_bvbaNi6m-F_pIyttsWQz040soRY9pWA9PgNEYFA_fBkg_keYixRXCAjz9Q=s0',
'https://lh3.googleusercontent.com/AyiKhdEWJ7XmtPXQbRg_kWqKn6mCV07bsuUB01hJHjVVP-ZQFmzjTWt7JIWiQFZbb9l5tKFhVOspmco4lMwqwWImfgg=s0',
'https://lh3.googleusercontent.com/FNNTrTASiUR0f49UVUY5bisIM-3RlAbf_AmktgnU_4ou1ZG0juh3pMT1-xpQmtN1R8At4Gq9B4ioSSi4TVrgbCZsmtY=s0',
'https://lh3.googleusercontent.com/mAyAjvYjIeAIlByhJx1Huctgeb58y7519XYP38oL1FXarhVlcXW7kxuwayOCFdnwtOp6B6F0HJmmws-Ceo5b_pNSSQs=s0',
'https://lh3.googleusercontent.com/gShVRyvLLbwVB8jeIPghCXgr96wxTHaM4zqfmxIWRsUpMhMn38PwuUU13o1mXQzLMt5HFqX761u8Tgo4L_JG1XLATvw=s0',
'https://lh3.googleusercontent.com/KA2hIo0BlMDmyQDEC3ixvp9WHgcyJnlAvWtVcZmExh9ocPoZdQGRJh7bZjE2Mx2OGC0Zi3QGHGP0LlmuFgRlIYs36Sgn5G2OD-0MaTo=s0',
'https://lh3.googleusercontent.com/N2m90mImdcoLacUybb_rxcktTwtr0LFhtuzxbSE9elIhElF6jpWngx96_uZ0L1TGNof5pNt4n_Ygb4KYlPTpA9o6788=s0',
'https://lh3.googleusercontent.com/1pTfYJlLwVTifKj4PlsWPyAg4PcIVBAiVvB8sameSnmm7HRd056abNUIRq33rgry7u9t-ju-eHOnbfqQpK4q_8IwzIXZ4WgrqZW9l7U=s0',
'https://lh3.googleusercontent.com/0bgOiMrBM2GuhW_pNeQW711GuB3kD7Gq7AILGHaJGeWKa1Fu1hUJGpOjvSpiP_XpgRlC4jVmH0Z1233PEPMJTfNRR7Q=s0',
'https://lh3.googleusercontent.com/x9NFmu-RbZ_9M5BK_hOzQRdVj4pu7p--y_IYwDK46lDPzQtTIO9AlBV_ObgQiY7GeWE0ZfNjMSyrCWgnwL4MCasQZQ=s0']
# Create a variable to keep track of the current image
current_image = [0,0,0,0,0,0,0,0,0,0]
# Create a grid of labels to display the images
image_grid = [[tk.Label(root) for _ in range(5)] for _ in range(2)]
# Function to change the image
def change_image(x,y):
global current_image
current_image[x*5+y] += 1
if current_image[x*5+y] >= len(images):
current_image[x*5+y] = 0
image = Image.open(BytesIO(requests.get(images[current_image[x*5+y]]).content))
image = image.resize((256,256))
print(image)
photo = ImageTk.PhotoImage(image)
image_grid[x][y].config(image=photo)
image_grid[x][y].image = photo
# Bind labels to the function
for i in range(2):
for j in range(5):
image_grid[i][j].bind("<Button-1>", lambda event, x=i, y=j: change_image(x,y))
image_grid[i][j].grid(row=i, column=j)
# Start the main loop
root.mainloop()
The Images will only display after you click on a label. And your labels are all very small when you initialize your window. Set a bigger window and use sticky in grid to get bigger cells (you can even set a border to the labels to see where exactly you're clicking):
import tkinter as tk
from PIL import Image, ImageTk
from io import BytesIO
import requests
# Create the main window
root = tk.Tk()
root.geometry('1280x720')
# Create a list of images to display
images = ['https://lh3.googleusercontent.com/SsEIJWka3_cYRXXSE8VD3XNOgtOxoZhqW1uB6UFj78eg8gq3G4jAqL4Z_5KwA12aD7Leqp27F653aBkYkRBkEQyeKxfaZPyDx0O8CzWg=s0',
'https://lh3.googleusercontent.com/Bawo7r1nPZV6sJ4OHZJHdKV_4Ky59vquAR7KoUXcNZgx9fqTaOW-QaOM9qoyYhOTAopzjt9OIfW06RMwa-9eJW9KjQw=s0',
'https://lh3.googleusercontent.com/tm1DbZrAP0uBM-OJhLwvKir1Le5LglRF_bvbaNi6m-F_pIyttsWQz040soRY9pWA9PgNEYFA_fBkg_keYixRXCAjz9Q=s0',
'https://lh3.googleusercontent.com/AyiKhdEWJ7XmtPXQbRg_kWqKn6mCV07bsuUB01hJHjVVP-ZQFmzjTWt7JIWiQFZbb9l5tKFhVOspmco4lMwqwWImfgg=s0',
'https://lh3.googleusercontent.com/FNNTrTASiUR0f49UVUY5bisIM-3RlAbf_AmktgnU_4ou1ZG0juh3pMT1-xpQmtN1R8At4Gq9B4ioSSi4TVrgbCZsmtY=s0',
'https://lh3.googleusercontent.com/mAyAjvYjIeAIlByhJx1Huctgeb58y7519XYP38oL1FXarhVlcXW7kxuwayOCFdnwtOp6B6F0HJmmws-Ceo5b_pNSSQs=s0',
'https://lh3.googleusercontent.com/gShVRyvLLbwVB8jeIPghCXgr96wxTHaM4zqfmxIWRsUpMhMn38PwuUU13o1mXQzLMt5HFqX761u8Tgo4L_JG1XLATvw=s0',
'https://lh3.googleusercontent.com/KA2hIo0BlMDmyQDEC3ixvp9WHgcyJnlAvWtVcZmExh9ocPoZdQGRJh7bZjE2Mx2OGC0Zi3QGHGP0LlmuFgRlIYs36Sgn5G2OD-0MaTo=s0',
'https://lh3.googleusercontent.com/N2m90mImdcoLacUybb_rxcktTwtr0LFhtuzxbSE9elIhElF6jpWngx96_uZ0L1TGNof5pNt4n_Ygb4KYlPTpA9o6788=s0',
'https://lh3.googleusercontent.com/1pTfYJlLwVTifKj4PlsWPyAg4PcIVBAiVvB8sameSnmm7HRd056abNUIRq33rgry7u9t-ju-eHOnbfqQpK4q_8IwzIXZ4WgrqZW9l7U=s0',
'https://lh3.googleusercontent.com/0bgOiMrBM2GuhW_pNeQW711GuB3kD7Gq7AILGHaJGeWKa1Fu1hUJGpOjvSpiP_XpgRlC4jVmH0Z1233PEPMJTfNRR7Q=s0',
'https://lh3.googleusercontent.com/x9NFmu-RbZ_9M5BK_hOzQRdVj4pu7p--y_IYwDK46lDPzQtTIO9AlBV_ObgQiY7GeWE0ZfNjMSyrCWgnwL4MCasQZQ=s0']
# Create a variable to keep track of the current image
current_image = [0,0,0,0,0,0,0,0,0,0]
# Create a grid of labels to display the images
image_grid = [[tk.Label(root, borderwidth=2, relief="groove") for _ in range(5)] for _ in range(2)]
# Function to change the image
def change_image(x,y):
global current_image
current_image[x*5+y] += 1
if current_image[x*5+y] >= len(images):
current_image[x*5+y] = 0
image = Image.open(BytesIO(requests.get(images[current_image[x*5+y]]).content))
image = image.resize((256,256))
print(image)
photo = ImageTk.PhotoImage(image)
image_grid[x][y].config(image=photo)
image_grid[x][y].image = photo
# Bind labels to the function
for i in range(2):
root.rowconfigure(i, weight=1)
for j in range(5):
root.columnconfigure(j, weight=1)
image_grid[i][j].bind("<Button-1>", lambda event, x=i, y=j: change_image(x,y))
image_grid[i][j].grid(row=i, column=j, sticky="nsew")
# Start the main loop
root.mainloop()
Note: setting rowconfigure/columnconfigure ensures that the cells have the same dimension, you might want to use it in change_image as well
your issue is that the labels start with a zero width and height because they are empty, you could set a placeholder image on startup to make the GUI fit exactly perfect around it.
import tkinter as tk
from PIL import Image, ImageTk
from io import BytesIO
import requests
# Create the main window
root = tk.Tk()
# Create a list of images to display
images = ['https://lh3.googleusercontent.com/SsEIJWka3_cYRXXSE8VD3XNOgtOxoZhqW1uB6UFj78eg8gq3G4jAqL4Z_5KwA12aD7Leqp27F653aBkYkRBkEQyeKxfaZPyDx0O8CzWg=s0',
'https://lh3.googleusercontent.com/Bawo7r1nPZV6sJ4OHZJHdKV_4Ky59vquAR7KoUXcNZgx9fqTaOW-QaOM9qoyYhOTAopzjt9OIfW06RMwa-9eJW9KjQw=s0',
'https://lh3.googleusercontent.com/tm1DbZrAP0uBM-OJhLwvKir1Le5LglRF_bvbaNi6m-F_pIyttsWQz040soRY9pWA9PgNEYFA_fBkg_keYixRXCAjz9Q=s0',
'https://lh3.googleusercontent.com/AyiKhdEWJ7XmtPXQbRg_kWqKn6mCV07bsuUB01hJHjVVP-ZQFmzjTWt7JIWiQFZbb9l5tKFhVOspmco4lMwqwWImfgg=s0',
'https://lh3.googleusercontent.com/FNNTrTASiUR0f49UVUY5bisIM-3RlAbf_AmktgnU_4ou1ZG0juh3pMT1-xpQmtN1R8At4Gq9B4ioSSi4TVrgbCZsmtY=s0',
'https://lh3.googleusercontent.com/mAyAjvYjIeAIlByhJx1Huctgeb58y7519XYP38oL1FXarhVlcXW7kxuwayOCFdnwtOp6B6F0HJmmws-Ceo5b_pNSSQs=s0',
'https://lh3.googleusercontent.com/gShVRyvLLbwVB8jeIPghCXgr96wxTHaM4zqfmxIWRsUpMhMn38PwuUU13o1mXQzLMt5HFqX761u8Tgo4L_JG1XLATvw=s0',
'https://lh3.googleusercontent.com/KA2hIo0BlMDmyQDEC3ixvp9WHgcyJnlAvWtVcZmExh9ocPoZdQGRJh7bZjE2Mx2OGC0Zi3QGHGP0LlmuFgRlIYs36Sgn5G2OD-0MaTo=s0',
'https://lh3.googleusercontent.com/N2m90mImdcoLacUybb_rxcktTwtr0LFhtuzxbSE9elIhElF6jpWngx96_uZ0L1TGNof5pNt4n_Ygb4KYlPTpA9o6788=s0',
'https://lh3.googleusercontent.com/1pTfYJlLwVTifKj4PlsWPyAg4PcIVBAiVvB8sameSnmm7HRd056abNUIRq33rgry7u9t-ju-eHOnbfqQpK4q_8IwzIXZ4WgrqZW9l7U=s0',
'https://lh3.googleusercontent.com/0bgOiMrBM2GuhW_pNeQW711GuB3kD7Gq7AILGHaJGeWKa1Fu1hUJGpOjvSpiP_XpgRlC4jVmH0Z1233PEPMJTfNRR7Q=s0',
'https://lh3.googleusercontent.com/x9NFmu-RbZ_9M5BK_hOzQRdVj4pu7p--y_IYwDK46lDPzQtTIO9AlBV_ObgQiY7GeWE0ZfNjMSyrCWgnwL4MCasQZQ=s0']
# Create a variable to keep track of the current image
current_image = [0,0,0,0,0,0,0,0,0,0]
# Create a grid of labels to display the images
image = Image.new('RGBA', (256, 256))
photo = ImageTk.PhotoImage(image)
image_grid = [[tk.Label(root, image=photo, borderwidth=2, relief="groove") for _ in range(5)] for _ in range(2)]
# Function to change the image
def change_image(x,y):
global current_image
current_image[x*5+y] += 1
if current_image[x*5+y] >= len(images):
current_image[x*5+y] = 0
image = Image.open(BytesIO(requests.get(images[current_image[x*5+y]]).content))
image = image.resize((256,256))
print(image)
photo = ImageTk.PhotoImage(image)
image_grid[x][y].config(image=photo)
image_grid[x][y].image = photo
# Bind labels to the function
for i in range(2):
root.rowconfigure(i, weight=1)
for j in range(5):
root.columnconfigure(j, weight=1)
image_grid[i][j].bind("<Button-1>", lambda event, x=i, y=j: change_image(x,y))
image_grid[i][j].grid(row=i, column=j)
# Start the main loop
root.mainloop()
As already mentioned, you used Label without a text and they were just not visible. I suggest you use Button instead. Your x and y in change_image update correctly, but images[current_image[x*5+y]] always pointed to the same image. I simplified your code and removed the global variable:
import tkinter as tk
from PIL import Image, ImageTk
import requests
from io import BytesIO
# Create the main window
root = tk.Tk()
# Create a list of images to display
images = ['https://lh3.googleusercontent.com/SsEIJWka3_cYRXXSE8VD3XNOgtOxoZhqW1uB6UFj78eg8gq3G4jAqL4Z_5KwA12aD7Leqp27F653aBkYkRBkEQyeKxfaZPyDx0O8CzWg=s0',
'https://lh3.googleusercontent.com/Bawo7r1nPZV6sJ4OHZJHdKV_4Ky59vquAR7KoUXcNZgx9fqTaOW-QaOM9qoyYhOTAopzjt9OIfW06RMwa-9eJW9KjQw=s0',
'https://lh3.googleusercontent.com/tm1DbZrAP0uBM-OJhLwvKir1Le5LglRF_bvbaNi6m-F_pIyttsWQz040soRY9pWA9PgNEYFA_fBkg_keYixRXCAjz9Q=s0',
'https://lh3.googleusercontent.com/AyiKhdEWJ7XmtPXQbRg_kWqKn6mCV07bsuUB01hJHjVVP-ZQFmzjTWt7JIWiQFZbb9l5tKFhVOspmco4lMwqwWImfgg=s0',
'https://lh3.googleusercontent.com/FNNTrTASiUR0f49UVUY5bisIM-3RlAbf_AmktgnU_4ou1ZG0juh3pMT1-xpQmtN1R8At4Gq9B4ioSSi4TVrgbCZsmtY=s0',
'https://lh3.googleusercontent.com/mAyAjvYjIeAIlByhJx1Huctgeb58y7519XYP38oL1FXarhVlcXW7kxuwayOCFdnwtOp6B6F0HJmmws-Ceo5b_pNSSQs=s0',
'https://lh3.googleusercontent.com/gShVRyvLLbwVB8jeIPghCXgr96wxTHaM4zqfmxIWRsUpMhMn38PwuUU13o1mXQzLMt5HFqX761u8Tgo4L_JG1XLATvw=s0',
'https://lh3.googleusercontent.com/KA2hIo0BlMDmyQDEC3ixvp9WHgcyJnlAvWtVcZmExh9ocPoZdQGRJh7bZjE2Mx2OGC0Zi3QGHGP0LlmuFgRlIYs36Sgn5G2OD-0MaTo=s0',
'https://lh3.googleusercontent.com/N2m90mImdcoLacUybb_rxcktTwtr0LFhtuzxbSE9elIhElF6jpWngx96_uZ0L1TGNof5pNt4n_Ygb4KYlPTpA9o6788=s0',
'https://lh3.googleusercontent.com/1pTfYJlLwVTifKj4PlsWPyAg4PcIVBAiVvB8sameSnmm7HRd056abNUIRq33rgry7u9t-ju-eHOnbfqQpK4q_8IwzIXZ4WgrqZW9l7U=s0',
'https://lh3.googleusercontent.com/0bgOiMrBM2GuhW_pNeQW711GuB3kD7Gq7AILGHaJGeWKa1Fu1hUJGpOjvSpiP_XpgRlC4jVmH0Z1233PEPMJTfNRR7Q=s0',
'https://lh3.googleusercontent.com/x9NFmu-RbZ_9M5BK_hOzQRdVj4pu7p--y_IYwDK46lDPzQtTIO9AlBV_ObgQiY7GeWE0ZfNjMSyrCWgnwL4MCasQZQ=s0']
# Create a grid of labels to display the images
image_grid = [[tk.Button(root, text=f"Button {x} {y}") for x in range(5)] for y in range(2)]
# Function to change the image
def change_image(x,y):
print(f"Changing image to: {x} {y} (index: {x*5+y}): {images[x*5+y]}")
image = Image.open(BytesIO(requests.get(images[x*5+y]).content))
image = image.resize((256, 256))
print(image)
photo = ImageTk.PhotoImage(image)
image_grid[x][y].config(image=photo)
image_grid[x][y].image = photo
# Bind labels to the function
for i in range(2):
for j in range(5):
image_grid[i][j].bind("<Button-1>", lambda event, x=i, y=j: change_image(x,y))
image_grid[i][j].grid(row=i, column=j)
# Start the main loop
root.mainloop()
So, my goal is to create a sort of slideshow within Tkinter. I have a list of images like Images = ["1.png", "2.png", ...], I want to be able to iterate through the list and display each image in a Tkinter window, the concept is simple and as follows:
Display Image 1
30 Second Delay
Display Image 2
30 Second Delay
Display Image 3
I have managed to iterate the images using a button press, however, I do not want to have to click a button as it is meant to imitate a slideshow, I also attempted looping a function but the time.sleep() function does not delay in the correct way because of how Tkinter behaves.
I managed to achieve the above using mostly source code from here, and I would appreciate a little hand achieving the above.
My Code:
from tkinter import *
from PIL import ImageTk, Image
Window = Tk()
Window.geometry("1920x1080")
Window.resizable(0, 0)
Label1 = Label(Window)
Label1.pack()
Images = iter(["1.png", "2.png", "3.png", "4.png", "5.png",
"6.png", "7.png", "8.png", "9.png", "10.png"])
def Next_Image(Val):
try:
Image1 = next(Images)
except StopIteration:
return
Image1 = ImageTk.PhotoImage(Image.open(Image1))
Label1.Image = Image1
Label1["image"] = Image1
Button1 = Button(text = "Next image", command =
lambda:Next_Image(1))
Button1.place(x = 50, y = 50)
Next_Image(1)
Window.mainloop()
I also attempted to use .after(), however, it did not display each image, it skipped from the first image to the last straight away with the compounded delay.
for x in range(1, 11):
Window.after(1000, lambda : Next_Image(1))
You need to create a function that gets the image off of the list and displays it, and then uses after to call itself again in a second. Your main program needs to call this exactly once, and then it will run until it runs out of things to do.
Here's a working example that uses a text string for simplicity, but it should be obvious how to modify it to use images.
import tkinter as tk
images = iter(["1.png", "2.png", "3.png", "4.png", "5.png",
"6.png", "7.png", "8.png", "9.png", "10.png"])
def next_image():
try:
image = next(images)
label.configure(text=image)
root.after(1000, next_image)
except StopIteration:
return
root = tk.Tk()
label = tk.Label(root, width = 40, height=4)
label.pack()
next_image()
root.mainloop()
You can use .after() to switch image periodically:
from itertools import cycle
...
# use cycle() instead of iter()
Images = cycle([f"{i}.png" for i in range(1, 5)])
...
def next_image():
# use next() to get next image in the cycle list
Label1.image = ImageTk.PhotoImage(file=next(Images))
Label1['image'] = Label1.image
# switch image again after 1 second
Label1.after(1000, next_image)
next_image() # start the loop
Window.mainloop()
This worked, Thank you #acw1668 and #Bryan Oakley.
from tkinter import *
from PIL import ImageTk, Image
Window = Tk()
Window.geometry("1920x1080")
Window.resizable(0, 0)
Label1 = Label(Window)
Label1.pack()
Images = iter(["1.png", "2.png", "3.png", "4.png", "5.png", "6.png",
"7.png", "8.png", "9.png", "10.png"])
def Next_Image(Val):
try:
Image1 = next(Images)
except StopIteration:
return
Image1 = ImageTk.PhotoImage(Image.open("BuyingConfig\\" + Image1))
Label1.Image = Image1
Label1["image"] = Image1
Window.after(3000, lambda:Next_Image(1))
Window.after(0, lambda:Next_Image(1))
Window.mainloop()
I'm trying to display an animated gif as background for my GUI but i can't do it, console shows this error:
Also i already tried every solution i found on this website and google, i read PIL and Tkinter documentation too but apparently nothing works for me
File "C:\Users\user\.spyder-py3\temporal.py", line 32, in <listcomp>
frames = [Image(file='079.gif',format = 'gif -index %i' %(i)) for i in range(79)]
TypeError: 'module' object is not callable
This is my code:
import tkinter as tk
import os
from PIL import Image
root= tk.Tk()
root.title("SCP-079")
root.resizable(0,0)
root.iconbitmap("079.ico")
root.geometry("540x360")
frames = [Image(file='079.gif',format = 'gif -index %i' %(i)) for i in range(79)]
def update(ind):
frame = frames[ind]
ind += 1
if ind>78: #With this condition it will play gif infinitely
ind = 0
gif.configure(image=frame)
root.after(100, update, ind)
gif = root.Label
gif.pack()
root.after(0, update, 0)
root.mainloop()
This is the gif i want to use
079.gif
i tried to do it in a different way but now i don't know how to display it
import tkinter as tk
import PIL.Image
root= tk.Tk()
root.title("SCP-079")
root.resizable(0,0)
root.iconbitmap("079.ico")
root.geometry("540x360")
gif=[PIL.Image.open(fp='079.gif', mode='r', formats=None)]
root.mainloop()
I got your code working.
Note that you haven't set everything on it. You must to "Image.open" in your file before.
"Image" is imported as PIM from PIL to prevent conflict.
import os, tkinter as tk
from PIL import Image as PIM, ImageTk
from tkinter import*
root= tk.Tk()
root.title("SCP-079")
root.resizable(0,0)
root.iconbitmap("079.ico")
root.geometry("540x360")
im = PIM.open("C:\\...\\CeEOy.gif")
ph = ImageTk.PhotoImage(im)
gif = Label(root, image = ph, bg="black", bd=3)
gif.image = ph
framnr = 79
frames = [PhotoImage(file="C:\\...\\CeEOy.gif",
format = 'gif -index %i' %(i)) for i in range(framnr)]
def update(ind):
frame = frames[ind]
ind += 1
if ind>78:
ind = 0
gif.configure(image = frame)
root.after(100, update, ind)
gif = Label(root)
gif.pack()
root.after(0, update, 0)
root.mainloop()
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()
I am trying to show video frames (not from a stream) with tkinter. The next step are buttons which allow the user to get a frame backward or forward in the video. I have to say that I am quite new in programming with python.
So first I read the following articles:
Python snippets: Converting video to images http://srand.fr/blog/python%20import%20video.html
The Tkinter PhotoImage Class: http://effbot.org/tkinterbook/photoimage.htm
The problem is that I can’t use the image converted with imageio or VideoFileClip to show it with tkinter photoimage. I get the following error:
_tkinter.TclError: image "[[ …(some numbers)… ]]" doesn't exist
Here is my simple code. I hope you can help me :)
from moviepy.editor import VideoFileClip
from tkinter import *
import pylab
vid =VideoFileClip("example.mp4")
window = Tk()
window.title("Choose Frame")
window.geometry ("900x600")
count =20
photo = vid.get_frame(count)
label =Label(window, image = photo)
label.pack()
Other Code, same problem:
import imageio
from tkinter import *
import pylab
filename = './example.mp4'
vid = imageio.get_reader(filename, 'ffmpeg')
window = Tk()
window.title("Choose Frame")
window.geometry ("900x600")
count =20
photo = vid.get_data(count)
label =Label(window, image = photo)
label.pack()
This is a bit late but better late than never.
Here is a working example I found and modify a little, this works with '.mp4', videos but not with '.flv', don't know why.
Note:
python 2.7 import Tkinter
python 3 import tkinter
import Tkinter as tk
import threading
import imageio
from PIL import Image, ImageTk
video_name = "test_video.mp4" #This is your video file path
video = imageio.get_reader(video_name)
def stream(label):
frame = 0
for image in video.iter_data():
frame += 1 #counter to save new frame number
image_frame = Image.fromarray(image)
image_frame.save('FRAMES/frame_%d.png' % frame) #if you need the frame you can save each frame to hd
frame_image = ImageTk.PhotoImage(image_frame)
label.config(image=frame_image)
label.image = frame_image
if frame == 40: break #after 40 frames stop, or remove this line for the entire video
if __name__ == "__main__":
root = tk.Tk()
my_label = tk.Label(root)
my_label.pack()
thread = threading.Thread(target=stream, args=(my_label,))
thread.daemon = 1
thread.start()
root.mainloop()
And here is another nice working example of a player that I was trying to make with Tkinter and some sample code with Opencv module.
This is a just an example idea, not finish code by any means.
import cv2
from Tkinter import *
from PIL import Image, ImageTk
import io
import threading
import os, sys
def resize(image):
im = image
new_siz = siz
im.thumbnail(new_siz, Image.ANTIALIAS)
return im
def size(event):
global siz
if siz == screenWH:
siz = (200, 200)
else:
siz = screenWH
win.state('zoomed')
print 'size is: ', siz
def view_frame_video():
vc = cv2.VideoCapture('test_video.flv')
if vc.isOpened():
rval , frame = vc.read()
else:
rval = False
while rval:
rval, frame = vc.read()
img =Image.fromarray(frame)
img = resize(img)
imgtk = ImageTk.PhotoImage(img)
lbl.config(image=imgtk)
lbl.img = imgtk
if stop == True:
vc.release()
break #stop the loop thus stops updating the label and reading imagge frames
cv2.waitKey(1)
vc.release()
def stop_():
global stop
stop = True
def play():
stop = False
t = threading.Thread(target=view_frame_video)
t.start()
win = Tk()
stop = None
screenWH = (win.winfo_screenwidth(), win.winfo_screenheight())
siz = (200, 200)
Label(text='Press Play Button').pack()
frm_ = Frame(bg='black')
frm_.pack()
lbl = Label(frm_, bg='black')
lbl.pack(expand=True)
lbl.bind('<Double-Button-1>', size)
frm = Frame()
frm.pack()
Button(text='Play', command = play).pack(side=LEFT)
Button(text='Stop', command = stop_).pack(side=LEFT)
win.mainloop()