当前位置: 首页 > article >正文

使用 Python 制作 GIF 动图,并打包为 EXE 可执行程序

文章目录

  • 成品百度网盘下载
  • 🎬 使用 Python 制作 GIF 动图,并打包为 EXE 可执行程序(含图形界面)
  • 🧰 环境准备
  • 💻 功能预览
  • 🧑‍💻 完整代码(图形界面 + 功能)
  • 如何打包成 Windows 可执行程序(`.exe`)
    • 安装命令
    • 打包命令
  • 小贴士与拓展建议
  • ✅ 总结


成品百度网盘下载

百度网盘下载


🎬 使用 Python 制作 GIF 动图,并打包为 EXE 可执行程序(含图形界面)

在工作或个人项目中,常常会遇到需要将多张图片合成 GIF 动图的需求,同时添加版权水印保护作品。本文分享一个使用 Python 和 Pillow 库实现的 GIF 生成工具,配备简单的 Tkinter 图形界面,支持:

  • 批量上传图片,合成 GIF 动图
  • 固定文字水印自动添加
  • 可选图片水印(Logo)叠加
  • 一键生成,操作简单
  • 使用 PyInstaller 打包为 Windows 独立 EXE

无论你是 Python 初学者,还是想快速做一个实用小工具,这篇文章都会帮你搞定。


🧰 环境准备

  • Python 3.6+

  • Pillow:图像处理库,安装命令:

    pip install pillow
    
  • Tkinter:Python 内置图形界面库(Windows 下默认包含)

  • PyInstaller:后续将介绍如何打包


💻 功能预览

功能说明
多图片上传支持多选 PNG/JPG/JPEG/BMP 等常见格式
GIF 动画生成支持循环播放,帧间隔可自定义
简洁图形界面按钮操作:选择图片、生成 GIF
一键生成直接点击按钮即可生成
EXE 打包使用 PyInstaller 一键打包,免 Python 环境

🧑‍💻 完整代码(图形界面 + 功能)

gif_creator.py

import tkinter as tk
from tkinter import filedialog, messagebox, ttk
from PIL import Image, ImageTk
import os
import threading
import webbrowserclass GifMakerApp:def __init__(self, root):self.root = rootself.root.title("GIF 动图生成器")self.image_paths = []self.build_ui()def build_ui(self):# 图片列表框self.listbox = tk.Listbox(self.root, selectmode=tk.SINGLE, width=50, height=8)self.listbox.grid(row=0, column=0, columnspan=3, padx=10, pady=5)# 上移/下移按钮tk.Button(self.root, text="↑ 上移", command=self.move_up).grid(row=1, column=0, sticky="ew", padx=10)tk.Button(self.root, text="↓ 下移", command=self.move_down).grid(row=1, column=1, sticky="ew", padx=10)# 选择图片tk.Button(self.root, text="选择图片", command=self.select_images).grid(row=2, column=0, columnspan=2, pady=5)# 帧间隔时间tk.Label(self.root, text="帧间隔 (ms):").grid(row=3, column=0, sticky="e")self.duration_var = tk.IntVar(value=1000)tk.Entry(self.root, textvariable=self.duration_var, width=8).grid(row=3, column=1, sticky="w")# 选择保存路径tk.Button(self.root, text="保存路径", command=self.choose_output_path).grid(row=4, column=0, pady=5)self.output_path_var = tk.StringVar(value="output.gif")tk.Entry(self.root, textvariable=self.output_path_var, width=30).grid(row=4, column=1)# 进度条self.progress = ttk.Progressbar(self.root, orient="horizontal", length=300, mode="determinate")self.progress.grid(row=5, column=0, columnspan=3, pady=5)# 生成按钮tk.Button(self.root, text="生成 GIF", command=self.generate_gif_thread).grid(row=6, column=0, columnspan=3, pady=10)def select_images(self):file_paths = filedialog.askopenfilenames(title="选择多张图片",filetypes=[("图片文件", "*.png *.jpg *.jpeg *.bmp")])if file_paths:self.image_paths = list(file_paths)self.refresh_listbox()def refresh_listbox(self):self.listbox.delete(0, tk.END)for path in self.image_paths:self.listbox.insert(tk.END, os.path.basename(path))def move_up(self):index = self.listbox.curselection()if not index or index[0] == 0:returnidx = index[0]self.image_paths[idx-1], self.image_paths[idx] = self.image_paths[idx], self.image_paths[idx-1]self.refresh_listbox()self.listbox.select_set(idx-1)def move_down(self):index = self.listbox.curselection()if not index or index[0] == len(self.image_paths) - 1:returnidx = index[0]self.image_paths[idx+1], self.image_paths[idx] = self.image_paths[idx], self.image_paths[idx+1]self.refresh_listbox()self.listbox.select_set(idx+1)def choose_output_path(self):path = filedialog.asksaveasfilename(defaultextension=".gif",filetypes=[("GIF 文件", "*.gif")],title="选择 GIF 保存路径")if path:self.output_path_var.set(path)def generate_gif_thread(self):t = threading.Thread(target=self.generate_gif)t.start()def generate_gif(self):if not self.image_paths:messagebox.showwarning("未选择图片", "请先选择图片!")returntry:duration = int(self.duration_var.get())except ValueError:messagebox.showerror("无效间隔", "请输入合法的帧间隔(整数)")returnoutput_path = self.output_path_var.get().strip()if not output_path:messagebox.showerror("路径错误", "请输入有效的保存路径")returntry:frames = []self.progress["maximum"] = len(self.image_paths)self.progress["value"] = 0from PIL import ImageFont, ImageDraw# ...在循环中每次读取图片时for idx, path in enumerate(self.image_paths):img = Image.open(path).convert("RGBA")if idx == 0:w, h = img.sizeelse:img = img.resize((w, h))# 添加水印draw = ImageDraw.Draw(img)text = "@ CSDN博主XMYX-0"font_size = 50try:# Windows 通用字体路径(可自定义)# font = ImageFont.truetype("arial.ttf", font_size)font = ImageFont.truetype("C:/Windows/Fonts/simhei.ttf", font_size)except:font = ImageFont.load_default()bbox = draw.textbbox((0, 0), text, font=font)text_width = bbox[2] - bbox[0]text_height = bbox[3] - bbox[1]position = (w - text_width - 10, h - text_height - 10)  # 右下角draw.text(position, text, font=font, fill=(255, 0, 0, 128))  # 半透明红色水印frames.append(img)self.progress["value"] += 1self.root.update_idletasks()frames[0].save(output_path,save_all=True,append_images=frames[1:],duration=duration,loop=0)messagebox.showinfo("成功", f"GIF 已生成:\n{output_path}")webbrowser.open(output_path)except Exception as e:messagebox.showerror("错误", f"生成失败:\n{str(e)}")if __name__ == "__main__":root = tk.Tk()app = GifMakerApp(root)root.mainloop()

如何打包成 Windows 可执行程序(.exe

我们可以使用 PyInstaller 进行打包:

安装命令

pip install pyinstaller

打包命令

pyinstaller --noconsole --onefile --icon=app.ico gif_creator.py
参数说明
--noconsole不显示黑色终端窗口(适用于 GUI 程序)
--onefile打包为一个独立 .exe 文件
--icon=app.ico自定义图标(可选)

生成后可在 dist/ 目录找到 gif_creator.exe,可直接发送给他人使用,无需安装 Python。


小贴士与拓展建议

  • 字体问题:如果打包后字体显示异常,建议把字体文件放到项目里,使用绝对路径加载。
  • 水印透明度:可在代码中调整 (255, 0, 0, 128) 中最后的 128 控制透明度,范围 0~255。
  • 图片大小限制:上传图片尺寸过大时,合成 GIF 文件会很大,建议做图片缩放。
  • 帧间隔调整duration=1000 单位为毫秒,可根据需求调整动画速度。

✅ 总结

本项目展示了如何使用 Python 构建一个实用的 GIF 动图生成工具,并加入水印功能,最终打包成 Windows 可执行文件,真正做到“一键使用、无需安装”。

http://www.lryc.cn/news/2398666.html

相关文章:

  • HarmonyOS Next 弹窗系列教程(2)
  • Ubuntu 18.04 上源码安装 protobuf 3.7.0
  • 中小企业搭建网站选择虚拟主机还是云服务器?华为云有话说
  • 使用 HTML + JavaScript 在高德地图上实现物流轨迹跟踪系统
  • 19-项目部署(Linux)
  • html基础01:前端基础知识学习
  • Golang学习之旅
  • 【RoadRunner】自动驾驶模拟3D场景构建 | 软件简介与视角控制
  • 基于RK3576+FPGA芯片构建的CODESYS软PLC Linux实时系统方案,支持6T AI算力
  • 鸿蒙OSUniApp复杂表单与动态验证实践:打造高效的移动端表单解决方案#三方框架 #Uniapp
  • 在linux系统上搭建git服务器(ssh协议)
  • 适配器模式:让不兼容接口协同工作
  • NodeJS全栈开发面试题讲解——P12高性能场景题
  • DDP与FSDP:分布式训练技术全解析
  • 【Spring AI 1.0.0】Spring AI 1.0.0框架快速入门(1)——Chat Client API
  • 【笔记】在 MSYS2(MINGW64)中正确安装 Rust
  • 从汇编的角度揭秘C++引用,豁然开朗
  • 设计模式系列(07):建造者模式(Builder)
  • Maven 项目中集成数据库文档生成工具
  • 聊聊Tomato Architecture
  • 小白的进阶之路系列之十二----人工智能从初步到精通pytorch综合运用的讲解第五部分
  • Java并发编程实战 Day 6:Future与异步编程模型
  • .NET Core 中预防跨网站请求伪造 (XSRFCSRF) 攻击
  • MFC Resource.h 文件详解与修改指南
  • 2025年06月03日Github流行趋势
  • AI视频编码器(0.4.3) 调试训练bug——使用timm SoftTargetCrossEntropy时出现loss inf
  • 【数据分析】基于Cox模型的R语言实现生存分析与生物标志物风险评估
  • 使用nginx配置反向代理,负载均衡
  • 从 iPhone 备份照片: 保存iPhone图片的5种方法
  • Spring Ai 从Demo到搭建套壳项目(一)初识与实现与deepseek对话模式