我想使用 python 构建一个有按钮的应用程序,该按钮在单击后打开相机, 但我想在打开时设计相机框架。设计类似于此图像,但中间的空白是相机显示的内容。
我尝试使用中间透明的图像,但没有成功。
为了创建设计,我也尝试使用 Canvas,但它只运行一次,第二次时圆圈没有显示。
这是我正在处理的最后一个代码,它没有我想要的形状,并且存在我提到的相机问题。
from tkinter import *
from PIL import ImageTk, Image
import cv2
from tkinter import PhotoImage
main_root = Tk()
main_root.withdraw()
splash_root = Toplevel()
splash_root.geometry("800x480")
splash_root.overrideredirect(True)
bg = PhotoImage(file="image/tc.png")
lab = Label(splash_root, image=bg)
lab.pack()
def main():
splash_root.withdraw()
# splash_root.destroy()
root = Toplevel()
root.geometry("800x480")
root.resizable(width=False, height=False)
root.title("")
WIDTH = 800
HEIGHT = 480
cam_on = False
cap = None
# cap= cv2.VideoCapture(0)
def first_window():
frame = Frame(root, width=WIDTH, height=HEIGHT, bg="#edf5ef")
frame.place(x=0, y=0)
border1 = LabelFrame(root, bd=2, bg="black", fg="black", width=160, height=61)
border1.place(x=80, y=300)
newExamBtn = Button(
root,
text="New Exam",
bg="#c1d4c6",
font=("Helvatical", 13),
padx=36,
pady=15,
border=0,
command=newExam,
)
newExamBtn.place(x=82, y=302)
def newExam():
frameNE = Frame(root, width=WIDTH, height=HEIGHT, bg="white")
frameNE.place(x=0, y=0)
backBtn = Button(
root,
bg="white",
activebackground="white",
border=0,
width=64,
height=64,
image=backImgGray,
command=first_window,
)
backBtn.place(x=0, y=0)
examBtnBorder = LabelFrame(
frameNE, bd=2, bg="gray", fg="white", width=200, height=80
)
examBtnBorder.place(x=300, y=100)
examBtnIcn = Label(root, bg="gray", image=examImg)
examBtnIcn.place(x=310, y=105)
examBtn = Button(
frameNE,
text="Exam",
bg="gray",
fg="white",
activebackground="gray",
activeforeground="white",
border=0,
font=("Helvatical", 20),
command=Camera,
)
examBtn.place(x=380, y=110)
def start_vid():
global cam_on, cap
# stop_vid()
cam_on = True
cap = cv2.VideoCapture(0)
show_frames()
def stop_vid():
global cam_on, cap
cam_on = False
if cap:
cap.release()
cap = None
def show_frames():
global cap , cam_on
labelCam =Label(root)
labelCam.pack()
if cam_on:
# ret, frame = cap.read()
# Get the latest frame and convert into Image
cv2image= cv2.cvtColor(cap.read()[1],cv2.COLOR_BGR2RGB)
img = Image.fromarray(cv2image)
# Convert image to PhotoImage
imgtk = ImageTk.PhotoImage(image = img)
labelCam.imgtk = imgtk
labelCam.configure(image=imgtk)
# Repeat after an interval to capture continiously
labelCam.after(10, show_frames)
# if ret:
# cv2image = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
# img = Image.fromarray(cv2image).resize((810,640))
# imgtk = ImageTk.PhotoImage(image=img)
# labelCam.imgtk = imgtk
# labelCam.configure(image=imgtk)
# labelCam.after(10, show_frames)
def closeCam_and_Back():
stop_vid()
newExam()
def Camera():
frameC = Frame(root, width=WIDTH, height=HEIGHT, bg="#edf5ef")
frameC.place(x=0, y=0)
# IMAGE_PATH = 'image/Untitled11.png'
# canvas = Canvas(root, width=WIDTH, height=HEIGHT)
# canvas.pack()
start_vid()
# img = ImageTk.PhotoImage(Image.open(IMAGE_PATH).resize((WIDTH, HEIGHT), Image.ANTIALIAS))
# canvas.background = img # Keep a reference in case this code is put in a function.
# bg = canvas.create_image(0, 0, anchor='nw', image=img)
backBtn = Button(
frameC,
bg="#353b36",
activebackground="#353b36",
border=0,
width=50,
height=32,
image=backImg32,
command=closeCam_and_Back,
)
backBtn.place(x=0, y=0)
first_window()
backImg32 = Image.open("image/icons8-left-64.png").resize((32, 32), Image.LANCZOS)
backImg32 = ImageTk.PhotoImage(backImg32)
backImgGray = Image.open("image/icons8-left-64-gray.png").resize((50, 50), Image.LANCZOS)
backImgGray = ImageTk.PhotoImage(backImgGray)
examImg = PhotoImage(file="image/icons8-exam-64.png")
splash_root.after(3000, main)
mainloop()
您可以使用
Canvas
小部件来显示透明图像。只需将相机馈送的图像与透明图像放在中间覆盖层的顶部即可。
下面是中间透明的图像:
下面是显示上图背后的视频的示例:
import tkinter as tk
from PIL import Image, ImageTk
import cv2
# define the video size
w, h = 640, 360
root = tk.Tk()
canvas = tk.Canvas(root, width=w, height=h, highlightthickness=0)
canvas.pack()
# image for showing the camera feed
tkimg = ImageTk.PhotoImage("RGB", (w, h))
video = canvas.create_image(0, 0, image=tkimg, anchor="nw")
# image overlay on top of the above image
panel = tk.PhotoImage(file="panel.png")
canvas.create_image(0, 0, image=panel, anchor="nw")
#cap = cv2.VideoCapture(0)
# use a video file instead for demostration
cap = cv2.VideoCapture("TheDivision2.mp4")
def play_video():
ret, frame = cap.read()
if ret:
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
image = Image.fromarray(frame)
tkimg.paste(image)
root.after(20, play_video)
play_video() # start playing the video
root.mainloop()
输出: