用Python实现序列帧播放器
用Python实现序列帧播放器
注意
以下所有代码不可直接使用,若要使用请到百度网盘上下载源码!
链接:https://pan.baidu.com/s/1P0x8ddbnn5veFnFQJLQ0tw
提取码:6666
程序思路
- 用PyQt5创建一个窗口
- 使用tkinter.messagebox和filedialog进行用户交互
- 使用Pygame播放序列帧动画
- 使用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实现序列帧播放器相关推荐
- 基于python的音频播放器_基于python实现音乐播放器代码实例
基于python实现音乐播放器代码实例,一首,函数,按钮,布局,音乐 基于python实现音乐播放器代码实例 易采站长站,站长之家为您整理了基于python实现音乐播放器代码实例的相关内容. 核心播放 ...
- python制作音乐播放器_python实现音乐播放器 python实现花框音乐盒子
本文实例为大家分享了python实现音乐播放器的具体代码,供大家参考,具体内容如下 """这是一个用海龟画图模块和pygame的混音模块制作的简易播放器. 作者:李兴球, ...
- python生成USB播放器歌单
用python生成USB播放器歌单 个人比较喜欢听歌,前段时间还买了个可以插U盘和储存卡的播放器,它支持直接按数字跳转歌曲,但自己却不知道歌曲对应的号码. 测试发现歌曲顺序并不是按文件名排序,也不是按 ...
- python本地音乐播放器+附源文件地址
python本地音乐播放器 因为现在听歌都要版权,所以我喜欢把音乐下载下来听.但一直没找到喜欢的本地音乐播放器,我也只会一些python皮毛,所以有了自己写一个python本地音乐播放器的想法,经过摸 ...
- 用Python制作简易播放器(电子钢琴) mac系统
用Python制作简易播放器(电子钢琴) 开发环境:Python3.7 Mac OS 思路: 先根据需要设计GUI的样式,并思考需要定义什么功能 把功能写出来 把功能填入GUI之中 用曲子测试完整的程 ...
- python可视化音乐播放器(pyqt5+多平台下载)
1.主要功能 实现一个python可视化音乐播放器,用的是pyqt5,主要是三个平台获取,一个是网易云音乐,一个是酷我音乐,一个是酷狗音乐者三个平台获取音乐,能够进行下载,然后进行播放,具备网页获取的 ...
- 用Python制作音乐播放器(下,含完整源代码)
哈喽,大家不知道是上午好还是中午好还是下午好还是晚上好! 音乐播放器,大家应该不陌生吧!今天我们一起来学习如何用python制作音乐播放器.之所开头有一个"下",是因为我们以前已经 ...
- 用Python制作音乐播放器(上)
用Python制作简单的音乐播放器 哈喽,大家不知道是上午好还是中午好还是下午好还是晚上好! 音乐播放器,大家应该不陌生吧!今天我们一起来学习如何用python制作音乐播放器.之所开头有一个" ...
- python 本地音乐播放器制作过程
制作这个播放器的目的是为了将下载下来的mp3文件进行随机或是顺序的播放.选择需要播放的音乐的路径,选择播放方式,经过测试可以完美的播放本地音乐. [阅读全文] 在开始之前介绍一个免费下载mp3音乐的网 ...
最新文章
- apache php wordpress,windows 安装 apache php wordpress
- 这届科技冬奥,就数这位北京大妞让人意想不到
- C++ 中 const和define的区别
- Spring属性占位符配置器–一些不太明显的选项
- SQL SERVER 2016研究三
- 【HDU - 1839】Delay Constrained Maximum Capacity Path(最短路 + 二分)
- 基于JAVA+SpringMVC+MYSQL的人事管理系统
- D3、EChart、HighChart绘图demol
- 如何让路由器摆脱安全困扰
- 事件和数据回发机制的实现
- 周志华《机器学习》西瓜书第一章绪论第一部分
- 分享一个Halcon学习网站
- 2021年最优秀的新闻APP或许是这两个(国内没上架)
- 同步时间服务器修改同步间隔,如何更改Windows 10时间同步间隔
- ‘class QFontMetrics‘ has no member named ‘horizontalAdvance‘
- 深入理解HTML表格秘籍
- MeterSphere与云效DevOps集成
- 2.系统测试流程规范
- 论信息时代企业管理如何创新
- 问题解决:使用GitHub时git push需要输入账号和密码Username for... (Use git clone SSH) git remote add 或set-url(推荐)
热门文章
- WPS文字中通过宏加快捷键实现仿word中Lorem()函数的功能
- python计算利息程序_Python——GUI编程 利息计算器 作业9(python programming)-Go语言中文社区...
- docker镜像迁移mysql启动报错_README.md
- Java基础——斐波那契数列问题之兔子不死会有几只兔子
- ivue-admin Table单元格内换行问题
- 做私域最常犯的四个错误
- Qdown:你值得拥有的全功能文件下载工具
- 茅台酒养成记:质量是对消费者最长久而衷心的承诺
- Linux常用基础命令(巨全)你想要的我都有❀
- 一个生成公章图片的简易工具