why can not see images in a similar code? - python

please help to understand the cause of the phenomenon.
This script does not work (can not see images).
import os, sys
from tkinter import *
from PIL.ImageTk import PhotoImage
DIR_IMGS = 'imgs'
imgfiles = os.listdir(DIR_IMGS)
main = Tk()
for imgfile in imgfiles:
win = Toplevel()
imgpath = os.path.join(DIR_IMGS, imgfile)
objImg = PhotoImage(file=imgpath)
Label(win, image=objImg).pack()
main.mainloop()
and this script works (see images).
import os, sys
from tkinter import *
from PIL.ImageTk import PhotoImage
imgdir = 'images'
imgfiles = os.listdir(imgdir)
main = Tk()
savephotos = [] #?????????????????????
for imgfile in imgfiles:
imgpath = os.path.join(imgdir, imgfile)
win = Toplevel()
win.title(imgfile)
imgobj = PhotoImage(file=imgpath)
Button(win, image=imgobj).pack()
savephotos.append(imgobj) #?????????????????????
main.mainloop()
they differ only in two rows. it is unclear why such great importance "savephotos"

As FabienAndre writes in the second comment. The garbage collector deletes the image object. The image must be retained for the duration of the display.
I tried a simple code modification:
import os, sys
from tkinter import *
from PIL.ImageTk import PhotoImage
DIR_IMGS = 'imgs'
imgfiles = os.listdir(DIR_IMGS)
main = Tk()
objImgList = []
for imgfile in imgfiles:
win = Toplevel()
imgpath = os.path.join(DIR_IMGS, imgfile)
objImg = PhotoImage(file=imgpath)
Label(win, image=objImg).pack()
objImgList.append(objImg)
main.mainloop()
All pictures are now displayed.

Related

How to open another GUI window, once video is completed in GUI in python tkinter?

The purpose of the below code is to automatically open another window of GUI once video is completed (the length of video is 10 seconds)
I have tried to do this but some how its not working pl. have a look at below code.
import tkinter as tk, threading
import imageio
import tkinter as tk
from tkinter import *
from tkinter import ttk
import tkinter.font as font
import os
import re
from PIL import Image, ImageTk
global Image
global image
global Label
video_name = "C:\\Users\\Ray\\Desktop\\Duplicate.mp4"
video = imageio.get_reader(video_name)
def stream(label):
for image in video.iter_data():
frame_image = ImageTk.PhotoImage(Image.fromarray(image))
label.config(image=frame_image)
label.image = frame_image
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()
ima = Image.open('C:\\Users\\Ray\\Desktop\\July_bill.jpg')
ima = ima.resize((1920,1050), Image.ANTIALIAS)
my_img = ImageTk.PhotoImage(ima)
my_lbl = Label(Image = my_img)
my_lbl.pack()
root.mainloop()
In this code if I remove the image inserting code ( which is ima, my_img lines in code) the video plays smoothly but if i use this code then it does not works it shows the error of "unknown option "-Image"
Can anybody help me in getting this solved it would be great.
Regards,
Ray
Just change my_lbl = Label(Image = my_img) to my_lbl = Label(image = my_img)
You can see TK Label options here. As you can see "image" starts with lowercase, in your code, you had "Image" that caused the error.
Full code:
import tkinter as tk, threading
import imageio
from tkinter import *
from PIL import Image, ImageTk
from time import sleep
def stream(label):
video_name = "C:\\Users\\Ray\\Desktop\\Duplicate.mp4"
video = imageio.get_reader(video_name)
for image in video.iter_data():
frame_image = ImageTk.PhotoImage(Image.fromarray(image))
label.config(image=frame_image)
label.image = frame_image
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()
sleep(10)
ima = Image.open('C:\\Users\\Ray\\Desktop\\July_bill.jpg')
ima = ima.resize((1920,1050), Image.ANTIALIAS)
my_img = ImageTk.PhotoImage(ima)
my_lbl = Label(image = my_img)
my_lbl.pack()
root.mainloop()
I have not tested the video, but the image works well.

displaying an Image in python within a function [duplicate]

This question already has answers here:
Why does Tkinter image not show up if created in a function?
(5 answers)
Closed 2 years ago.
I'm trying to display the image from the link the code below works and shows image as intended
from tkinter import *
from PIL import ImageTk,Image
import requests
from io import BytesIO
root = Tk()
root.title('Weather')
root.iconbitmap('icon.ico')
root.geometry("450x300")
image_link = requests.get('https://assets.weatherstack.com/images/wsymbols01_png_64/wsymbol_0006_mist.png')
my_img = ImageTk.PhotoImage(Image.open(BytesIO(image_link.content)))
image_link =Label(root, image = my_img)
image_link.grid(row = 0, column = 0 )
root.mainloop()
but now i have to update my code a little bit and have to put this in a function
from tkinter import *
from PIL import ImageTk,Image
import requests
from io import BytesIO
root = Tk()
root.title('Weather')
root.iconbitmap('icon.ico')
root.geometry("450x300")
def image_func():
image_link = requests.get('https://assets.weatherstack.com/images/wsymbols01_png_64/wsymbol_0006_mist.png')
my_img = ImageTk.PhotoImage(Image.open(BytesIO(image_link.content)))
image_label =Label(root, image = my_img)
image_label.grid(row = 0, column = 0 )
image_func()
root.mainloop()
the above doesn't shows the image so I tried to to put the image label inside a frame but that just shows the frame with nothing inside also the powershell or cmd doesn't show any error
All the objects you create inside the function are local. So these object are deleted when the function exits. You need a way to keep these object existing. For example by using global variables
from tkinter import *
from PIL import ImageTk,Image
import requests
from io import BytesIO
root = Tk()
root.title('Weather')
root.iconbitmap('icon.ico')
root.geometry("450x300")
my_img = None
image_label = None
def image_func():
global my_img, image_label
image_link = requests.get('https://assets.weatherstack.com/images/wsymbols01_png_64/wsymbol_0006_mist.png')
my_img = ImageTk.PhotoImage(Image.open(BytesIO(image_link.content)))
image_label = Label(root, image = my_img)
image_label.grid(row = 0, column = 0 )
image_func()
root.mainloop()
Another way could be returning the objects from the function and keep the returned values
from tkinter import *
from PIL import ImageTk, Image
import requests
from io import BytesIO
root = Tk()
root.title('Weather')
root.iconbitmap('icon.ico')
root.geometry("450x300")
def image_func():
image_link = requests.get('https://assets.weatherstack.com/images/wsymbols01_png_64/wsymbol_0006_mist.png')
my_img = ImageTk.PhotoImage(Image.open(BytesIO(image_link.content)))
image_label = Label(root, image=my_img)
image_label.grid(row=0, column=0)
return my_img, image_label
my_img, image_label = image_func()
root.mainloop()

Making more windows with backgrounds (using the paths) in a for loop

I'm new to python and I'm trying this code:
import random
from random import choice
import tkinter
from tkinter import messagebox
from tkinter import *
from tkinter.filedialog import askopenfilename
import sys
from PIL import ImageTk, Image
from tkinter import filedialog
import os
num_npcs = 2
num_img_tot = 100
npc_window = {}
canvas = {}
background_label = {}
for i in range(0, num_npcs,1):
num_img = round(random.uniform(0.5, num_img_tot+0.5))
npc_window["npc_window{0}".format(i)] = Tk()
canvas["canvas{0}".format(i)] = Canvas(npc_window["npc_window{0}".format(i)], bg="blue", height=250, width=300)
filename["canvas{0}".format(i)] = PhotoImage(file=base_folder + 'biome\\'+str(char)+'\\'+str(int) + '\\'+str(num_img)+'.png')
background_label["background_label{0}".format(i)] = Label(npc_window["npc_window{0}".format(i)], image=filename["canvas{0}".format(i)])
background_label["background_label{0}".format(i)].place(x=0, y=0, relwidth=1, relheight=1)
canvas["canvas{0}".format(i)].pack()
but I probably messed up a little bit... I'm not used to GUI and stuff and I'm actually experimenting.
By the way the error is:
_tkinter.TclError: image "pyimage2" doesn't exist
I'm trying to make a program that opens X (random) images, that's why I tried Tk().
Also I'm using Pycharm in a Windows 10 machine.
The pyimage2 error may be due to an incorrect file path. Suggestion to improve folfer path:
base_folder = "base_folder"
alignment_list = [0.1, 0.2, 0.3]
integer_list = [1,2,3]
images = []
tk = Tk()
for alignment, integer in zip(alignment_list, integer_list):
image_name = "img" + str(integer) + ".png"
file_name = os.path.join(base_folder, "biome", str(alignment), str(integer), image_name)
print(file_name)
img = PhotoImage(file=file_name)
images.append(img)
Which gives
base_folder/biome/0.1/1/img1.png
base_folder/biome/0.2/2/img2.png
base_folder/biome/0.3/3/img3.png

how do you make a randomized photo slide show in python

I am trying to make a randomized slideshow in Python
current working code:
import tkinter as tk
from itertools import cycle
from PIL import ImageTk, Image
with open('list.txt', 'r') as f:
lines = f.read().strip('[]')
images = [i.strip("\" ") for i in lines.split(',')]
photos = cycle(ImageTk.PhotoImage(Image.open(image)) for image in images)
def slideShow():
img = next(photos)
displayCanvas.config(image=img)
root.after(1200, slideShow)
root = tk.Tk()
root.overrideredirect(True)
width = root.winfo_screenwidth()
height = root.winfo_screenwidth()
root.geometry('%dx%d' % (1920, 1280))
displayCanvas = tk.Label(root)
displayCanvas.pack()
root.after(1000, lambda: slideShow())
root.mainloop()
I tried randomizing it by changing img = next(photos) to img = random.choice(photos)
I got the error NameError: name 'random' is not defined
full randomized code:
import tkinter as tk
from itertools import cycle
from PIL import ImageTk, Image
import random
with open('list.txt', 'r') as f:
lines = f.read().strip('[]')
images = [i.strip("\" ") for i in lines.split(',')]
photos = cycle(ImageTk.PhotoImage(Image.open(image)) for image in images)
def slideShow():
img = random.choice(photos)
displayCanvas.config(image=img)
root.after(1200, slideShow)
root = tk.Tk()
root.overrideredirect(True)
width = root.winfo_screenwidth()
height = root.winfo_screenwidth()
root.geometry('%dx%d' % (1920, 1280))
displayCanvas = tk.Label(root)
displayCanvas.pack()
root.after(1000, lambda: slideShow())
root.mainloop()
How should I go about properly converting my slide show to a random one?
I would just use shuffle() from random which is part of the Python standard library.
import random
random.shuffle(images)
Just keep in mind that shuffle works in place and returns None

how to display an inverted image on the screen?

please help display the inverted image on screen("main"-window).
import os, sys
import tkinter
from PIL.ImageTk import PhotoImage, Image
main = tkinter.Tk()
catalog1 = 'imgs'
catalog2 = 'newImgs'
file1 = 'n.jpg'
ima1 = os.path.join(catalog1, file1)
objImg = Image.open(ima1)
rotImg = objImg.rotate(270)
#renderImg = PhotoImage(file=ima1)
#tkinter.Label(main, image=renderImg).pack()
rotImg.save(catalog2 + '/' + 'cv.jpg')
main.mainloop()
I did it only to withdraw in an inverted image file ...
From your example, you could just reuse your label code with this renderImg
renderImg = PhotoImage(image=rotImg)
PhotoImage is an Tkinter compliant image class that you can build from either
image= PIL Image
file= file
data= raw data (usually binary image content in a string)
please try this code (updated ) :
import os, sys
import Tkinter
from PIL import ImageTk, Image
main = Tkinter.Tk()
catalog1 = 'imgs'
catalog2 = 'newImgs'
file1 = 'n.png'
ima1 = os.path.join(catalog1, file1)
img_path = "%s/%s"%(catalog1,file1);
image_ob = ImageTk.PhotoImage(Image.open(img_path).rotate(270))
Tkinter.Label(main,text="",image=image_ob).pack()
main.mainloop()

Categories