用Python实现序列帧播放器

注意

以下所有代码不可直接使用,若要使用请到百度网盘上下载源码!
链接:https://pan.baidu.com/s/1P0x8ddbnn5veFnFQJLQ0tw
提取码:6666

程序思路

  1. 用PyQt5创建一个窗口
  2. 使用tkinter.messagebox和filedialog进行用户交互
  3. 使用Pygame播放序列帧动画
  4. 使用Opencv2无损合成序列帧

窗口设计

用Qt designer设计窗口,并用PyUIC转换,有需要的小伙伴请点击这里(提取码6666)

主界面

设计完成后主窗口大概是这个样子


这里是代码

import sys
from PyQt5 import QtCore, QtGui, QtWidgetsclass Ui_Form(object):def setupUi(self, Form):Form.setObjectName("Form")Form.resize(400, 194)self.label = QtWidgets.QLabel(Form)self.label.setGeometry(QtCore.QRect(80, 30, 281, 31))font = QtGui.QFont()font.setFamily("Adobe Caslon Pro Bold")font.setPointSize(13)font.setBold(True)font.setWeight(75)self.label.setFont(font)self.label.setObjectName("label")self.horizontalLayoutWidget = QtWidgets.QWidget(Form)self.horizontalLayoutWidget.setGeometry(QtCore.QRect(50, 70, 311, 41))self.horizontalLayoutWidget.setObjectName("horizontalLayoutWidget")self.horizontalLayout = QtWidgets.QHBoxLayout(self.horizontalLayoutWidget)self.horizontalLayout.setContentsMargins(0, 0, 0, 0)self.horizontalLayout.setObjectName("horizontalLayout")self.label_2 = QtWidgets.QLabel(self.horizontalLayoutWidget)self.label_2.setObjectName("label_2")self.horizontalLayout.addWidget(self.label_2)self.lineEdit = QtWidgets.QLineEdit(self.horizontalLayoutWidget)self.lineEdit.setReadOnly(True)self.lineEdit.setObjectName("lineEdit")self.horizontalLayout.addWidget(self.lineEdit)self.pushButton = QtWidgets.QPushButton(self.horizontalLayoutWidget)self.pushButton.setObjectName("pushButton")self.horizontalLayout.addWidget(self.pushButton)self.pushButton_2 = QtWidgets.QPushButton(Form)self.pushButton_2.setGeometry(QtCore.QRect(50, 130, 151, 41))self.pushButton_2.setObjectName("pushButton_2")self.pushButton_3 = QtWidgets.QPushButton(Form)self.pushButton_3.setGeometry(QtCore.QRect(214, 130, 151, 41))self.pushButton_3.setObjectName("pushButton_3")Form.setFixedSize(Form.width(), Form.height())self.retranslateUi(Form)QtCore.QMetaObject.connectSlotsByName(Form)def retranslateUi(self, Form):_translate = QtCore.QCoreApplication.translateForm.setWindowTitle(_translate("Form", "序列帧播放器 v3.2.4"))self.label.setText(_translate("Form", "欢迎使用序列帧播放器 v3.2.4"))self.label_2.setText(_translate("Form", "文件路径:"))self.pushButton.setText(_translate("Form", "浏览..."))self.pushButton_2.setText(_translate("Form", "预览动画"))self.pushButton_3.setText(_translate("Form", "合成动画"))self.pushButton_2.setDisabled(True)self.pushButton_3.setDisabled(True)def show_mainwindow():app=QtWidgets.QApplication(sys.argv)mainwindow_ui = Ui_Form()qMainWindow = QtWidgets.QMainWindow()mainwindow_ui.setupUi(qMainWindow)qMainWindow.show()sys.exit(app.exec_())show_mainwindow()

其他界面不作详细解释,需要源码请点击这里(提取码6666)

窗口交互

使用PyQt5的槽,绑定按钮事件

self.控件名.事件.connect(执行函数)

代码如下

def choose_file(self):self.pushButton.setDisabled(True)path=askdirectory()self.pushButton.setDisabled(False)if path!="":self.pushButton_2.setDisabled(False)self.pushButton_3.setDisabled(False)self.lineEdit.setText(path)else:self.pushButton_2.setDisabled(True)self.pushButton_3.setDisabled(True)def b2(self):f = open("setting.ini" , "w")f.write("path=" + self.lineEdit.text())f.close()import composeclass Login(QtWidgets.QWidget , compose.Ui_Form):def __init__(self):super(Login , self).__init__()self.setupUi(self)self.Form.setWindowModality(QtCore.Qt.ApplicationModal)lg = Login()lg.show()
def brot(self):self.pushButton_2.setDisabled(True)self.pushButton_3.setDisabled(True)f = open("setting.ini", "w")f.write("path=" + self.lineEdit.text())f.close()import browseclass Browse(QtWidgets.QWidget, browse.Ui_Form):def __init__(self):super(Browse, self).__init__()self.setupUi(self)self.Form.setWindowModality(QtCore.Qt.ApplicationModal)rg = Browse()rg.show()self.pushButton_2.setDisabled(False)self.pushButton_3.setDisabled(False)
def bro(self):#heref = open("setting.ini", "w")f.write("path=" + self.lineEdit.text())f.close()import browseclass Browse(QtWidgets.QWidget, browse.Ui_Form):def __init__(self):super(Browse, self).__init__()self.setupUi(self)self.Form.setWindowModality(QtCore.Qt.ApplicationModal)rg = Browse()rg.show()self.pushButton_2.setDisabled(False)self.pushButton_3.setDisabled(False)

绑定槽函数

self.pushButton.clicked.connect(self.choose_file)
self.pushButton_2.clicked.connect(self.brot)
self.pushButton_3.clicked.connect(self.b2)

预览模块

预览使用Pygame进行图片加载并循环播放。
代码如下

import glob
import os
import tkinter
from tkinter import messagebox
from PyQt5.QtWidgets import QMessageBox
root=tkinter.Tk()
root.withdraw()
from PyQt5 import QtCore, QtGui, QtWidgets
import time
import sys
import pygame
import threading
import random
from PIL import Image
from pygame.locals import *
pic=[]
def main():global picpygame.init()f = open("setting.ini", "r").read()f = f.split("\n")[0]f = f.split("=")[1]fn = os.listdir(f)imgf = fn[0].split(".")[1]g = glob.glob(f + "/*." + imgf)img = Image.open(g[0])imgSize = img.size  # 大小/尺寸w = img.width  # 图片的宽o = img.height  # 图片的高h=open("setting.ini","r").read()if bool(h.split("\n")[1].split("=")[1] == "True"):try:screen = pygame.display.set_mode((w, o), flags=FULLSCREEN | HWSURFACE)except:screen = pygame.display.set_mode((w, o))else:screen = pygame.display.set_mode((w, o))text = pygame.font.SysFont("SimHei", 30)pygame.display.set_caption("动图预览")index = 0fcclock = pygame.time.Clock()  # 创建一个时间对象fcclock.tick(int(h.split("\n")[2].split("=")[1]))  # 调用Clock()类创建的对象中的tick()函数while True:for event in pygame.event.get():if event.type == QUIT:pygame.quit()sys.exit()if event.type == KEYDOWN:if event.key == K_ESCAPE:pygame.quit()sys.exit()screen.fill((100, 100, 100))screen.blit(pic[index], (0, 0))text = pygame.font.SysFont("SimHei", 10)screen.blit(text.render("Animation file displayed " + f, True, (255, 255, 255)), (0, o - 10))screen.blit(text.render("Software maker Xiao Shen", True, (255, 255, 255)), (w - 120, o - 10))screen.blit(text.render("Current frame: " + str(index) + "/" + str(len(pic)), True, (255, 255, 255)), (0, 0))screen.blit(text.render("Press ESC to exit", True, (255, 255, 255)), (w - 85, 0))# Press ESC to exitindex += 1if index >= len(pic):index = 0pygame.display.update()fcclock.tick(int(h.split("\n")[2].split("=")[1]))
class Ui_Form(object):def setupUi(self, Form):Form.setObjectName("Form")Form.resize(400, 97)font = QtGui.QFont()font.setPointSize(11)Form.setFont(font)self.label = QtWidgets.QLabel(Form)self.label.setGeometry(QtCore.QRect(20, 20, 121, 16))font = QtGui.QFont()font.setPointSize(10)self.label.setFont(font)self.label.setObjectName("label")self.progressBar = QtWidgets.QProgressBar(Form)self.progressBar.setGeometry(QtCore.QRect(20, 50, 401, 23))self.progressBar.setMaximum(0)self.progressBar.setProperty("value", 0)self.progressBar.setFormat("")self.progressBar.setObjectName("progressBar")self.label_2 = QtWidgets.QLabel(Form)self.label_2.setGeometry(QtCore.QRect(310, 20, 71, 20))font = QtGui.QFont()font.setPointSize(10)self.label_2.setFont(font)self.Form=Formself.label_2.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)self.label_2.setObjectName("label_2")self.retranslateUi(Form)Form.setFixedSize(Form.width(), Form.height())t=threading.Thread(target=self.time_go)t.start()QtCore.QMetaObject.connectSlotsByName(Form)def time_go(self):for i in range(11):self.label_2.setText("("+str(i)+"/10)")if i==6:time.sleep(3)f = open("setting.ini", "r").read()f = f.split("\n")[0]f = f.split("=")[1]fn = os.listdir(f)try:imgf = fn[0].split(".")[1]g = glob.glob(f + "/*." + imgf)if imgf == 'jpg':passelif imgf == 'png':passelif imgf == 'jpeg':passelif imgf == 'bmp':passelse:print(自动)if len(g) == 0:print(自动)img = Image.open(g[0])except:QtWidgets.QMessageBox.critical(QtWidgets.QWidget(),"错误", "选择的文件夹无法被识别。\n请检查以下原因:\n1.文件夹内没有图片\n2.文件夹内有非图片文件\n请重新选择文件!")self.Form.close()time.sleep(random.uniform(0.0001000,0.2000000))self.Form.hide()time.sleep(0.3)self.Form.setWindowTitle("Loading resource")self.label.setText("正在加载资源...")f = open("setting.ini", "r").read()f = f.split("\n")[0]f = f.split("=")[1]fn = os.listdir(f)imgf = fn[0].split(".")[1]g = glob.glob(f + "/*." + imgf)self.label_2.setText("(0/"+str(len(g))+")")self.Form.show()count=0for i in g:global picpic.append(pygame.image.load(i))count+=1self.label_2.setText("("+str(count)+"/" + str(len(g)) + ")")self.Form.close()main()def retranslateUi(self, Form):_translate = QtCore.QCoreApplication.translateForm.setWindowTitle(_translate("Form", "Loading component"))self.label.setText(_translate("Form", "正在加载组件..."))      # 这里是为了耗时间,不需要的朋友可以去掉self.label_2.setText(_translate("Form", "(0/10)"))
def show_mainwindow():app=QtWidgets.QApplication(sys.argv)mainwindow_ui = Ui_Form()qMainWindow = QtWidgets.QMainWindow()mainwindow_ui.setupUi(qMainWindow)qMainWindow.show()sys.exit(app.exec_())
show_mainwindow()

渲染模块

使用OpenCV库进行图片的合成,这里有一个小细节
——计时模块
大概就是一个进位原理
代码如下

def time_go(self):while True:self.label_15.setText("已用时间:" + self.nt)h=int(self.nt.split(":")[0])m = int(self.nt.split(":")[1])s = int(self.nt.split(":")[2])#self.progressBar.setValue(int(self.value))time.sleep(1)s+=1if s>=60:s=0m+=1if m>=60:s=0m=0h+=1ss="00"sm="00"sh="00"if s<10:ss="0"+str(s)else:ss=str(s)if m<10:sm="0"+str(m)else:sm=str(m)if h<10:sh="0"+str(h)else:sh=str(h)self.nt=sh+":"+sm+":"+ssself.label_15.setText("已用时间:"+self.nt)if self.mt==False:return

我们决定使用多线程进行一个加快的处理
用法:

thread=threading.Thread(target=函数名)
thread.start # 启动线程

图片的合成过程有些复杂,不多说,直接放代码

def main_thread(self):self.label_13.setText("当前状态:正在准备")time.sleep(1.3)self.label_13.setText("当前状态:正在合成")img_array = []fn = os.listdir(open("setting.ini","r").read().split("\n")[0].split("=")[1])imgf = fn[0].split(".")[1]g = glob.glob(open("setting.ini","r").read().split("\n")[0].split("=")[1] + "/*." + imgf)add = 100 / len(g)for filename in g:self.label_14.setText("当前合成项:" + filename)if self.value <= 100:self.value += addimg = cv2.imdecode(ny.fromfile(filename, dtype=ny.uint8), -1)img_array.append(img)fps=self.spinBox.value()_width=int(open("config.tmp","r").read().split(" ")[0])_height =int(open("config.tmp", "r").read().split(" ")[1])self.label_13.setText("当前状态:正在写入")out = cv2.VideoWriter(self.lineEdit.text(), cv2.VideoWriter_fourcc(*'DIVX'), fps, (_width, _height))for i in range(len(img_array)):out.write(img_array[i])out.release()self.mt=Falseself.label_13.setText("当前状态:合成完毕")self.progressBar.setMaximum(1)self.label_16.setText("100%")QtWidgets.QMessageBox.information(QtWidgets.QWidget(), "完成","合成已完成\n耗时 "+self.nt+" 秒!")self.pushButton.setDisabled(False)self.pushButton_2.setDisabled(False)self.lineEdit.setDisabled(False)self.spinBox.setDisabled(False)self.comboBox_3.setDisabled(False)

用Python实现序列帧播放器相关推荐

  1. 基于python的音频播放器_基于python实现音乐播放器代码实例

    基于python实现音乐播放器代码实例,一首,函数,按钮,布局,音乐 基于python实现音乐播放器代码实例 易采站长站,站长之家为您整理了基于python实现音乐播放器代码实例的相关内容. 核心播放 ...

  2. python制作音乐播放器_python实现音乐播放器 python实现花框音乐盒子

    本文实例为大家分享了python实现音乐播放器的具体代码,供大家参考,具体内容如下 """这是一个用海龟画图模块和pygame的混音模块制作的简易播放器. 作者:李兴球, ...

  3. python生成USB播放器歌单

    用python生成USB播放器歌单 个人比较喜欢听歌,前段时间还买了个可以插U盘和储存卡的播放器,它支持直接按数字跳转歌曲,但自己却不知道歌曲对应的号码. 测试发现歌曲顺序并不是按文件名排序,也不是按 ...

  4. python本地音乐播放器+附源文件地址

    python本地音乐播放器 因为现在听歌都要版权,所以我喜欢把音乐下载下来听.但一直没找到喜欢的本地音乐播放器,我也只会一些python皮毛,所以有了自己写一个python本地音乐播放器的想法,经过摸 ...

  5. 用Python制作简易播放器(电子钢琴) mac系统

    用Python制作简易播放器(电子钢琴) 开发环境:Python3.7 Mac OS 思路: 先根据需要设计GUI的样式,并思考需要定义什么功能 把功能写出来 把功能填入GUI之中 用曲子测试完整的程 ...

  6. python可视化音乐播放器(pyqt5+多平台下载)

    1.主要功能 实现一个python可视化音乐播放器,用的是pyqt5,主要是三个平台获取,一个是网易云音乐,一个是酷我音乐,一个是酷狗音乐者三个平台获取音乐,能够进行下载,然后进行播放,具备网页获取的 ...

  7. 用Python制作音乐播放器(下,含完整源代码)

    哈喽,大家不知道是上午好还是中午好还是下午好还是晚上好! 音乐播放器,大家应该不陌生吧!今天我们一起来学习如何用python制作音乐播放器.之所开头有一个"下",是因为我们以前已经 ...

  8. 用Python制作音乐播放器(上)

    用Python制作简单的音乐播放器 哈喽,大家不知道是上午好还是中午好还是下午好还是晚上好! 音乐播放器,大家应该不陌生吧!今天我们一起来学习如何用python制作音乐播放器.之所开头有一个" ...

  9. python 本地音乐播放器制作过程

    制作这个播放器的目的是为了将下载下来的mp3文件进行随机或是顺序的播放.选择需要播放的音乐的路径,选择播放方式,经过测试可以完美的播放本地音乐. [阅读全文] 在开始之前介绍一个免费下载mp3音乐的网 ...

最新文章

  1. apache php wordpress,windows 安装 apache php wordpress
  2. 这届科技冬奥,就数这位北京大妞让人意想不到
  3. C++ 中 const和define的区别
  4. Spring属性占位符配置器–一些不太明显的选项
  5. SQL SERVER 2016研究三
  6. 【HDU - 1839】Delay Constrained Maximum Capacity Path(最短路 + 二分)
  7. 基于JAVA+SpringMVC+MYSQL的人事管理系统
  8. D3、EChart、HighChart绘图demol
  9. 如何让路由器摆脱安全困扰
  10. 事件和数据回发机制的实现
  11. 周志华《机器学习》西瓜书第一章绪论第一部分
  12. 分享一个Halcon学习网站
  13. 2021年最优秀的新闻APP或许是这两个(国内没上架)
  14. 同步时间服务器修改同步间隔,如何更改Windows 10时间同步间隔
  15. ‘class QFontMetrics‘ has no member named ‘horizontalAdvance‘
  16. 深入理解HTML表格秘籍
  17. MeterSphere与云效DevOps集成
  18. 2.系统测试流程规范
  19. 论信息时代企业管理如何创新
  20. 问题解决:使用GitHub时git push需要输入账号和密码Username for... (Use git clone SSH) git remote add 或set-url(推荐)

热门文章

  1. WPS文字中通过宏加快捷键实现仿word中Lorem()函数的功能
  2. python计算利息程序_Python——GUI编程 利息计算器 作业9(python programming)-Go语言中文社区...
  3. docker镜像迁移mysql启动报错_README.md
  4. Java基础——斐波那契数列问题之兔子不死会有几只兔子
  5. ivue-admin Table单元格内换行问题
  6. 做私域最常犯的四个错误
  7. Qdown:你值得拥有的全功能文件下载工具
  8. 茅台酒养成记:质量是对消费者最长久而衷心的承诺
  9. Linux常用基础命令(巨全)你想要的我都有❀
  10. 一个生成公章图片的简易工具