You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Tkinter框架中同时显示源视频及多个视频副本

在同一Tkinter窗口显示源视频+多个副本的实现方案

你现在的代码已经能单帧播放视频了,要加多个副本很简单,核心就是把读出来的同一帧,在画布的不同位置重复绘制即可,下面给你两种可行的修改方案:

方案1:直接在画布不同位置重复绘制单帧

这种方式改动少,快速实现多副本显示,适合基础布局需求:

from tkinter import *
from PIL import Image, ImageTk
import cv2

root = Tk()
root.title("多视频窗口")

# 换成本地MP4就把0改成"vid1.mp4"
vid = cv2.VideoCapture(0)
width = int(vid.get(cv2.CAP_PROP_FRAME_WIDTH))
height = int(vid.get(cv2.CAP_PROP_FRAME_HEIGHT))

# 设置显示的行列数,比如2行2列,共4个视频窗口(含源视频)
rows = 2
cols = 2

# 画布尺寸要适配所有窗口
canvas_width = width * cols
canvas_height = height * rows

def get_frame():
    ret, frame = vid.read()
    if ret:
        return (ret, cv2.cvtColor(frame, cv2.COLOR_BGR2RGB))
    else:
        return (ret, None)

def update():
    ret, frame = get_frame()
    if ret:
        img = Image.fromarray(frame)
        photo = ImageTk.PhotoImage(image=img)
        # 清空画布旧内容,避免画面重叠
        canvas.delete("all")
        # 循环在不同坐标绘制相同帧
        for i in range(rows):
            for j in range(cols):
                x_pos = j * width
                y_pos = i * height
                canvas.create_image(x_pos, y_pos, image=photo, anchor=NW)
        # 必须保留图片引用,防止被垃圾回收导致画面消失
        canvas.image = photo
    # 定时更新画面,维持视频流畅度
    root.after(delay, update)

canvas = Canvas(root, width=canvas_width, height=canvas_height)
canvas.pack()
delay = 15
update()
root.mainloop()
vid.release()

方案2:将多帧拼接成大图后显示

这种方式先把多个相同帧拼成一张完整大图,再整体绘制到画布,适合需要自定义布局(比如不同大小副本)的场景:

from tkinter import *
from PIL import Image, ImageTk
import cv2
import numpy as np

root = Tk()
root.title("拼接式多视频窗口")

vid = cv2.VideoCapture(0)
width = int(vid.get(cv2.CAP_PROP_FRAME_WIDTH))
height = int(vid.get(cv2.CAP_PROP_FRAME_HEIGHT))

rows = 2
cols = 2
combined_width = width * cols
combined_height = height * rows

def get_frame():
    ret, frame = vid.read()
    if ret:
        return (ret, cv2.cvtColor(frame, cv2.COLOR_BGR2RGB))
    else:
        return (ret, None)

def update():
    ret, frame = get_frame()
    if ret:
        # 创建空的大图容器
        combined_img = np.zeros((combined_height, combined_width, 3), dtype=np.uint8)
        # 将源帧填充到大图的各个区域
        for i in range(rows):
            for j in range(cols):
                y_start = i * height
                x_start = j * width
                combined_img[y_start:y_start+height, x_start:x_start+width] = frame
        
        # 转换为Tkinter支持的图像格式
        img = Image.fromarray(combined_img)
        photo = ImageTk.PhotoImage(image=img)
        canvas.create_image(0, 0, image=photo, anchor=NW)
        canvas.image = photo
    root.after(delay, update)

canvas = Canvas(root, width=combined_width, height=combined_height)
canvas.pack()
delay = 15
update()
root.mainloop()
vid.release()

关键注意点

  • 修改rows和cols数值可以调整显示的副本数量,比如3行3列就是9个窗口
  • 若使用本地MP4文件,替换cv2.VideoCapture(0)中的0为视频文件路径即可
  • 必须保留canvas.image = photo这行代码,否则Tkinter的垃圾回收机制会销毁图片对象,导致画面消失

内容的提问来源于stack exchange,提问作者Enthusiast

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 03:08:14