from PIL import Image
import moviepy.editor as mp
import os
# 1. 定义函数 resize_frame,用于调整视频帧的大小
def resize_frame(frame, max_size=240):
img = Image.fromarray(frame)
img = img.resize((max_size, max_size), Image.Resampling.LANCZOS) # 使用 LANCZOS 采样进行高质量缩放
return img
# 2. 定义函数 resize_image,用于调整图片的大小
def resize_image(image_path, max_size=240):
with Image.open(image_path) as img:
img = img.resize((max_size, max_size), Image.Resampling.LANCZOS) # 使用 LANCZOS 采样进行高质量缩放
return img
# 3. 定义函数 video_to_gif,用于处理视频文件,将其转换为 GIF
def video_to_gif(video_path, max_size=240, num_frames=24):
clip = mp.VideoFileClip(video_path) # 加载视频文件
duration = clip.duration # 获取视频总时长
timestamps = [duration * i / num_frames for i in range(num_frames)] # 计算分割帧的时间点
frames = []
for t in timestamps:
frame = clip.get_frame(t) # 提取指定时间点的帧
resized_frame = resize_frame(frame, max_size) # 调整帧的大小
frames.append(resized_frame)
return frames
# 4. 定义函数 save_gif,用于将帧列表保存为 GIF 文件
def save_gif(frames, output_path):
frames[0].save(output_path, save_all=True, append_images=frames[1:], format='GIF', loop=0, duration=100, optimize=True)
# 5. 定义函数 get_unique_output_path,用于生成唯一的输出文件名
def get_unique_output_path(output_path):
base, ext = os.path.splitext(output_path)
counter = 1
new_output_path = output_path
while os.path.exists(new_output_path):
new_output_path = f"{base}_{counter}{ext}"
counter += 1
return new_output_path
# 6. 定义函数 convert_file,用于处理单个文件
def convert_file(file_path, output_dir, max_size=240):
ext = os.path.splitext(file_path)[1].lower() # 获取文件扩展名
output_file_name = os.path.splitext(os.path.basename(file_path))[0] + '.gif'
output_file_path = get_unique_output_path(os.path.join(output_dir, output_file_name))
if ext in ['.jpg', '.jpeg', '.png', '.bmp']:
img = resize_image(file_path, max_size) # 如果是图片文件,调用 resize_image 函数
img.save(output_file_path, format='GIF') # 保存为 GIF 文件
elif ext in ['.mp4', '.avi', '.mov', '.mkv']:
frames = video_to_gif(file_path, max_size) # 如果是视频文件,调用 video_to_gif 函数
save_gif(frames, output_file_path) # 保存为 GIF 文件
else:
print(f"Unsupported file type: {file_path}") # 不支持的文件类型提示
# 7. 定义函数 process_directory,用于处理目录中的所有文件
def process_directory(directory_path, output_dir, max_size=240):
if not os.path.exists(output_dir):
os.makedirs(output_dir) # 确保输出目录存在
for filename in os.listdir(directory_path):
file_path = os.path.join(directory_path, filename)
if os.path.isfile(file_path):
convert_file(file_path, output_dir, max_size) # 处理单个文件
# 8. 定义函数 convert_to_gif,根据输入的路径处理单个文件或目录
def convert_to_gif(input_path, output_path, max_size=240):
if not os.path.exists(output_path):
os.makedirs(output_path) # 确保输出目录存在
if os.path.isfile(input_path):
convert_file(input_path, output_path, max_size) # 如果是文件,直接转换
elif os.path.isdir(input_path):
process_directory(input_path, output_path, max_size) # 如果是目录,处理目录中的所有文件
else:
print(f"File or directory {input_path} does not exist.") # 文件或目录不存在提示
# 9. 示例使用:
input_path = "source" # 替换为你的图片或视频文件路径或目录路径
output_path = "output_directory" # 输出目录
convert_to_gif(input_path, output_path, max_size=240) # 调用转换函数
微信gif限制:大小控制1m范围