PyQt5视频截图项目升级版

1、需求

原需求:使用PyQt5将视频切割成图片

现增加:进度条以及选择文件功能,在ui上打印出日志

2、UI设计

原ui:

使用PyQt重新设计ui:

3、cmd命令转化为python文件
C:\Users\DIY-PC\AppData\Local\Programs\Python\Python38\python.exe -m PyQt5.uic.pyuic D:\python\pyqt\ui\screenshot.ui -o D:\python\pyqt\ui\ssplus.py
4、总结新加入知识点

1、往QTextEdit组件后追加文本:

self.output = QtWidgets.QTextEdit(Dialog)
self.output.append("")

2、选择文件,选择文件夹

self.inputBut = QtWidgets.QPushButton(Dialog)
self.inputBut.setGeometry(QtCore.QRect(300, 20, 75, 23))
self.inputBut.setObjectName("inputBut") # 选择文件
self.inputBut.clicked.connect(self.select_file)  # 为button绑定消息对话框
self.outputBut = QtWidgets.QPushButton(Dialog)
self.outputBut.setGeometry(QtCore.QRect(300, 50, 75, 23))
self.outputBut.setObjectName("outputBut") # 选择文件夹
self.outputBut.clicked.connect(self.select_dir)  # 为button绑定消息对话框

self.inputBut.setText(_translate("Dialog", "选择文件"))
self.outputBut.setText(_translate("Dialog", "选择文件夹"))

def select_file(self):
    """选择文件对话框"""
    # QFileDialog组件定义
    fileDialog = QFileDialog(self)
    # QFileDialog组件设置
    fileDialog.setWindowTitle("选择视频")  # 设置对话框标题
    fileDialog.setFileMode(QFileDialog.AnyFile)  # 设置能打开文件的格式
    fileDialog.setDirectory(r'D:')  # 设置默认打开路径
    # fileDialog.setNameFilter("Images (*.png *.xpm *.jpg)")  # 按文件名过滤
    file_path = fileDialog.exec()  # 窗口显示,返回文件路径
    if file_path and fileDialog.selectedFiles():
        #self.output.append("选择文件成功:{}".format(fileDialog.selectedFiles()[0]))
        self.inputdir.setText(fileDialog.selectedFiles()[0])
    # 方式二
    # file_path, file_type = QFileDialog.getOpenFileName(self, '标题', os.getcwd(), 'Images (*.png *.xpm *.jpg)')
    # if file_path and file_type:
    #     print("选择文件成功:{}".format(file_path))

def select_dir(self):
    """选择文件夹对话框架"""
    dir_path = QFileDialog.getExistingDirectory(self, '选择存储路径', os.getcwd())
    if dir_path:
        #self.output.append("选择文件夹成功:{}".format(dir_path))
        self.outputdir.setText(dir_path)

 

3、进度条根据程序设置进度:

思路:视频按帧截图和按秒截图,知道视频总帧数和总秒数之后,在程序进行时,计算当前正在处理第几秒第几帧的数据,这样能得知当前进度

self.progressBar = QtWidgets.QProgressBar(Dialog)
self.progressBar.setGeometry(QtCore.QRect(90, 120, 281, 16))
self.progressBar.setProperty("value", 0)
self.progressBar.setObjectName("progressBar")

self.ui.progressBar.setValue(XXX)#XXX指的当前进度
5、运行效果

6、详细代码

项目结构:

main.py:

import sys
import os
import cv2
import ssplus
from PyQt5.QtWidgets import QApplication, QDialog
#注意就是下面的 if 语句
if hasattr(sys, 'frozen'):
    os.environ['PATH'] = sys._MEIPASS + ";" + os.environ['PATH']

# import others
class MainDialog(QDialog):

    def __init__(self, parent=None):

        super(QDialog, self).__init__(parent)

        self.ui = ssplus.Ui_Dialog()

        self.ui.setupUi(self)

    def accept(self):
        # 设置进度条
        video=self.ui.inputdir.text()
        f_save_path=self.ui.outputdir.text()+'/'
        maskText = self.ui.pattern.currentText()

        mask = self.getCode(maskText)
        frame_interval = 2  # 设置帧率间隔
        time_interval = 1  # 设置时间间隔(单位:s)
     
        if (mask == 1):
            self.ui.output.append("当前模式:按照帧率截取视频\n帧率间隔:"+str(frame_interval))
        elif (mask == 2):
            self.ui.output.append("当前模式:按照时间截取视频\n时间间隔:"+str(time_interval)+"s")

        file_name=os.path.basename(video).split('.')[0]  # 拆分视频文件名称 ,剔除后缀
        folder_name = f_save_path + file_name  # 保存图片的上级目录+对应每条视频名称 构成新的目录存放每个视频
        os.makedirs(folder_name, exist_ok=True)  # 创建存放视频的对应目录
        vc = cv2.VideoCapture(video)  # 读入视频文件
        fps = vc.get(cv2.CAP_PROP_FPS)  # 获取当前视频帧率
        frame_num=vc.get(cv2.CAP_PROP_FRAME_COUNT)
        rval = vc.isOpened()  # 判断视频是否打开
        c = 1
        while rval:  # 循环读取视频帧
            rval, frame = vc.read()  # videoCapture.read() 函数,第一个返回值为是否成功获取视频帧,第二个返回值为返回的视频帧;
            pic_path = folder_name + '/'
            if rval:
                if(mask == 1):
                    if (c % round(frame_interval) == 0):  # 每隔frame_interval帧存储一次
                        cv2.imencode('.jpg', frame)[1].tofile(
                            pic_path + file_name + '_' + str(round(c / frame_interval)) + '.jpg')  # 中文路径也可以保存

                        self.ui.output.append(file_name + '_' + str(round(c / frame_interval)) + '.jpg')
                        self.ui.progressBar.setValue(round(c / frame_interval) / round(frame_num/frame_interval) * 100)
                    cv2.waitKey(1)
                    c = c + 1
                elif(mask == 2):
                    total_seconds=frame_num/fps
                    if (c % (round(fps)*time_interval) == 0):  # 每隔time_interval秒存储一次
                        cv2.imencode('.jpg', frame)[1].tofile(
                            pic_path + file_name + '_' + str(round(c / fps)) + '.jpg')
                        self.ui.output.append(file_name + '_' + str(round(c / fps)) + '.jpg')
                        self.ui.progressBar.setValue(round(c / fps) / round(total_seconds) * 100)
                        print(round(c / fps) / round(total_seconds) * 100)
                    cv2.waitKey(1)
                    c = c + 1
            else:
                break
        vc.release()
        outputText=('save_success:' + folder_name)
        self.ui.output.append(outputText)
        self.ui.progressBar.setValue(100)

    def getCode(self, cityName):

        cityDict = {"按帧": 1,
                    "按秒": 2}

        return cityDict[cityName]

    def clearText(self):
        self.ui.inputdir.clear()
        self.ui.outputdir.clear()
        self.ui.output.clear()
        self.ui.progressBar.setValue(0)  # 任务完成后将进度条归零

if __name__ == '__main__':

    myapp = QApplication(sys.argv)

    myDlg = MainDialog()

    myDlg.show()

    sys.exit(myapp.exec_())

 ssplus.py:

# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file 'D:\python\pyqt\ui\screenshot.ui'
#
# Created by: PyQt5 UI code generator 5.15.9
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again.  Do not edit this file unless you know what you are doing.

import os
import time

from PyQt5 import QtCore, QtWidgets
from PyQt5.QtWidgets import QFileDialog, QWidget

class Ui_Dialog(QWidget):
    def setupUi(self, Dialog):
        Dialog.setObjectName("Dialog")
        Dialog.resize(400, 300)
        self.confirm = QtWidgets.QDialogButtonBox(Dialog)
        self.confirm.setGeometry(QtCore.QRect(30, 260, 341, 32))
        self.confirm.setOrientation(QtCore.Qt.Horizontal)
        self.confirm.setStandardButtons(QtWidgets.QDialogButtonBox.Cancel|QtWidgets.QDialogButtonBox.Ok)
        self.confirm.setObjectName("confirm")
        self.label = QtWidgets.QLabel(Dialog)
        self.label.setGeometry(QtCore.QRect(30, 20, 54, 12))
        self.label.setObjectName("label")
        self.label_2 = QtWidgets.QLabel(Dialog)
        self.label_2.setGeometry(QtCore.QRect(30, 50, 54, 12))
        self.label_2.setObjectName("label_2")
        self.label_3 = QtWidgets.QLabel(Dialog)
        self.label_3.setGeometry(QtCore.QRect(30, 80, 54, 20))
        self.label_3.setObjectName("label_3")
        self.pattern = QtWidgets.QComboBox(Dialog)
        self.pattern.setGeometry(QtCore.QRect(90, 80, 69, 22))
        self.pattern.setObjectName("pattern")
        self.pattern.addItem("")
        self.pattern.addItem("")
        self.inputdir = QtWidgets.QLineEdit(Dialog)
        self.inputdir.setGeometry(QtCore.QRect(90, 20, 201, 20))
        self.inputdir.setObjectName("inputdir")
        self.outputdir = QtWidgets.QLineEdit(Dialog)
        self.outputdir.setGeometry(QtCore.QRect(90, 50, 201, 20))
        self.outputdir.setObjectName("outputdir")
        self.output = QtWidgets.QTextEdit(Dialog)
        self.output.setGeometry(QtCore.QRect(30, 150, 341, 101))
        self.output.setObjectName("output")
        self.progressBar = QtWidgets.QProgressBar(Dialog)
        self.progressBar.setGeometry(QtCore.QRect(90, 120, 281, 16))
        self.progressBar.setProperty("value", 0)
        self.progressBar.setObjectName("progressBar")
        self.label_4 = QtWidgets.QLabel(Dialog)
        self.label_4.setGeometry(QtCore.QRect(30, 120, 54, 12))
        self.label_4.setObjectName("label_4")
        self.inputBut = QtWidgets.QPushButton(Dialog)
        self.inputBut.setGeometry(QtCore.QRect(300, 20, 75, 23))
        self.inputBut.setObjectName("inputBut") # 选择文件
        self.inputBut.clicked.connect(self.select_file)  # 为button绑定消息对话框
        self.outputBut = QtWidgets.QPushButton(Dialog)
        self.outputBut.setGeometry(QtCore.QRect(300, 50, 75, 23))
        self.outputBut.setObjectName("outputBut") # 选择文件夹
        self.outputBut.clicked.connect(self.select_dir)  # 为button绑定消息对话框

        self.retranslateUi(Dialog)

        # Start program execution when the start button is clicked
        self.confirm.accepted.connect(Dialog.accept)
        #self.confirm.accepted.connect(Dialog.onStart) # type: ignore
        self.confirm.rejected.connect(Dialog.clearText) # type: ignore
        QtCore.QMetaObject.connectSlotsByName(Dialog)

    def retranslateUi(self, Dialog):
        _translate = QtCore.QCoreApplication.translate
        Dialog.setWindowTitle(_translate("Dialog", "视频截图"))
        self.label.setText(_translate("Dialog", "视频:"))
        self.label_2.setText(_translate("Dialog", "存储路径:"))
        self.label_3.setText(_translate("Dialog", "截取模式:"))
        self.pattern.setCurrentText(_translate("Dialog", "按帧"))
        self.pattern.setItemText(0, _translate("Dialog", "按帧"))
        self.pattern.setItemText(1, _translate("Dialog", "按秒"))
        self.label_4.setText(_translate("Dialog", "进度条:"))
        self.inputBut.setText(_translate("Dialog", "选择文件"))
        self.outputBut.setText(_translate("Dialog", "选择文件夹"))

    def select_file(self):
        """选择文件对话框"""
        # QFileDialog组件定义
        fileDialog = QFileDialog(self)
        # QFileDialog组件设置
        fileDialog.setWindowTitle("选择视频")  # 设置对话框标题
        fileDialog.setFileMode(QFileDialog.AnyFile)  # 设置能打开文件的格式
        fileDialog.setDirectory(r'D:')  # 设置默认打开路径
        # fileDialog.setNameFilter("Images (*.png *.xpm *.jpg)")  # 按文件名过滤
        file_path = fileDialog.exec()  # 窗口显示,返回文件路径
        if file_path and fileDialog.selectedFiles():
            #self.output.append("选择文件成功:{}".format(fileDialog.selectedFiles()[0]))
            self.inputdir.setText(fileDialog.selectedFiles()[0])
        # 方式二
        # file_path, file_type = QFileDialog.getOpenFileName(self, '标题', os.getcwd(), 'Images (*.png *.xpm *.jpg)')
        # if file_path and file_type:
        #     print("选择文件成功:{}".format(file_path))

    def select_dir(self):
        """选择文件夹对话框架"""
        dir_path = QFileDialog.getExistingDirectory(self, '选择存储路径', os.getcwd())
        if dir_path:
            #self.output.append("选择文件夹成功:{}".format(dir_path))
            self.outputdir.setText(dir_path)

  • 9
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值