通过Python将MP4视频转换为GIF动画

目录
  • 运行环境
  • 如何从 MP4 视频中提取帧
  • 将帧变成 GIF
  • 创建 MP4 到 GIF GUI

Python 可用于读取常见的 MP4 视频格式并将其转换为 GIF动画。当然,如果你愿意,你可以使用预先构建的软件,但是自己做很有趣(并且是一种很好的学习体验)。

在本教程中,你将学习以下内容:

  • 如何从 MP4 视频中提取帧
  • 将帧转换为 GIF
  • 创建 MP4 到 GIF GUI

让我们开始吧!

运行环境

你需要安装 OpenCV 绑定以读取 MP4 文件并将视频中的每一帧转换为 JPG 文件。安装教程:

python3 -m pip install opencv-python

你还需要Pillow从你从视频中提取的 JPG 创建动画 GIF。也可以用pip安装:

python3 -m pip install Pillow

要创建 GUI,我这里会用到PySimpleGUI。要安装该库,请使用以下命令:

python3 -m pip install PySimpleGUI

如果你使用的是 Anaconda,则包含 opencv-python 和 Pillow。你只需要单独安装 PySimpleGUI。

如何从 MP4 视频中提取帧

从 MP4 视频中提取帧的第一步是找到要转换为 GIF 的视频。

要从上面的视频中提取单个帧,你需要编写一些 Python。创建一个新文件并将其命名为mp4_converter.py。然后输入以下代码:

import cv2

def convert_mp4_to_jpgs(path):
    video_capture = cv2.VideoCapture(path)
    still_reading, image = video_capture.read()
    frame_count = 0
    while still_reading:
        cv2.imwrite(f"output/frame_{frame_count:03d}.jpg", image)

        # read next image
        still_reading, image = video_capture.read()
        frame_count += 1

if __name__ == "__main__":
    convert_mp4_to_jpgs("flask_demo.mp4")

此代码采用 MP4 视频文件的路径。然后使用cv2.VideoCapture(path)打开视频。你可以使用此方法通读整个视频并提取每一帧。提取帧时,可以使用cv2.imwrite()将其写出。

当你运行这段代码时,你会发现这个 7 秒的视频产生了 235 帧!

现在准备好拍摄这些帧并将它们转换为动画 GIF。

将帧变成 GIF

该过程的下一步是将使用 OpenCV 从 MP4 文件中提取的帧转换为动画 GIF。

这就是 Pillow 包的用武之地。你可以使用它来接收图像文件夹并创建你的 GIF。打开一个新文件并将其命名为gif_maker.py。然后输入以下代码:

import glob

from PIL import Image

def make_gif(frame_folder):
    images = glob.glob(f"{frame_folder}/*.jpg")
    images.sort()
    frames = [Image.open(image) for image in images]
    frame_one = frames[0]
    frame_one.save("flask_demo.gif", format="GIF", append_images=frames,
                   save_all=True, duration=50, loop=0)

if __name__ == "__main__":
    make_gif("output")

在这里,你使用 Python 的glob模块在输出文件夹中搜索 JPG 文件。然后对帧进行排序,使它们按正确的顺序排列。最后,你将它们保存为 GIF.

创建 MP4 到 GIF GUI

PySimpleGUI 是一个跨平台的 GUI 框架,可在 Linux、Mac 和 Windows 上运行。它封装了 Tkinter、wxPython、PyQt 和其他几个 GUI 工具包,为它们提供了一个通用接口。

在本文前面安装 PySimpleGUI 时,你安装了包装 Tkinter 的默认版本。

打开一个新的 Python 文件并将其命名为mp4_converter_gui.py。然后将此代码添加到你的文件中:

# mp4_converter_gui.py

import cv2
import glob
import os
import shutil
import PySimpleGUI as sg

from PIL import Image

file_types = [("MP4 (*.mp4)", "*.mp4"), ("All files (*.*)", "*.*")]

def convert_mp4_to_jpgs(path):
    video_capture = cv2.VideoCapture(path)
    still_reading, image = video_capture.read()
    frame_count = 0
    if os.path.exists("output"):
        # remove previous GIF frame files
        shutil.rmtree("output")
    try:
        os.mkdir("output")
    except IOError:
        sg.popup("Error occurred creating output folder")
        return

    while still_reading:
        cv2.imwrite(f"output/frame_{frame_count:05d}.jpg", image)

        # read next image
        still_reading, image = video_capture.read()
        frame_count += 1

def make_gif(gif_path, frame_folder="output"):
    images = glob.glob(f"{frame_folder}/*.jpg")
    images.sort()
    frames = [Image.open(image) for image in images]
    frame_one = frames[0]
    frame_one.save(gif_path, format="GIF", append_images=frames,
                   save_all=True, duration=50, loop=0)

def main():
    layout = [
        [
            sg.Text("MP4 File"),
            sg.Input(size=(25, 1), key="-FILENAME-", disabled=True),
            sg.FileBrowse(file_types=file_types),
        ],
        [
            sg.Text("GIF File Save Location"),
            sg.Input(size=(25, 1), key="-OUTPUTFILE-", disabled=True),
            sg.SaveAs(file_types=file_types),

        ],
        [sg.Button("Convert to GIF")],
    ]

    window = sg.Window("MP4 to GIF Converter", layout)

    while True:
        event, values = window.read()
        mp4_path = values["-FILENAME-"]
        gif_path = values["-OUTPUTFILE-"]
        if event == "Exit" or event == sg.WIN_CLOSED:
            break
        if event in ["Convert to GIF"]:
            if mp4_path and gif_path:
                convert_mp4_to_jpgs(mp4_path)
                make_gif(gif_path)
                sg.popup(f"GIF created: {gif_path}")

    window.close()

if __name__ == "__main__":
    main()

这是一段相当长的代码。我们来一段一段分析。

要开始,请查看导入部分:

# mp4_converter_gui.py

import cv2
import glob
import os
import shutil
import PySimpleGUI as sg

from PIL import Image

file_types = [("MP4 (*.mp4)", "*.mp4"), ("All files (*.*)", "*.*")]

在这里,你导入创建 GUI 应用程序所需的所有模块和包。这包括 OpenCV (cv2)、Pillow 的 Image clas 和 PySimpleGUI,以及许多 Python 自己的模块。

你还创建了一个变量来保存可以加载到 GUI 中的文件类型。这是一个元组列表。

现在是时候将注意力转向程序中的第一个函数:

def convert_mp4_to_jpgs(path):
    video_capture = cv2.VideoCapture(path)
    still_reading, image = video_capture.read()
    frame_count = 0
    if os.path.exists("output"):
        # remove previous GIF frame files
        shutil.rmtree("output")
    try:
        os.mkdir("output")
    except IOError:
        sg.popup("Error occurred creating output folder")
        return

    while still_reading:
        cv2.imwrite(f"output/frame_{frame_count:05d}.jpg", image)

        # read next image
        still_reading, image = video_capture.read()
        frame_count += 1

这是你之前创建的 MP4 转换器代码的修改版本。在这个版本中,你仍然使用VideoCapture()来读取 MP4 文件并将其转换为单独的帧。

但是,你还添加了一些额外的代码来删除“输出”文件夹(如果存在)。这可以防止你意外地将两个 MP4 文件合并到一个输出文件中,这会导致 GIF 混乱。

你还添加了一些代码来尝试在删除后创建“输出”文件夹。如果创建文件夹时出现错误,则会显示错误对话框。

其余代码与之前相同。

现在你已准备好查看下一个函数:

def make_gif(gif_path, frame_folder="output"):
    images = glob.glob(f"{frame_folder}/*.jpg")
    images.sort()
    frames = [Image.open(image) for image in images]
    frame_one = frames[0]
    frame_one.save(gif_path, format="GIF", append_images=frames,
                   save_all=True, duration=50, loop=0)

你可以使用make_gif()将帧文件夹转换为 GIF 文件。此代码与原始代码几乎相同,只是你传入 GIF 文件的路径以使其唯一。

最后一段代码是你的 GUI 代码:

def main():
    layout = [
        [
            sg.Text("MP4 File"),
            sg.Input(size=(25, 1), key="-FILENAME-", disabled=True),
            sg.FileBrowse(file_types=file_types),
        ],
        [
            sg.Text("GIF File Save Location"),
            sg.Input(size=(25, 1), key="-OUTPUTFILE-", disabled=True),
            sg.SaveAs(file_types=file_types),

        ],
        [sg.Button("Convert to GIF")],
    ]

    window = sg.Window("MP4 to GIF Converter", layout)

    while True:
        event, values = window.read()
        mp4_path = values["-FILENAME-"]
        gif_path = values["-OUTPUTFILE-"]
        if event == "Exit" or event == sg.WIN_CLOSED:
            break
        if event in ["Convert to GIF"]:
            if mp4_path and gif_path:
                convert_mp4_to_jpgs(mp4_path)
                make_gif(gif_path)
                sg.popup(f"GIF created: {gif_path}")

    window.close()

if __name__ == "__main__":
    main()

在 PySimpleGUI 中,当你想在用户界面中“布局”元素时,你可以将项目添加到 Python 列表中。对于此示例,你添加以下元素:

  • sg.Text - 此元素有两个实例。它们用作输入(文本框)的标签
  • sg.Input - 这个元素有两个实例,它是一个文本框类型的元素。一个保存 MP4 文件的位置,一个保存你要保存 GIF 的位置
  • sg.FileBrowse - 打开文件浏览对话框的按钮
  • sg.SaveAs - 打开文件另存为对话框的按钮
  • sg.Button - 一个可以做任何你想做的事情的按钮

接下来,你获取元素列表并将其传递给sg.Window,它表示包含所有其他元素的窗口。你的窗口还有一个退出按钮、一个最小化按钮和一个标题栏。

要启动 GUI 的事件循环,你需要创建一个 while 循环并从 Window 对象中读取数据。这允许你提取两个sg.Input()对象的值,其中包含 MP4 和 GIF 文件的路径。

当用户按下标记为“转换为 GIF”的按钮时,你会捕获该事件并调用convert_mp4_to_jpgs()和make_gif()。如果一切顺利,视频将被转换,你将看到一个弹出对话框,说明新创建的 GIF 的保存位置。

尝试运行此代码。你应该会看到如下内容:

现在你拥有了将 MP4 视频文件转换为 GIF 所需的所有内容。你可以采取多种不同的措施来改进你的代码。例如,你可以向代码中添加更多错误处理,以免意外覆盖 GIF。

你还可以添加一些新的 UI 元素来告诉你的代码调整各个帧的大小以帮助缩小 GIF。另一种选择是更改每个单独的 JPG 的压缩,这也将减小 GIF 的大小。

还有很多其他有趣的方法可以使这段代码变得更好。考虑一下,你一定会自己想出一些新功能! 

到此这篇关于通过Python将MP4视频转换为GIF动画的文章就介绍到这了,更多相关Python视频转为GIF动画内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Python3视频转字符动画的实例代码

    Python3视频转字符动画,具体代码如下所示: # -*- coding:utf-8 -*- import json import os import subprocess from pathlib import Path from cv2 import cv2 import numpy as np from time import time import webbrowser play_chars_js = ''' let i = 0; window.setInterval(function

  • python游戏开发之视频转彩色字符动画

    本文实例为大家分享了python视频转彩色字符动画的具体代码,供大家参考,具体内容如下 一.效果 原图: 转换后: 效果可通过代码开头几行的参数调节 二.代码 开头几行代码,自己看着调整,把效果调到最佳就ok. 依赖库: pip install opencv-python pip install pygame 代码: import pygame import cv2 FONT_SIZE = 18 # 字体大小,可自行调整 WIN_SIZE = (1440, 1000) # 窗口大小,可自行调整

  • 三行代码使用Python将视频转Gif的方法示例

    目录 一.前言 二.教程 1. 安装必备库moviepy 2. 写入代码 3. 转换效果 4. GIF很大的解决方案 5. 截取视频长度转换 5. 指定转换后的图片大小(分辨率) 一.前言 很多网站提供视频转GIF的功能,但要么收费要么有广告 实际上我们通过python,几行代码就能够实现视频转gif 二.教程 1. 安装必备库moviepy pip install moviepy -i https://pypi.tuna.tsinghua.edu.cn/simple 2. 写入代码 from

  • python编程简单几行代码实现视频转换Gif示例

    目录 一.前言 二.教程 1. 安装必备库moviepy 2. 写入代码 3. 转换效果 4. GIF很大的解决方案 5. 截取视频长度转换 6. 指定转换后的图片大小(分辨率) 示例 一.前言 很多网站提供视频转GIF的功能,但要么收费要么有广告 实际上我们通过python,几行代码就能够实现视频转gif 二.教程 1. 安装必备库moviepy pip install moviepy -i https://pypi.tuna.tsinghua.edu.cn/simple 2. 写入代码 fr

  • 通过Python将MP4视频转换为GIF动画

    目录 运行环境 如何从 MP4 视频中提取帧 将帧变成 GIF 创建 MP4 到 GIF GUI Python 可用于读取常见的 MP4 视频格式并将其转换为 GIF动画.当然,如果你愿意,你可以使用预先构建的软件,但是自己做很有趣(并且是一种很好的学习体验). 在本教程中,你将学习以下内容: 如何从 MP4 视频中提取帧 将帧转换为 GIF 创建 MP4 到 GIF GUI 让我们开始吧! 运行环境 你需要安装 OpenCV 绑定以读取 MP4 文件并将视频中的每一帧转换为 JPG 文件.安装

  • Python解析m3u8拼接下载mp4视频文件的示例代码

    一.关于m3u8: m3u8是苹果公司推出一种视频播放标准,是m3u的一种,不过编码方式是utf-8,是一种文件检索格式,将视频切割成一小段一小段的ts格式的视频文件,然后存在服务器中(现在为了减少I/o访问次数,一般存在服务器的内存中),通过m3u8解析出来路径,然后去请求. 示例: #EXTM3U #EXT-X-TARGETDURATION:10 #EXTINF:9, http://data.video.iqiyi.com/videos/vts/20210301/69/b8/73ad4ef0

  • 基于Python实现合并多张图片转成mp4视频

    目录 前言 一.需要调入的模块 1.imageio模块 2.Image 模块 二.实现合并多张图片转成 mp4 视频 三.优化改进一下 总结 前言 随着现代科技飞速发展和人们提升视觉上体验,利用图片生成视频的方法,确实为工作或者提升生活体验感做了很多成功案例: 1.简单的幻灯片演示,如展示旅游照片.产品展示等: 2.改编图片动画,如口红试色.时尚大片中的效果: 3.制作日记式的视频内容,将一段长时间内的照片串在一起,如婚礼纪实.Baby成长记录等: 4.制作信息图表,如将各种数据图表整合在一起以

  • python将视频转换为全字符视频

    简介 如何简单的使用python来实现将一部视频转换为字符画视频的效果. 其实,大家都知道视频就是一帧一帧的图片构成的. 那么如今我们想要实现,将视频转换为字符视频,那么是不是可以认为只要将一部视频全部逐帧拆解成图片,然后采取和以前相同的将图片转换为字符画的算法即可.然后在将这些图片按照原先的视频的格式封装起来就可以了. 既然有了想法,那接下来,自然是开始实际开发了. 代码 以下是相关部分的代码: #-*- coding:utf-8 -*- import argparse import os i

  • 利用Python小工具实现3秒钟将视频转换为音频

    最近,有读者微信上私聊我,想让我写一篇视频批量转换成音频的文章,我答应了,周末宅家里把这个小工具做出来了. 这样,对于有些视频学习文件,我们可以批量转换成音频文件,学习方式更多样化了. 之前也用过 ffmpeg 处理视频文件.ffmpeg 这个程序处理视频是好用,但是有没有更轻便的呢?可以不下载这个程序吗?还真有,Python 里有 ffmpeg 相关的库:ffmpy3. ffmpy3 是 ffmpy 的一个分支,它是一个简单的 FFmpeg 命令行包装程序.ffmpy 实现了一个 Python

  • Python实现视频转换为字符画详解

    上次写了个华强买瓜字符视频的帖子,下面有人问如何保存,所以这次就写一个能将字符画视频保存下来的帖子,然而时不待我,华强纪元已经结束,现在是穿山甲的时代了. 首先读取视频,并转为字符.视频是从B站下载的,地址<激战江南>穿山甲名场面. 由于B站直接下载的视频为flv格式,而imageio并不支持,尽管可以用opencv来读取,但相比之下,用ffmepg转个码也不复杂,这样可以最大限度地利用华强买瓜的代码. 另外,视频素材过长不适合代码演示,所以从第2:10进行截取15s. 在命令行中输入 >

  • python opencv读mp4视频的实例

    如下所示: #获得视频的格式 videoCapture = cv2.VideoCapture('/home/lw/3661.mp4') #获得码率及尺寸 fps = videoCapture.get(cv2.CAP_PROP_FPS) size = (int(videoCapture.get(cv2.CAP_PROP_FRAME_WIDTH)), int(videoCapture.get(cv2.CAP_PROP_FRAME_HEIGHT))) fNUMS = videoCapture.get(

  • Python将视频转换为图片介绍

    目录 前言 代码展示 结果展示 总结 前言 代码让人头秃,可是我喜欢上了代码的逻辑感和代码解决问题的力量.(我要对这个专题的图片进行修改,缩小看和我导头像有点像QAQ) 代码展示 此段代码能够实现多个文件夹中多个视频片段的转换,代码的具体含义可以参考注释.具体操作为将此段代码复制粘贴到创建好的main.py文件,配置好第63行的源文件路径,然后运行. # 将四个文件夹中的多个视频文件转换为图片 import cv2 import os number_in_dir = [] # 可以去掉 def

  • python如何实现视频转代码视频

    本文实例为大家分享了python如何实现视频转代码视频的具体代码,供大家参考,具体内容如下 # -*- coding:utf-8 -*- #coding:utf-8 import argparse import os import cv2 import subprocess from cv2 import VideoWriter, VideoWriter_fourcc, imread, resize from PIL import Image, ImageFont, ImageDraw # 命令

  • Python使用Matplotlib实现雨点图动画效果的方法

    本文实例讲述了Python使用Matplotlib实现雨点图动画效果的方法.分享给大家供大家参考,具体如下: 关键点 win10安装ffmpeg animation函数使用 update函数 win10安装ffmpeg 因为最后要将动画图保存为.mp4格式,要用到ffmpeg,去官网下载,我az下载的是windows64bit static版本的,下载后解压到软件安装常用路径,并将ffmpeg路径添加到环境变量(这个方法在最后没用,但还是添加一下) animationa函数 准确来说是anima

随机推荐