python MP4视频转GIF动图

40 篇文章 2 订阅

一个相当于原视频三倍速的GIF动图
一个相当于原视频三倍速的GIF动图

引言

将MP4格式的视频转为GIF动图可以方便地向他人展示动画效果。GIF是网络上广泛使用的图像格式之一,几乎所有的网页浏览器和客户端都支持,其兼容性较好。比如可以直接插入到PPT中、或是在微信上发给别人、或者直接插入到CSDN博客中,但是MP4等视频格式的文件显然不行。

  • 常用的免费在线转换网站上不去了,好多其它网站需要注册,本作者亲自写一个方便日常使用。

当然,GIF也有其缺点,将MP4视频同帧率转为GIF,文件会变大,占用更多内存:

文心一言给出的理由:将MP4视频转换为GIF后,文件变大主要是因为GIF格式的编码方式和MP4不同。MP4文件内一般采用视频压缩的格式,例如h264,这种压缩方式利用时间上相邻两帧的相似性和人眼视觉上的冗余来做有损压缩,从而压缩率很高。而GIF格式则单独保留了每一帧图片,同时每张图片都是采用无损压缩的方式,因此GIF尺寸比较大。

一、转换代码

使用moviepy库,安装: pip install moviepy

英文文档:https://zulko.github.io/moviepy/ 推荐,方便Search
中文文档:http://doc.moviepy.com.cn/

from moviepy.editor import *
myClip = VideoFileClip("xxx.mp4")
myClip.write_gif("xxx.gif")

write_gif默认与原视频时常一样(只能更改帧速率,默认帧率也与原视频一样),如果想更改播放速度可使用speedx函数,如:

  • 放慢一半:
myClip.speedx(0.5).write_gif("xxx.gif")
  • 二倍速播放
myClip.speedx(2).write_gif("xxx.gif")

二、PyQt界面编写

2.1 效果展示

在这里插入图片描述
使用gif展示了一个将mp4转为gif动图的软件

2.2 源码

使用pyqt5-tool生成的ui界面,转成py后增加了mp4_to_gif函数,可直接运行

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

from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *


def mp4_to_gif():
    dialog = QFileDialog()
    dialog.setFileMode(QFileDialog.ExistingFile)
    dialog.setAcceptMode(QFileDialog.AcceptOpen)
    filename, _ = dialog.getOpenFileName(dialog, "Open file", "", "files (*.mp4);;(*.*)")
    print(filename.replace('.mp4', '.gif'))

    from moviepy.editor import VideoFileClip
    myClip = VideoFileClip(filename)
    myClip.speedx(3).write_gif(filename.replace('.mp4', '.gif'))
    pass


class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(321, 71)
        MainWindow.setMaximumSize(QtCore.QSize(321, 71))
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.pushButton = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton.setGeometry(QtCore.QRect(0, 0, 321, 71))
        font = QtGui.QFont()
        font.setFamily("微软雅黑")
        font.setPointSize(24)
        self.pushButton.setFont(font)
        self.pushButton.setObjectName("pushButton")
        MainWindow.setCentralWidget(self.centralwidget)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MP4_to_GIF"))
        self.pushButton.setText(_translate("MainWindow", "将MP4转为GIF"))

        # 按钮事件
        self.pushButton.clicked.connect(mp4_to_gif)


if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    MainWindow = QtWidgets.QMainWindow()
    ui = Ui_MainWindow()
    ui.setupUi(MainWindow)
    MainWindow.show()
    sys.exit(app.exec_())

  • 还有个小bug,filename为空,程序会奔溃

三、打包成可执行文件(.exe)

安装pyinstaller:pip install pyinstaller

  • 执行 pyinstaller -F -w main.py
    在这里插入图片描述
  • 打包生成100MB的exe文件… 结果如下:
    在这里插入图片描述
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
要实现一个Python聊天室中的GIF动图,你需要使用Python的Socket库来建立客户端和服务器之间的连接。然后,你需要使用Python的Pillow库来处理GIF动图,以便将其发送到其他客户端。 以下是一个简单的Python聊天室实现GIF动图的示例: ```python import socket import threading from PIL import Image, ImageSequence # 客户端类 class ChatClient: def __init__(self, host, port): self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.sock.connect((host, port)) self.gif_data = b'' # 接收消息 def receive(self): while True: data = self.sock.recv(1024).decode() if data.startswith('GIF'): # 如果接收到的数据是GIF动图 self.gif_data += data.encode() # 将数据添加到GIF缓冲区中 if data.endswith('\r\n'): # 如果数据以\r\n结尾,说明GIF动图接收完毕 self.show_gif() # 显示GIF动图 self.gif_data = b'' # 清空GIF缓冲区 else: print(data) # 发送消息 def send(self, msg): self.sock.send(msg.encode()) # 显示GIF动图 def show_gif(self): img = Image.open(BytesIO(self.gif_data)) for frame in ImageSequence.Iterator(img): frame.show() # 服务器类 class ChatServer: def __init__(self, host, port): self.clients = [] self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.sock.bind((host, port)) self.sock.listen(1) # 接收连接 def accept_clients(self): while True: client_sock, client_addr = self.sock.accept() client = ChatClient(client_sock) self.clients.append(client) client_thread = threading.Thread(target=self.handle_client, args=(client,)) client_thread.start() # 处理客户端 def handle_client(self, client): while True: data = client.sock.recv(1024).decode() if data: if data.startswith('/gif'): # 如果客户端发送的消息是GIF动图 self.send_gif(client, data) # 将GIF动图广播给其他客户端 else: self.broadcast(client, data) # 广播消息给其他客户端 # 广播消息 def broadcast(self, client, msg): for c in self.clients: if c != client: c.sock.send(msg.encode()) # 广播GIF动图 def send_gif(self, client, data): for c in self.clients: if c != client: c.sock.send(data.encode()) # 主函数 if __name__ == '__main__': server = ChatServer('localhost', 9999) server_thread = threading.Thread(target=server.accept_clients) server_thread.start() while True: name = input('Enter your name: ') if name: break client = ChatClient('localhost', 9999) receive_thread = threading.Thread(target=client.receive) receive_thread.start() while True: msg = input() if msg.startswith('/gif'): # 如果发送的消息是GIF动图 with open('animated.gif', 'rb') as f: gif_data = f.read() client.send(gif_data) # 发送GIF动图数据 else: client.send(f'{name}: {msg}') ``` 这个示例中,客户端和服务器之间使用Socket库建立连接。当客户端收到GIF动图时,它会将数据添加到GIF缓冲区中,直到接收完毕。当接收完毕后,它会使用Pillow库将GIF动图显示在屏幕上。当客户端发送GIF动图时,它会将GIF动图数据发送到服务器,并广播给其他客户端。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大米粥哥哥

感谢认可!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值