python实现 mp4转gif文件
安装库:
bash
pip install opencv-python imageio
实现python代码如下:
bash
import cv2
import imageio
import numpy as np
import argparse
import os
def mp4_to_gif(mp4_path, gif_path=None, fps=None, scale=1.0, start=0, duration=None):
"""
mp4 -> gif
:param mp4_path: 输入视频
:param gif_path: 输出路径,None 则同目录同名
:param fps: 输出帧率,None 则与视频一致
:param scale: 缩放因子,1.0 原尺寸,0.5 一半
:param start: 起始时间(秒)
:param duration: 截取时长(秒),None 表示到结尾
"""
gif_path = gif_path or os.path.splitext(mp4_path)[0] + '.gif'
cap = cv2.VideoCapture(mp4_path)
vid_fps = cap.get(cv2.CAP_PROP_FPS)
total_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
w = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
h = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
# 计算起止帧
start_frame = int(start * vid_fps)
if duration:
end_frame = start_frame + int(duration * vid_fps)
else:
end_frame = total_frames
end_frame = min(end_frame, total_frames)
# 目标帧率
out_fps = fps or vid_fps
frames = []
for idx in range(start_frame, end_frame):
cap.set(cv2.CAP_PROP_POS_FRAMES, idx)
ret, frame = cap.read()
if not ret:
break
# BGR->RGB
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
# 缩放
if scale != 1.0:
frame = cv2.resize(frame, (int(w*scale), int(h*scale)),
interpolation=cv2.INTER_AREA)
frames.append(frame)
cap.release()
if not frames:
raise ValueError("未读取到任何帧,请检查截取区间")
# 写 gif
imageio.mimsave(gif_path, frames, fps=out_fps)
print(f"gif 已保存 -> {gif_path} 共 {len(frames)} 帧 fps={out_fps}")
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument("mp4", help="输入 mp4 文件")
parser.add_argument("-o", "--output", help="输出 gif 路径")
parser.add_argument("--fps", type=float, help="输出帧率")
parser.add_argument("--scale", type=float, default=0.5, help="缩放因子,默认 0.5")
parser.add_argument("--start", type=float, default=0, help="起始时间(秒)")
parser.add_argument("--duration", type=float, help="截取时长(秒)")
args = parser.parse_args()
mp4_to_gif(args.mp4, args.output, args.fps, args.scale,
args.start, args.duration)
实现指令:
bash
python mp42gif.py demo.mp4 --scale 0.4 --fps 10 --start 5 --duration 3
实现示例效果如下:

