displaying an image full screen in Python - python-3.x

The following program works the for the first .jpg in the directory.
When called the second time it gets a "_tkinter.TclError: image
"pyimage2" doesn't exist" exception. Why does it get the error? Is
there a way to reuse the first image rather than creating a second?
import sys, os
if sys.version_info[0] == 2:
import Tkinter
tkinter = Tkinter
else:
import tkinter
from PIL import Image, ImageTk
def showPIL(pilImage):
root = tkinter.Tk()
w, h = root.winfo_screenwidth(), root.winfo_screenheight()
root.overrideredirect(1)
root.geometry("%dx%d+0+0" % (w, h))
root.focus_set()
root.bind("<Escape>", lambda e: (e.widget.withdraw(), e.widget.quit()))
canvas = tkinter.Canvas(root,width=w,height=h)
canvas.pack()
canvas.configure(background='black')
imgWidth, imgHeight = pilImage.size
# resize photo to full screen
ratio = min(w/imgWidth, h/imgHeight)
imgWidth = int(imgWidth*ratio)
imgHeight = int(imgHeight*ratio)
pilImage = pilImage.resize((imgWidth,imgHeight), Image.ANTIALIAS)
image = ImageTk.PhotoImage(pilImage)
print(image)
imagesprite = canvas.create_image(w/2,h/2,image=image)
root.mainloop()
names = os.listdir("E://Users//scott//Pictures")
print(names)
for file in names:
print(file)
if file[-4:] == ".jpg":
file=Image.open("E://Users//scott//Pictures//"+file)
showPIL(file)
Here is the console output. Traceback (most recent call last): File
"e:\Users\scott\Documents\Python\image test.py", line 36, in
showPIL(file) File "e:\Users\scott\Documents\Python\image test.py", line 27, in showPIL
imagesprite = canvas.create_image(w/2,h/2,image=image) File "C:\Program Files\Python37\lib\tkinter__init__.py", line 2486, in
create_image
return self._create('image', args, kw) File "C:\Program Files\Python37\lib\tkinter__init__.py", line 2477, in _create
*(args + self._options(cnf, kw))))
_tkinter.TclError: image "pyimage2" doesn't exist
>

after searching around I discovered that the first problem that tkinter.Tk() was being called multiple times whereas it must be called
only once so I moved it out of the showPIL function and into the
initialization. The next problem is that mainloop blocks so I
replaced it with the combination of root.update_idletasks() and
root.update(). The following works as I expect and need:
import sys, os
if sys.version_info[0] == 2: # the tkinter library changed it's name from Python 2 to 3.
import Tkinter
tkinter = Tkinter #I decided to use a library reference to avoid potential naming conflicts with people's programs.
else:
import tkinter
from PIL import Image, ImageTk
import time
root = tkinter.Tk()
w, h = root.winfo_screenwidth(), root.winfo_screenheight()
root.overrideredirect(1)
root.geometry("%dx%d+0+0" % (w, h))
root.focus_set()
canvas = tkinter.Canvas(root,width=w,height=h)
canvas.pack()
canvas.configure(background='black')
def showPIL(pilImage):
imgWidth, imgHeight = pilImage.size
# resize photo to full screen
ratio = min(w/imgWidth, h/imgHeight)
imgWidth = int(imgWidth*ratio)
imgHeight = int(imgHeight*ratio)
pilImage = pilImage.resize((imgWidth,imgHeight), Image.ANTIALIAS)
image = ImageTk.PhotoImage(pilImage)
imagesprite = canvas.create_image(w/2,h/2,image=image)
root.update_idletasks()
root.update()
# root.bind("<Escape>", lambda e: (e.widget.withdraw(), e.widget.quit()))
names = os.listdir("E://Users//scott//Pictures")
print(names)
for file in names:
print(file)
if file[-4:] == ".jpg":
file=Image.open("E://Users//scott//Pictures//"+file)
showPIL(file)
time.sleep(5)

Related

I want to display images that are send to a specific folder in a sort of slideshow

I have a piece of code right now that when i start it up it creates a black canvas and displays a image on it (With Tkinter) that i randomly grab from a folder i have selected with photos in it.
But right now i have to press esc to go to the next image. I would like it to be on a timer.
It also won't go to the next image. It says pyimage2 does not exist.
It would be great if someone can help me. I am incredibly new to python and don't know that much.
from PIL import Image
import os, random
import time
import sys
if sys.version_info[0] == 2:
import Tkinter
tkinter = Tkinter
else:
import tkinter
from PIL import Image, ImageTk
i = True
def showPIL(pilImage):
root = tkinter.Tk()
w, h = root.winfo_screenwidth(), root.winfo_screenheight()
root.overrideredirect(1)
root.geometry("%dx%d+0+0" % (w, h))
root.focus_set()
root.bind("<Escape>", lambda e: (e.widget.withdraw(), e.widget.quit()))
canvas = tkinter.Canvas(root,width=w,height=h)
canvas.pack()
canvas.configure(background='black')
imgWidth, imgHeight = pilImage.size
if imgWidth > w or imgHeight > h:
ratio = min(w/imgWidth, h/imgHeight)
imgWidth = int(imgWidth*ratio)
imgHeight = int(imgHeight*ratio)
pilImage = pilImage.resize((imgWidth,imgHeight), Image.ANTIALIAS)
image = ImageTk.PhotoImage(pilImage)
imagesprite = canvas.create_image(w/2,h/2,image=image)
root.mainloop()
while i == True:
timer = 0
while timer < 5:
path = "C:/Users/thymen.hummel/PycharmProjects/HelloWorld/Images"
random_filename = random.choice([x
for x in os.listdir(path)
if os.path.isfile(os.path.join(path, x))
])
pilImage = Image.open(f'C:/Users/thymen.hummel/PycharmProjects/HelloWorld/Images/{random_filename}')
showPIL(pilImage)
print(random_filename)
timer += 1
time.sleep(5)
check https://www.geeksforgeeks.org/python-convert-speech-to-text-and-text-to-speech/. Instead of typing, you can name the name of the image and the program will open it.
To do it by timer, you can do it using pygame.time.wait(). It takes input in milliseconds. see https://www.pygame.org/docs/ref/time.html for more information.

Tkinter throws exception, but the code still works, why?

I am working on a comic book reader and my code so far seems to be working great, except for a small result that happens when I update my canvas to display a jpg of the page of the comic book.
The Code:
from tkinter import *
from tkinter import filedialog, Tcl
from PIL import ImageTk, Image
from pyunpack import Archive
import shutil
import tempfile
import os
def open_comic():
os.mkdir('tmp/')
text_file = filedialog.askopenfilename(title="Open Comic Book File", filetypes=(("CBR Files", "*.cbr"), ("CBZ Files", "*.cbz"), ))
tempdir = tempfile.mkdtemp(suffix='.tmp', dir='tmp/')
print('Created temp directory', tempdir)
Archive(text_file).extractall(tempdir)
file_list = os.listdir(tempdir)
file_list.sort()
img = ImageTk.PhotoImage(Image.open(tempdir + "/" + file_list[1]))
my_image = comic_canvas.create_image(0, 0, anchor=NW, image=img)
canvas.update()
# Create the Main Window of the Application
mainWindow = Tk()
mainWindow.title("Comic Reader")
mainWindow.geometry("1200x1500")
buttonFrame = LabelFrame(mainWindow)
canvasFrame = LabelFrame(mainWindow, bg="light gray", border=2)
statusFrame = LabelFrame(mainWindow, bg="black", border=2)
comic_canvas = Canvas(canvasFrame, width="1100", height="1400", bg="light gray")
# Create the Menu Bar for the Application
main_menu = Menu(mainWindow)
mainWindow.config(menu=main_menu)
# The File Menu
file_menu = Menu(main_menu, tearoff=False)
main_menu.add_cascade(menu=file_menu, label="File")
file_menu.add_command(label="Open", command=open_comic)
file_menu.add_separator()
file_menu.add_command(label="Quit", command=quit_it)
# The Edit Menu
edit_menu = Menu(main_menu, tearoff=False)
main_menu.add_cascade(menu=edit_menu, label="Edit")
edit_menu.add_command(label="Cut", accelerator="(CTRL+X)")
edit_menu.add_command(label="Copy", accelerator="(CTRL+C)")
edit_menu.add_command(label="Paste", accelerator="(CTRL+V)")
button_back = Button(buttonFrame, text="<=", command=back)
button_exit = Button(buttonFrame, text="Exit", command=quit_it)
button_next = Button(buttonFrame, text="=>", command=lambda: forward(2))
buttonFrame.pack()
canvasFrame.pack()
statusFrame.pack()
button_back.grid(row=1, column=0)
button_exit.grid(row=1, column=1)
button_next.grid(row=1, column=2)
comic_canvas.grid(row=2, column=1)
# Start the Application Here
mainWindow.mainloop() # Creates the GUI for the Application
Now as it is above, it works to update the canvas, and lets you see the image, but throws the error:
> Exception in Tkinter callback Traceback (most recent call last):
> File
> "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/tkinter/__init__.py",
> line 1884, in __call__
> return self.func(*args) File "/Users/kb2mob/Python Projects/Comic Reader/comicreader.py", line 28, in open_comic
> canvas.update() NameError: name 'canvas' is not defined
Which, yeah it should because the canvas is named "comic_canvas". But then I do use the correct name for the .update() method, it flashes quickly and then vanishes, and of course doesn't throw an error because it's the correct use.
Does anyone know why that is?
This is in Python 3.9.1 on a latest Mac OS.
Found the issue:
Wasn't keeping the image reference at the end of my function open_comic()
comic_canvas.img = img
dropped that on the end of it and it worked.

Advice on Python tkinter PIL slideshow script

I am trying to run a script that seems to work for others, but not me: https://gist.github.com/terencewu/034e09f0e318c621516b
I have all the packages installed on my mac, using python3 pip, os is 10.15.7.
The only change I've made to the script is to put in a path to a folder with some pictures in it.
When I run the script, I don't get any errors, and the Python terminal prints the full correct paths, but no slideshow. I'm using IDLE 3.9.1.
I would be very grateful for any suggestions as to how to get the script working.
Here's the code (curr_dir contains 3 jpg files):
import tkinter as tk
from PIL import Image, ImageTk
import time
import sys
import os
class HiddenRoot(tk.Tk):
def __init__(self):
tk.Tk.__init__(self)
#hackish way, essentially makes root window
#as small as possible but still "focused"
#enabling us to use the binding on <esc>
self.wm_geometry("0x0+0+0")
self.window = MySlideShow(self)
self.window.startSlideShow()
class MySlideShow(tk.Toplevel):
def __init__(self, *args, **kwargs):
tk.Toplevel.__init__(self, *args, **kwargs)
#remove window decorations
self.overrideredirect(True)
#save reference to photo so that garbage collection
#does not clear image variable in show_image()
self.persistent_image = None
self.imageList = []
self.pixNum = 0
#used to display as background image
self.label = tk.Label(self)
self.label.pack(side="top", fill="both", expand=True)
self.getImages()
def getImages(self):
curr_dir = "/Users/kenpeel/Pictures/testpics/FolderA/FolderA1"
for root, dirs, files in os.walk(curr_dir):
for f in files:
if f.endswith(".png") or f.endswith(".jpg"):
img_path = os.path.join(root, f)
print(img_path)
self.imageList.append(img_path)
def startSlideShow(self, delay=4): #delay in seconds
myimage = self.imageList[self.pixNum]
self.pixNum = (self.pixNum + 1) % len(self.imageList)
self.showImage(myimage)
#its like a callback function after n seconds (cycle through pics)
self.after(delay*1000, self.startSlideShow)
def showImage(self, filename):
image = Image.open(filename)
img_w, img_h = image.size
scr_w, scr_h = self.winfo_screenwidth(), self.winfo_screenheight()
width, height = min(scr_w, img_w), min(scr_h, img_h)
image.thumbnail((width, height), Image.ANTIALIAS)
#set window size after scaling the original image up/down to fit screen
#removes the border on the image
scaled_w, scaled_h = image.size
self.wm_geometry("{}x{}+{}+{}".format(scaled_w,scaled_h,0,0))
# create new image
self.persistent_image = ImageTk.PhotoImage(image)
self.label.configure(image=self.persistent_image)
slideShow = HiddenRoot()
slideShow.bind("<Escape>", lambda e: slideShow.destroy()) # exit on esc
slideShow.mainloop()
The IDLE shell prints the paths, but there are no other errors:
/Users/kenpeel/Pictures/testpics/FolderA/FolderA1/PICT0001.jpg
/Users/kenpeel/Pictures/testpics/FolderA/FolderA1/PICT0002.jpg
/Users/kenpeel/Pictures/testpics/FolderA/FolderA1/PICT0003.jpg
>>>
It seems it could be Mac OS compatability with Pillow and tkinter?

self.tk.call - in photo image python

I'm trying to import an image and recognize by text in Python using below commands but it shows error.
My code:
from Tkinter import *
import pygame
import pyttsx3
pygame.init()
engine = pyttsx3.init()
root = Tk()
root.title('Application')
root.geometry('1352x652+100+100')
root.config(background='white')
str1 = StringVar()
str1.set('Application name')
frame1 = Frame(root,bg='white')
frame1.grid()
Disp = Canvas(frame1, width=160,height=120,bg='white')
Disp.grid(row=1,column=3)
img =PhotoImage(file='Icone.png')
image = Disp.create_image(85,62,image = img)
error stack trace:
img =PhotoImage(file='Icone.png')
Image.__init__(self, 'photo', name, cnf, master, **kw)
self.tk.call(('image', 'create', imgtype, name,) + options)
_tkinter.TclError: couldn't recognize data in image file "Icone.png"

get the zdata with event from a orthoviewer of medical image

I want get the zdata, from navigation toolbar, when I load a .nii file. I want do that with the event def _onclick(event):
import matplotlib
matplotlib.use('TkAgg')
from tkinter import filedialog
from tkinter import *
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg
from nibabel.loadsave import read_img_data
from nibabel.loadsave import load as load_nii
from viewers import OrthoSlicer3D
from matplotlib.figure import Figure
import numpy as np
import sys
if sys.version_info[0] < 3:
import Tkinter as Tk
else:
import tkinter as Tk
root = Tk.Tk()
root.wm_title("Orthoslicer3D for brain segmentation")
f = Figure()
sagital = f.add_subplot(221)
sagital.set_position([0,0,0.5,0.5])
sagital.set_axis_off()
coronal = f.add_subplot(222)
coronal.set_axis_off()
coronal.set_position([0,0.5,0.5,0.5])
axial = f.add_subplot(223)
axial.set_position([0.5,0.5,0.5,0.5])
axial.set_axis_off()
axes = (sagital, coronal, axial)
# a tk.DrawingArea
canvas = FigureCanvasTkAgg(f, master=root)
canvas.get_tk_widget().pack(side=Tk.RIGHT, fill=Tk.BOTH, expand=1)
toolbar = NavigationToolbar2TkAgg(canvas, root)
toolbar.update()
canvas._tkcanvas.pack(side=Tk.RIGHT, fill=Tk.BOTH, expand=0)
def _load():
data = filedialog.askopenfilename(initialdir = "/", title = "Select file", filetypes = (("nii files","*.nii"),("gz files", "*.gz"),("all files","*.*")))
data_load = load_nii(data)
data_read = read_img_data(data_load)
data_read = np.asanyarray(data_read)
OrthoSlicer3D(data_read, axes=axes).show()
coords = []
def _onclick(event):
coords.append((event.xdata, event.ydata, event.zdata))
return coords
canvas.mpl_connect('button_press_event', _onclick)
buttonLoad = Tk.Button(master=root, text='Load', command=_load)
buttonLoad.pack(side=Tk.LEFT, expand = 1)
Tk.mainloop()
But the traceback is:
Traceback (most recent call last):
File "C:\Users\migue\Documents\IM\TFG\venv\lib\site-packages\matplotlib\cbook\__init__.py", line 388, in process
proxy(*args, **kwargs)
File "C:\Users\migue\Documents\IM\TFG\venv\lib\site-packages\matplotlib\cbook\__init__.py", line 228, in __call__
return mtd(*args, **kwargs)
File "C:/Users/migue/Documents/IM/TFG/pruebsd.py", line 58, in _onclick
coords.append((event.xdata, event.ydata, event.zdata))
AttributeError: 'MouseEvent' object has no attribute 'zdata'

Resources