最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Python實現(xiàn)批量添加視頻文本水印

 更新時間:2025年02月14日 15:26:24   作者:探客白澤  
這篇文章主要為大家詳細介紹了如何基于PyQt5開發(fā)一個視頻水印批量添加工具,旨在為多個視頻文件添加文本水印,感興趣的小伙伴可以參考一下

1. 簡介

這個是一個基于PyQt5開發(fā)的視頻水印批量添加工具,旨在為多個視頻文件添加文本水印。用戶可以自定義水印的文本內(nèi)容、字體顏色、字號大小以及位置(如左上角、右上角、左下角、右下角和中心位置)。程序支持常見的視頻格式,如MP4、AVI、MOV和MKV,并能夠批量處理視頻文件,輸出帶有水印的新視頻。

2.功能介紹

選擇輸入和輸出目錄: 用戶可以通過文件對話框選擇視頻文件的輸入目錄和保存帶水印視頻的輸出目錄。

自定義水印文本: 用戶可以在輸入框中填寫水印的文本內(nèi)容,水印會被添加到視頻上。

自定義水印位置: 水印可以選擇顯示在視頻的不同位置,包括左上角、右上角、左下角、右下角和中心。

自定義水印字體顏色: 用戶可以通過顏色選擇器來選擇水印文本的顏色,支持豐富的顏色選擇。

選擇水印字體大小: 提供了多個字體大小選項(20到100),用戶可以根據(jù)需要選擇合適的字號。

批量處理視頻: 程序會遍歷輸入目錄中的所有視頻文件,逐一為其添加水印并保存到輸出目錄。支持的視頻格式包括MP4、AVI、MOV、MKV等。

進度條與日志顯示: 程序提供實時進度條,顯示當前視頻處理的進度。同時,日志框顯示詳細的處理信息和錯誤提示,幫助用戶實時了解處理狀態(tài)。

處理完成提示: 所有視頻處理完成后,會彈出提示框,告知用戶所有視頻水印已成功添加。

3. 運行效果

4.相關(guān)源碼

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:
            # 創(chuàng)建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. 總結(jié)

這款視頻水印批量添加軟件通過PyQt5實現(xiàn)了一個簡潔且功能強大的圖形用戶界面,支持對多個視頻文件進行水印添加。用戶可以輕松自定義水印的各項參數(shù),程序在處理過程中提供實時進度條和日志顯示,確保用戶能夠清晰了解每個視頻的處理狀態(tài)。該工具特別適合需要批量處理視頻并添加水印的用戶,提供了便捷且高效的視頻編輯功能

到此這篇關(guān)于Python實現(xiàn)批量添加視頻文本水印的文章就介紹到這了,更多相關(guān)Python視頻添加水印內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • python中的斷言(assert語句)

    python中的斷言(assert語句)

    這篇文章主要介紹了python中的斷言(assert語句),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-05-05
  • 實例解析Python設(shè)計模式編程之橋接模式的運用

    實例解析Python設(shè)計模式編程之橋接模式的運用

    這篇文章主要介紹了Python設(shè)計模式編程之橋接模式的運用,橋接模式主張把抽象部分與它的實現(xiàn)部分分離,需要的朋友可以參考下
    2016-03-03
  • 在django view中給form傳入?yún)?shù)的例子

    在django view中給form傳入?yún)?shù)的例子

    今天小編就為大家分享一篇在django view中給form傳入?yún)?shù)的例子,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-07-07
  • python利用PyQt5設(shè)計鼠標顯示形狀

    python利用PyQt5設(shè)計鼠標顯示形狀

    不知道大家有沒有發(fā)現(xiàn),我們在網(wǎng)頁移動鼠標時,不同的網(wǎng)頁會有不同的鼠標移動特效,通過移動鼠標,會形成類似蜘蛛網(wǎng)等等的特效,本文將用PyQt5實現(xiàn)這一特效,需要的可以參考一下
    2024-07-07
  • 關(guān)于Python Socket編程的要點詳解

    關(guān)于Python Socket編程的要點詳解

    Socket是網(wǎng)絡(luò)編程的一個抽象概念,通常我們用一個Socket表示“打開了一個網(wǎng)絡(luò)鏈接”,而打開一個Socket需要知道目標計算機的IP地址和端口號,再指定協(xié)議類型即可,這篇文章主要給大家介紹了關(guān)于Python Socket編程的相關(guān)資料,需要的朋友可以參考下
    2021-08-08
  • 根據(jù)tensor的名字獲取變量的值方式

    根據(jù)tensor的名字獲取變量的值方式

    今天小編就為大家分享一篇根據(jù)tensor的名字獲取變量的值方式,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-01-01
  • Python 命令行參數(shù)sys.argv

    Python 命令行參數(shù)sys.argv

    命令行參數(shù)是通過sys.argv[]來獲取的,sys.argv[0]是代碼文件本身的路徑,因此參數(shù)是從1開始的。比如設(shè)置參數(shù)為: spe
    2008-09-09
  • Django中URL的參數(shù)傳遞的實現(xiàn)

    Django中URL的參數(shù)傳遞的實現(xiàn)

    這篇文章主要介紹了Django中URL的參數(shù)傳遞的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-08-08
  • Python根據(jù)Windows窗口截圖的幾種實現(xiàn)方法

    Python根據(jù)Windows窗口截圖的幾種實現(xiàn)方法

    文章介紹了Windows下Python截圖的四種方法:PIL庫(簡單快速)、win32gui(精準控制窗口)、mss庫(跨平臺高性能)及win32API處理隱藏窗口,需注意窗口標題匹配、權(quán)限問題和DPI縮放調(diào)整,推薦常規(guī)截圖用PIL或mss,需精準控制時使用win32API,需要的朋友可以參考下
    2025-10-10
  • 使用python3.5仿微軟記事本notepad

    使用python3.5仿微軟記事本notepad

    這篇文章主要為大家詳細介紹了使用python3.5仿微軟記事本notepad的相關(guān)資料,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-06-06

最新評論

花莲县| 顺义区| 稻城县| 双牌县| 普陀区| 上林县| 吐鲁番市| 延安市| 都安| 界首市| 延庆县| 抚松县| 莲花县| 甘孜县| 达日县| 无极县| 诏安县| 灵山县| 巴中市| 区。| 来宾市| 中西区| 海淀区| 汤原县| 乐安县| 尤溪县| 甘孜县| 临桂县| 沈丘县| 宜都市| 泰兴市| 淮阳县| 明光市| 宁城县| 宁夏| 蓬莱市| 日照市| 绥中县| 襄垣县| 神木县| 遵义市|