广告位联系
返回顶部
分享到

Python实现批量添加视频文本水印

python 来源:互联网 作者:佚名 发布时间:2025-02-15 23:12:23 人浏览
摘要

这个是一个基于PyQt5开发的视频水印批量添加工具,旨在为多个视频文件添加文本水印。用户可以自定义水印的文本内容、字体颜色、字号大小以及位置(如左上角、右上角、左下角、右下角和

这个是一个基于PyQt5开发的视频水印批量添加工具,旨在为多个视频文件添加文本水印。用户可以自定义水印的文本内容、字体颜色、字号大小以及位置(如左上角、右上角、左下角、右下角和中心位置)。程序支持常见的视频格式,如MP4、AVI、MOV和MKV,并能够批量处理视频文件,输出带有水印的新视频。

2.功能介绍

选择输入和输出目录: 用户可以通过文件对话框选择视频文件的输入目录和保存带水印视频的输出目录。

自定义水印文本: 用户可以在输入框中填写水印的文本内容,水印会被添加到视频上。

自定义水印位置: 水印可以选择显示在视频的不同位置,包括左上角、右上角、左下角、右下角和中心。

自定义水印字体颜色: 用户可以通过颜色选择器来选择水印文本的颜色,支持丰富的颜色选择。

选择水印字体大小: 提供了多个字体大小选项(20到100),用户可以根据需要选择合适的字号。

批量处理视频: 程序会遍历输入目录中的所有视频文件,逐一为其添加水印并保存到输出目录。支持的视频格式包括MP4、AVI、MOV、MKV等。

进度条与日志显示: 程序提供实时进度条,显示当前视频处理的进度。同时,日志框显示详细的处理信息和错误提示,帮助用户实时了解处理状态。

处理完成提示: 所有视频处理完成后,会弹出提示框,告知用户所有视频水印已成功添加。

3. 运行效果

4.相关源码

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

221

222

223

224

225

226

227

228

229

230

231

232

233

234

235

236

237

238

239

240

241

242

243

244

245

246

247

248

249

250

251

252

253

254

255

import os

import time

import cv2

import numpy as np

from PyQt5.QtCore import Qt, QThread, pyqtSignal, QThreadPool, QRunnable, QObject

from PyQt5.QtGui import QColor

from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QPushButton, QFileDialog, QTextBrowser, QProgressBar, QComboBox, QLabel, QLineEdit, QColorDialog, QMessageBox, QHBoxLayout

from PyQt5.QtGui import QFont

from PIL import Image, ImageDraw, ImageFont

 

class WatermarkWorker(QObject):

    update_log_signal = pyqtSignal(str)

    update_progress_signal = pyqtSignal(int)

    processing_complete_signal = pyqtSignal()

 

    def __init__(self, input_dir, output_dir, watermark_text, watermark_position, watermark_color, font_size, video_file):

        super().__init__()

        self.input_dir = input_dir

        self.output_dir = output_dir

        self.watermark_text = watermark_text

        self.watermark_position = watermark_position

        self.watermark_color = watermark_color

        self.font_size = font_size

        self.video_file = video_file

 

    def add_watermark(self):

        input_video_path = os.path.join(self.input_dir, self.video_file)

        output_video_path = os.path.join(self.output_dir, "watermarked_" + self.video_file)

 

        self.update_log_signal.emit(f"[{self.get_current_time()}] 开始处理视频: {self.video_file}")

 

        cap = cv2.VideoCapture(input_video_path)

        frame_width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))

        frame_height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))

        fourcc = cv2.VideoWriter_fourcc(*'mp4v')

        out = cv2.VideoWriter(output_video_path, fourcc, 30.0, (frame_width, frame_height))

 

        total_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))

        processed_frames = 0

 

        while cap.isOpened():

            ret, frame = cap.read()

            if not ret:

                break

 

            frame = self.add_text_watermark(frame, self.watermark_text, self.watermark_position, frame_width, frame_height)

            out.write(frame)

 

            processed_frames += 1

            progress = int((processed_frames / total_frames) * 100)

            self.update_progress_signal.emit(progress)

 

        cap.release()

        out.release()

 

        self.update_log_signal.emit(f"[{self.get_current_time()}] 水印已添加并保存到: {output_video_path}")

        self.update_progress_signal.emit(100)

        self.processing_complete_signal.emit()

 

    def add_text_watermark(self, frame, text, position, width, height):

        pil_image = Image.fromarray(cv2.cvtColor(frame, cv2.COLOR_BGR2RGB))

        draw = ImageDraw.Draw(pil_image)

        try:

            font = ImageFont.truetype("simhei.ttf", self.font_size)

        except IOError:

            font = ImageFont.load_default()

 

        bbox = draw.textbbox((0, 0), text, font=font)

        text_width = bbox[2] - bbox[0]

        text_height = bbox[3] - bbox[1]

 

        x, y = 10, 30

        if position == "左上角":

            x, y = 10, 30

        elif position == "右上角":

            x, y = width - text_width - 10, 30

        elif position == "左下角":

            x, y = 10, height - text_height - 10

        elif position == "右下角":

            x, y = width - text_width - 10, height - text_height - 10

        elif position == "中心位置":

            x, y = (width - text_width) // 2, (height - text_height) // 2

 

        color = (self.watermark_color.red(), self.watermark_color.green(), self.watermark_color.blue())

        draw.text((x, y), text, font=font, fill=color)

 

        return cv2.cvtColor(np.array(pil_image), cv2.COLOR_RGB2BGR)

 

    def get_current_time(self):

        return time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())

 

 

class WatermarkApp(QWidget):

    def __init__(self):

        super().__init__()

 

        self.setWindowTitle("视频水印批量添加软件")

        self.setGeometry(300, 300, 650, 400)

 

        self.input_dir = ""

        self.output_dir = ""

        self.watermark_text = ""

        self.watermark_position = "center"

        self.watermark_color = QColor(255, 255, 255)

        self.font_size = 30

 

        self.thread_pool = QThreadPool()

 

        self.initUI()

 

    def initUI(self):

        main_layout = QHBoxLayout()

        left_layout = QVBoxLayout()

 

        self.setStyleSheet("background-color: #F5F5F5;")

 

        self.input_button = QPushButton("选择视频输入目录")

        self.input_button.setStyleSheet("background-color: #4CAF50; color: white; font-size: 14px; padding: 5px;")

        self.input_button.clicked.connect(self.select_input_directory)

        left_layout.addWidget(self.input_button)

 

        self.output_button = QPushButton("选择视频输出目录")

        self.output_button.setStyleSheet("background-color: #4CAF50; color: white; font-size: 14px; padding: 5px;")

        self.output_button.clicked.connect(self.select_output_directory)

        left_layout.addWidget(self.output_button)

 

        watermark_layout = QHBoxLayout()

 

        self.watermark_label = QLabel("水印文本:")

        self.watermark_label.setStyleSheet("font-size: 14px; color: #333333;")

        watermark_layout.addWidget(self.watermark_label)

 

        self.watermark_input = QLineEdit(self)

        self.watermark_input.setFont(QFont("Arial", 10))

        self.watermark_input.setStyleSheet("padding: 5px; border-radius: 5px; border: 1px solid #ccc;")

        self.watermark_input.textChanged.connect(self.update_watermark_text)

        watermark_layout.addWidget(self.watermark_input)

 

        left_layout.addLayout(watermark_layout)

 

        self.color_button = QPushButton("选择字体颜色")

        self.color_button.setStyleSheet("background-color: #4CAF50; color: white; font-size: 14px; padding: 5px;")

        self.color_button.clicked.connect(self.select_color)

        left_layout.addWidget(self.color_button)

 

        font_size_layout = QHBoxLayout()

 

        self.font_size_label = QLabel("选择字号大小:")

        self.font_size_label.setStyleSheet("font-size: 14px; color: #333333;")

        font_size_layout.addWidget(self.font_size_label)

 

        self.font_size_combo = QComboBox(self)

        self.font_size_combo.addItem("20")

        self.font_size_combo.addItem("30")

        self.font_size_combo.addItem("40")

        self.font_size_combo.addItem("50")

        self.font_size_combo.addItem("60")

        self.font_size_combo.addItem("70")

        self.font_size_combo.addItem("80")

        self.font_size_combo.addItem("90")

        self.font_size_combo.addItem("100")

        self.font_size_combo.setStyleSheet("padding: 5px; border-radius: 5px; border: 1px solid #ccc;")

        self.font_size_combo.currentTextChanged.connect(self.update_font_size)

        font_size_layout.addWidget(self.font_size_combo)

 

        left_layout.addLayout(font_size_layout)

 

        position_layout = QHBoxLayout()

        self.position_label = QLabel("选择水印位置:")

        self.position_label.setStyleSheet("font-size: 14px; color: #333333;")

        self.position_combo = QComboBox(self)

        self.position_combo.addItem("左上角")

        self.position_combo.addItem("右上角")

        self.position_combo.addItem("左下角")

        self.position_combo.addItem("右下角")

        self.position_combo.addItem("中心位置")

        self.position_combo.setStyleSheet("padding: 5px; border-radius: 5px; border: 1px solid #ccc;")

        self.position_combo.currentTextChanged.connect(self.update_watermark_position)

 

        position_layout.addWidget(self.position_label)

        position_layout.addWidget(self.position_combo)

        left_layout.addLayout(position_layout)

 

        self.process_button = QPushButton("添加水印并保存视频")

        self.process_button.setStyleSheet("background-color: #FF5722; color: white; font-size: 14px; padding: 10px;")

        self.process_button.clicked.connect(self.add_watermark)

        left_layout.addWidget(self.process_button)

 

        self.progress_bar = QProgressBar(self)

        self.progress_bar.setRange(0, 100)

        self.progress_bar.setValue(0)

        self.progress_bar.setTextVisible(True)

        self.progress_bar.setStyleSheet("height: 20px; background-color: #ddd;")

        left_layout.addWidget(self.progress_bar)

 

        self.log_browser = QTextBrowser(self)

        self.log_browser.setStyleSheet("background-color: #F5F5F5; border: 1px solid #ccc; padding: 5px;")

        self.log_browser.setFont(QFont("Arial", 10))

        main_layout.addLayout(left_layout)

        main_layout.addWidget(self.log_browser)

 

        self.setLayout(main_layout)

 

    def select_input_directory(self):

        self.input_dir = QFileDialog.getExistingDirectory(self, "选择输入目录")

        self.log_browser.append(f"[<font color='red'>{self.get_current_time()}</font>] 选择的输入目录: {self.input_dir}")

 

    def select_output_directory(self):

        self.output_dir = QFileDialog.getExistingDirectory(self, "选择输出目录")

        self.log_browser.append(f"[<font color='red'>{self.get_current_time()}</font>] 选择的输出目录: {self.output_dir}")

 

    def update_watermark_text(self):

        self.watermark_text = self.watermark_input.text()

 

    def update_watermark_position(self):

        self.watermark_position = self.position_combo.currentText()

 

    def update_font_size(self):

        self.font_size = int(self.font_size_combo.currentText())

 

    def select_color(self):

        color = QColorDialog.getColor(self.watermark_color, self, "选择字体颜色")

        if color.isValid():

            self.watermark_color = color

            self.log_browser.append(f"[<font color='red'>{self.get_current_time()}</font>] 已选择水印字体颜色: {self.watermark_color.name()}")

 

    def add_watermark(self):

        if not self.input_dir or not self.output_dir or not self.watermark_text:

            self.log_browser.append(f"[<font color='red'>{self.get_current_time()}</font>] 错误: 请检查输入目录、输出目录和水印文本")

            return

 

        video_files = [f for f in os.listdir(self.input_dir) if f.endswith(('.mp4', '.avi', '.mov', '.mkv'))]

        for video_file in video_files:

            # 创建WatermarkWorker实例

            worker = WatermarkWorker(self.input_dir, self.output_dir, self.watermark_text, self.watermark_position,

                                     self.watermark_color, self.font_size, video_file)

            # 连接信号

            worker.update_log_signal.connect(self.log_browser.append)

            worker.update_progress_signal.connect(self.progress_bar.setValue)

            worker.processing_complete_signal.connect(self.show_completion_message)

 

            # 启动处理

            worker.add_watermark()

 

    def show_completion_message(self):

        QMessageBox.information(self, "处理完成", "所有视频水印添加完毕!", QMessageBox.Ok)

 

    def get_current_time(self):

        return time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())

 

if __name__ == '__main__':

    app = QApplication([])

    window = WatermarkApp()

    window.show()

    app.exec_()

5. 总结

这款视频水印批量添加软件通过PyQt5实现了一个简洁且功能强大的图形用户界面,支持对多个视频文件进行水印添加。用户可以轻松自定义水印的各项参数,程序在处理过程中提供实时进度条和日志显示,确保用户能够清晰了解每个视频的处理状态。该工具特别适合需要批量处理视频并添加水印的用户,提供了便捷且高效的视频编辑功能


版权声明 : 本文内容来源于互联网或用户自行发布贡献,该文观点仅代表原作者本人。本站仅提供信息存储空间服务和不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权, 违法违规的内容, 请发送邮件至2530232025#qq.cn(#换@)举报,一经查实,本站将立刻删除。
原文链接 :
相关文章
  • Python实现批量添加视频文本水印
    这个是一个基于PyQt5开发的视频水印批量添加工具,旨在为多个视频文件添加文本水印。用户可以自定义水印的文本内容、字体颜色、字号大
  • 在不同系统间迁移Python程序的方法
    在开发 Python 项目时,我们常常会遇到需要将在 Windows 系统上编写的程序迁移到 Linux 服务器上运行的情况,尤其是当服务器环境存在差异(
  • Python+PyQt手搓一个文件浏览器

    Python+PyQt手搓一个文件浏览器
    一、效果展示 二、界面设计 该界面通过Qt Designer设计 ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
  • Python实现将PDF文件拆分任意页数介绍

    Python实现将PDF文件拆分任意页数介绍
    PyMuPDF,简称fitz,是一个轻量级的Python库,它基于MuPDF的C++库,提供了丰富的功能,包括但不限于PDF的读取、编辑、转换和渲染。Fitz作为Py
  • 20个实用的Python Excel自动化脚本介绍
    在数据处理和分析的过程中,Excel文件是我们日常工作中常见的格式。通过Python,我们可以实现对Excel文件的各种自动化操作,提高工作效率
  • Python实现移动指定图片到指定目录

    Python实现移动指定图片到指定目录
    前阵子,拍了200张照片,然后挑了20张找人精修下,今天修完发来给我,然后我先对比一下和原图的效果差异,以便做验收。由于前期挑出来
  • 使用Python IDLE进行Debug调试的图文介绍

    使用Python IDLE进行Debug调试的图文介绍
    1.首先以我的Python版本为例为大家讲解,我的版本是Python 3.7,版本问题对使用情况影响不大。 2.接着我们可以通过新建文件夹来输入我们的
  • 树莓派启动python的实现方法介绍

    树莓派启动python的实现方法介绍
    树莓派运行Python程序的方法: 一、RaspBerry系统设置 1、首先在开发板没有通电情况下,连接硬件,以及项目中用到传感器。比如当前项目需
  • Python给Excel写入数据的四种方法介绍
    Python 在数据处理领域应用广泛,其中与 Excel 文件的交互是常见需求之一。 本文将介绍四种使用 Python 给Excel 文件写入数据的方法,并结合生
  • 用Python编写一个MP3分割工具

    用Python编写一个MP3分割工具
    最终效果图 代码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
  • 本站所有内容来源于互联网或用户自行发布,本站仅提供信息存储空间服务,不拥有版权,不承担法律责任。如有侵犯您的权益,请您联系站长处理!
  • Copyright © 2017-2022 F11.CN All Rights Reserved. F11站长开发者网 版权所有 | 苏ICP备2022031554号-1 | 51LA统计