I'm trying to add a capture image on a previewed webcam on second window, for more functional GUI it seems I cant put the capture function, I had no idea Whats going.
here is my code:
from asyncio import wait_for
from enum import auto
from pathlib import PosixPath
from time import sleep
from tkinter import *
import tkinter as tk
from tkinter.filedialog import askopenfilename
from tkinter import messagebox
import os
import cv2
from PIL import Image, ImageTk
import datetime
#GLOBALS
font_size = 14
###instantiate videocapture
##cap = cv2.VideoCapture(0)
### Check if the webcam is opened correctly
##if not cap.isOpened():
## raise IOError("Cannot open webcam")
def browsefunc(ent):
filename = askopenfilename(filetypes=([
("image", ".jpeg"),
("image", ".png"),
("image", ".jpg"),
]))
ent.delete(0, tk.END)
ent.insert(tk.END, filename) # add this
label_result1.config(text = "")
def show_frames():
# Get the latest frame and convert into Image
direct_img = cap.read()[1]
cv2image= cv2.cvtColor(direct_img,cv2.COLOR_BGR2RGB)
img = Image.fromarray(cv2image)
# Convert image to PhotoImage
imgtk = ImageTk.PhotoImage(image = img)
label_cam.imgtk = imgtk
label_cam.configure(image=imgtk,height=300)
# Repeat after an interval to capture continiously
label_cam.after(20, show_frames)
return
#function to capture image on camera
#ADD THE FULL PATH if you want a separate location
#for example C:\Images\
def captureImage():
image1_path_entry.delete(0, tk.END)
image_to_write = cap.read()[1]
x=datetime.datetime.now()
## filetowrite = "c"+x.strftime("%m%d%Y%H%M%S")+".jpeg"
filetowrite = "c.jpeg"
print(str(filetowrite))
cv2.imwrite(str(filetowrite),image_to_write)
image1_path_entry.insert(0,filetowrite)
return
root = tk.Tk()
root.title("Signature verification")
def preview(path1):
# Toplevel object which will
# be treated as a new window
newWindow = Toplevel(root)
# sets the title of the
# Toplevel widget
newWindow.title("Preview")
# sets the geometry of toplevel
newWindow.geometry("500x500")
def closeit():
newWindow.destroy()
return 0
image = Image.open(path1)
width = 180
height = 170
resize_image = image.resize((width, height))
img = ImageTk.PhotoImage(resize_image)
panel = Label(newWindow, image = img)
panel.image =img
panel.pack()
# A Label widget to show in toplevel
button1 = Button(newWindow, text="Close", command = closeit)
button1.pack()
def camera(path1):
# Toplevel object which will
# be treated as a new window
newWindow = Toplevel(root)
# sets the title of the
# Toplevel widget
newWindow.title("Camera")
# sets the geometry of toplevel
newWindow.geometry("500x500")
def closeit():
newWindow.destroy()
return 0
show_frames()
takePicture_button = tk.Button(
frame_buttons, text="Capture Signature", font=font_size,command=lambda: captureImage())
takePicture_button.pack(fill=X,ipadx=5,ipady=5,pady=2)
button1 = Button(newWindow, text="Close", command = capture)
button1.pack()
# specify resolution or size of window
#Waveshare 5" inch LCD (G) is 800 x 480, just check to be sure
#https://www.waveshare.com/wiki/5inch_HDMI_LCD_(G)
window_width = 400
window_height = 500
# get the screen dimension
screen_width = root.winfo_screenwidth()
screen_height = root.winfo_screenheight()
# find the center point
center_x = int(screen_width/2 - window_width / 2)
center_y = int(screen_height/2 - window_height / 2)
# set the position of the window to the center of the screen
root.geometry(f'{window_width}x{window_height}+{center_x}+{center_y}')
# prevent window resizing
root.resizable(False,False)
# this is the placeholder for the camera
frame_cam = cv2.VideoCapture(0, cv2.CAP_DSHOW)
frame_cam = tk.Frame(root, height=300, bg="blue")
frame_cam.pack(fill=X)
label_cam = tk.Label(frame_cam,bg="violet")
label_cam.pack()
# frame to hold the signature label and text entry
frame_dirpath = tk.Frame(root)
frame_dirpath.pack(fill=X,ipadx=5,ipady=5)
image1_path_entry = tk.Entry(frame_dirpath, font=font_size,width=25)
image1_path_entry.pack(side=RIGHT,expand=True, ipadx=5,ipady=5)
# frame to hold the buttons and results
frame_buttons = tk.Frame(root)
frame_buttons.pack(fill=BOTH,ipadx=5,ipady=5)
img1_browse_button = tk.Button(
frame_buttons, text="Browse", font=font_size, command=lambda: browsefunc(ent=image1_path_entry))
img1_browse_button.pack(fill=X,ipadx=5,ipady=5,pady=5)
preview_button = tk.Button(
frame_buttons, text="Preview",fg = "green", border = "4",font="Aria 14 bold", command=lambda: preview(
path1=image1_path_entry.get()))
preview_button.pack(fill=X,ipadx=5,ipady=5,pady=5)
camera_btn = tk.Button(
frame_buttons, text="CAMERA",fg = "green", border = "4",font="Aria 14 bold", command=lambda: preview(
path1=image1_path_entry.get()))
camera_btn.pack(fill=X,ipadx=5,ipady=5,pady=5)
root.mainloop()
I get no response on the second window for the camera view, i tried calling the outside function to the new window theres no error but no response
Related
from tkinter import *
import tkinter as tk
from PIL import ImageTk, Image
from tkinter import ttk
import kalkulasi
#making the window
root = Tk()
root.title('Estimasi Perjalanan Kereta Rute Tangerang-Depok')
root.minsize(400,400)
root.geometry('650x700')
#define image
image = Image.open('petafix.png')
#define image as bg
bg = ImageTk.PhotoImage(image)
# create canvas
main_canvas = Canvas(root, width=650, height=700)
main_canvas.pack(fill='both', expand=True)
# set img in canvas
main_canvas.create_image(325, 300, image=bg)
# add "Selamat Datang!" text
main_canvas.create_text(325, 25, text="Selamat Datang!", font=('Helvetica', 25))
# making resize "HITUNG" button image
hitung_button = Image.open('button.jpg')
hitung_button_resized = hitung_button.resize((75, 30), Image.ANTIALIAS)
new_hitung_button = ImageTk.PhotoImage(hitung_button_resized)
label_hitung_button = Label(root, image= new_hitung_button, border= 0, anchor='center')
label_hitung_button.pack()
# reposition the "hitung" button
button = Button(root, image= new_hitung_button, border= 0, highlightthickness= 0,)
button_window = main_canvas.create_window(300, 670, anchor='nw', window=button)
# making resizer function
def resizer(event):
global bg1, resized_bg, new_bg
# open the image
bg1 = Image.open('petafix.png)
# Resize the image
resized_bg = bg1.resize((event.width, event.height), Image.ANTIALIAS)
# define image again as new bg
new_bg = ImageTk.PhotoImage(resized_bg)
# add new bg back to the canvas
main_canvas.create_image(325, 300, image=new_bg)
root.bind('<Configure>', resizer)
root.mainloop()
I'm trying to make my GUI window's dynamic, but there is an error i can't figured out that when i run the program, the program want to run but it still not dynamic and in the terminal, there is an error says AttributeError: 'PhotoImage' object has no attribute 'read'.
I am beginner in tkinter. I have added a resizable background which is perfectly working. Have look to the code
'''
import tkinter as tk
from PIL import ImageTk, Image
homeWin = tk.Tk()
homeWin.geometry("400x400")
background = ImageTk.PhotoImage(file = "bg.png")
hw_canvas = tk.Canvas(homeWin, width = 400, height=400)
hw_canvas.pack(fill="both", expand=True)
bg = hw_canvas.create_image(0, 0, image = background, anchor = "nw")
def bg_resizable(e):
global image, resized, image2
# open image to resize it
image = Image.open("bg.png")
# resize the image with width and height of root
resized = image.resize((e.width, e.height), Image.LANCZOS)
image2 = ImageTk.PhotoImage(resized)
hw_canvas.create_image(0, 0, image=image2, anchor='nw')
homeWin.bind("<Configure>", bg_resizable)
homeWin.mainloop()
'''
but after placing a frame on the canvas it is not working.
I don't know why this is. Pleas help me with it!
'''
import tkinter as tk
from PIL import ImageTk, Image
homeWin = tk.Tk()
homeWin.geometry("400x400")
background = ImageTk.PhotoImage(file = "bg.png")
hw_canvas = tk.Canvas(homeWin, width = 400, height=400)
hw_canvas.pack(fill="both", expand=True)
bg = hw_canvas.create_image(0, 0, image = background, anchor = "nw")
def bg_resizable(e):
global image, resized, image2
# open image to resize it
image = Image.open("bg.png")
# resize the image with width and height of root
resized = image.resize((e.width, e.height), Image.LANCZOS)
image2 = ImageTk.PhotoImage(resized)
hw_canvas.create_image(0, 0, image=image2, anchor='nw')
homeWin.bind("<Configure>", bg_resizable)
sl_frame = tk.Frame(hw_canvas, bg="white", width= 200, height=500)
sl_frame.place(relx= 0.5, rely= 0.5, anchor="center")
homeWin.mainloop()
'''
"<Configure>" events get called for main window and all children!
Using the following can exclude child "<Configure>" events:
import tkinter as tk
from PIL import ImageTk, Image
def bg_resizable(e):
global image, resized, image2
# main window has no master
if e.widget.master:
return
# resize the image with width and height of root
resized = image.resize((e.width, e.height), Image.LANCZOS)
image2 = ImageTk.PhotoImage(resized)
hw_canvas.itemconfigure(bg, image=image2)
image = Image.open("bg.png") # open image once, global
homeWin = tk.Tk()
homeWin.geometry("400x400")
hw_canvas = tk.Canvas(homeWin, width = 400, height=400)
hw_canvas.pack(fill="both", expand=True)
bg = hw_canvas.create_image(0, 0, anchor='nw')
sl_frame = tk.Frame(hw_canvas, bg="white", width= 200, height=500)
sl_frame.place(relx= 0.5, rely= 0.5, anchor="center")
homeWin.bind("<Configure>", bg_resizable)
homeWin.mainloop()
Also, note because event fires when window is first shown, there is not need to handle background outside of event.
I have two files:
mainfile.py : have button when I click on it should call the another file(showfile.py) which have function that contain canvas image , but nothing loaded ..
mainfile.py
from tkinter import *
import tkinter as tk
from showfile import sho
class Window(tk.Frame):
def __init__(self, master=None):
tk.Frame.__init__(self, master, bg='#333333')
menu = tk.Menu(self.master)
master.config(menu=menu)
root.minsize(width=1080, height=750)
width, height = root.winfo_screenwidth(), root.winfo_screenheight()
root.geometry('%dx%d+0+0' % (width, height))
root.iconbitmap("p.ico")
full = Button(root, text="Full Screen", command=sho, padx=10, pady=10, borderwidth=6)
full.pack(pady=20)
full.place(x=100, y=500)
root = Tk()
root.geometry("%dx%d" % (300, 300))
root.title("BMP Image GUI")
app = Window(root)
app.pack(fill=tk.BOTH, expand=1)
root.mainloop()
showfile.py
from tkinter import *
from PIL import ImageTk, Image
import tkinter as tko
def sh():
lan = tko.Tk() # Creating instance of Tk class
lan.title("Centering windows")
lan.resizable(False, False) # This code helps to disable windows from resizing
window_height = 300
window_width = 500
screen_width = lan.winfo_screenwidth()
screen_height = lan.winfo_screenheight()
x_cordinate = int((screen_width / 2) - (window_width / 2))
y_cordinate = int((screen_height / 2) - (window_height / 2))
lan.geometry("{}x{}+{}+{}".format(window_width, window_height, x_cordinate, y_cordinate))
filename = "iy.jpg"
load = Image.open(filename)
w, h = load.size
image = filename
render2 = ImageTk.PhotoImage(load) # must keep a reference to this
lastwidth, lasthight = w,h
image = load.resize((int(lastwidth), int(lasthight)), Image.ANTIALIAS)
canvas2 = tko.Canvas(lan,width=lastwidth, height=lasthight)
canvas2.pack(fill=tko.BOTH, expand=True)
canvas2.pack()
canvas2.place(relx=0.5, rely=0.5, anchor=CENTER)
render2 = ImageTk.PhotoImage(image)
canvas2.create_image(lastwidth / 2, lasthight / 2, image=render2, anchor=CENTER)
render2 = ImageTk.PhotoImage(load)
but when I run this files ,,, it popup without loaded image ,, and give error : _tkinter.TclError: image "pyimage1" doesn't exist
I want to display the video in canvas instead opening in a new window.
And I want to know how to stop and pause the video.
import pygame
from Tkinter import *
def movie():
from moviepy.editor import *
pygame.display.set_caption('Hello World!')
clip = VideoFileClip('1.mp4')
clip.preview()
pygame.quit()
root = Tk()
root.title("AVATAR")
label = Label(root, fg="dark green")
label.pack()
frame = Frame(root,background='red')
frame.pack()
canvas = Canvas(height=200,width=200)
canvas.pack()
conversationbutton = Button(frame, text='play in canvas',width=25,fg="green", command=movie)
conversationbutton.pack(side = RIGHT)
stopb=Button(root, text="stop").pack()
Thanks
I'm writing a program that needs to display a video stream in a Tkinter window. Since there will also be buttons for performing various functions, I'm using grid to organize where everything goes.
The following code, modified from Show webcam sequence TkInter, works fine on my Raspberry Pi:
import Tkinter as tk
import cv2
from PIL import Image, ImageTk
width, height = 800, 600
cap = cv2.VideoCapture(0)
root = tk.Tk()
lmain = tk.Label(root)
lmain.pack()
def show_frame():
_, frame = cap.read()
frame = cv2.flip(frame, 1)
cv2image = cv2.cvtColor(frame, cv2.COLOR_BGR2RGBA)
img = Image.fromarray(cv2image)
imgtk = ImageTk.PhotoImage(image=img)
lmain.imgtk = imgtk
lmain.configure(image=imgtk)
lmain.after(10, show_frame)
show_frame()
root.mainloop()
However, combining it with Tkinter doesn't work. (In what follows, I've tried commenting out Display 1, Display 2, and neither.)
import numpy as np
import cv2
import Tkinter as tk
import Image, ImageTk
#Set up GUI
window = tk.Tk() #Makes main window
window.wm_title("Digital Microscope")
window.config(background="#FFFFFF")
#Graphics window
imageFrame = tk.Frame(window, width=600, height=500)
imageFrame.grid(row=0, column=0, padx=10, pady=2)
#Capture video frames
lmain = tk.Label(imageFrame)
cap = cv2.VideoCapture(0)
def show_frame():
_, frame = cap.read()
frame = cv2.flip(frame, 1)
cv2image = cv2.cvtColor(frame, cv2.COLOR_BGR2RGBA)
img = Image.fromarray(cv2image)
imgtk = ImageTk.PhotoImage(image=img)
lmain.imgtk = imgtk
lmain.configure(image=imgtk)
lmain.after(10, show_frame)
tk.Label(imageFrame, image=show_frame()).grid(row=0, column=0, padx=10, pady=2) #Display 1
#Slider window (slider controls stage position)
sliderFrame = tk.Frame(window, width=600, height=100)
sliderFrame.grid(row = 600, column=0, padx=10, pady=2)
show_frame() #Display 2
window.mainloop() #Starts GUI
How can I get the video to display in imageFrame?
This should work:
import numpy as np
import cv2
import Tkinter as tk
import Image, ImageTk
#Set up GUI
window = tk.Tk() #Makes main window
window.wm_title("Digital Microscope")
window.config(background="#FFFFFF")
#Graphics window
imageFrame = tk.Frame(window, width=600, height=500)
imageFrame.grid(row=0, column=0, padx=10, pady=2)
#Capture video frames
lmain = tk.Label(imageFrame)
lmain.grid(row=0, column=0)
cap = cv2.VideoCapture(0)
def show_frame():
_, frame = cap.read()
frame = cv2.flip(frame, 1)
cv2image = cv2.cvtColor(frame, cv2.COLOR_BGR2RGBA)
img = Image.fromarray(cv2image)
imgtk = ImageTk.PhotoImage(image=img)
lmain.imgtk = imgtk
lmain.configure(image=imgtk)
lmain.after(10, show_frame)
#Slider window (slider controls stage position)
sliderFrame = tk.Frame(window, width=600, height=100)
sliderFrame.grid(row = 600, column=0, padx=10, pady=2)
show_frame() #Display 2
window.mainloop() #Starts GUI
First of all, you have the line tk.Label(imageFrame, image=show_frame()).grid(row=0, column=0, padx=10, pady=2), and since show_frame() doesn't return anything, you've set image to None. Second of all, you need to make sure you lmain.grid(), otherwise lmain won't show.
If you want to have two displays one on top of the other, you could do something like this:
import numpy as np
import cv2
import Tkinter as tk
import Image, ImageTk
#Set up GUI
window = tk.Tk() #Makes main window
window.wm_title("Digital Microscope")
window.config(background="#FFFFFF")
#Graphics window
imageFrame = tk.Frame(window, width=600, height=500)
imageFrame.grid(row=0, column=0, padx=10, pady=2)
#Capture video frames
cap = cv2.VideoCapture(0)
def show_frame():
_, frame = cap.read()
frame = cv2.flip(frame, 1)
cv2image = cv2.cvtColor(frame, cv2.COLOR_BGR2RGBA)
img = Image.fromarray(cv2image)
imgtk = ImageTk.PhotoImage(image=img)
display1.imgtk = imgtk #Shows frame for display 1
display1.configure(image=imgtk)
display2.imgtk = imgtk #Shows frame for display 2
display2.configure(image=imgtk)
window.after(10, show_frame)
display1 = tk.Label(imageFrame)
display1.grid(row=1, column=0, padx=10, pady=2) #Display 1
display2 = tk.Label(imageFrame)
display2.grid(row=0, column=0) #Display 2
#Slider window (slider controls stage position)
sliderFrame = tk.Frame(window, width=600, height=100)
sliderFrame.grid(row = 600, column=0, padx=10, pady=2)
show_frame() #Display
window.mainloop() #Starts GUI
Try this code:
from PIL import Image, ImageTk
import Tkinter as tk
import argparse
import datetime
import cv2
import os
class Application:
def __init__(self, output_path = "./"):
""" Initialize application which uses OpenCV + Tkinter. It displays
a video stream in a Tkinter window and stores current snapshot on disk """
self.vs = cv2.VideoCapture(0) # capture video frames, 0 is your default video camera
self.output_path = output_path # store output path
self.current_image = None # current image from the camera
self.root = tk.Tk() # initialize root window
self.root.title("PyImageSearch PhotoBooth") # set window title
# self.destructor function gets fired when the window is closed
self.root.protocol('WM_DELETE_WINDOW', self.destructor)
self.panel = tk.Label(self.root) # initialize image panel
self.panel.pack(padx=10, pady=10)
# create a button, that when pressed, will take the current frame and save it to file
btn = tk.Button(self.root, text="Snapshot!", command=self.take_snapshot)
btn.pack(fill="both", expand=True, padx=10, pady=10)
# start a self.video_loop that constantly pools the video sensor
# for the most recently read frame
self.video_loop()
def video_loop(self):
""" Get frame from the video stream and show it in Tkinter """
ok, frame = self.vs.read() # read frame from video stream
if ok: # frame captured without any errors
cv2image = cv2.cvtColor(frame, cv2.COLOR_BGR2RGBA) # convert colors from BGR to RGBA
self.current_image = Image.fromarray(cv2image) # convert image for PIL
imgtk = ImageTk.PhotoImage(image=self.current_image) # convert image for tkinter
self.panel.imgtk = imgtk # anchor imgtk so it does not be deleted by garbage-collector
self.panel.config(image=imgtk) # show the image
self.root.after(30, self.video_loop) # call the same function after 30 milliseconds
def take_snapshot(self):
""" Take snapshot and save it to the file """
ts = datetime.datetime.now() # grab the current timestamp
filename = "{}.jpg".format(ts.strftime("%Y-%m-%d_%H-%M-%S")) # construct filename
p = os.path.join(self.output_path, filename) # construct output path
self.current_image.save(p, "JPEG") # save image as jpeg file
print("[INFO] saved {}".format(filename))
def destructor(self):
""" Destroy the root object and release all resources """
print("[INFO] closing...")
self.root.destroy()
self.vs.release() # release web camera
cv2.destroyAllWindows() # it is not mandatory in this application
# construct the argument parse and parse the arguments
ap = argparse.ArgumentParser()
ap.add_argument("-o", "--output", default="./",
help="path to output directory to store snapshots (default: current folder")
args = vars(ap.parse_args())
# start the app
print("[INFO] starting...")
pba = Application(args["output"])
pba.root.mainloop()