把一张静态图片变成GIF,本质上是解决一个问题:帧从哪里来。下面按「帧的来源」分成四条路线,每条都说明原理、关键参数和适用范围。
| 路线 | 帧的来源 | 帧之间是否一致 | 画面里的物体会不会动 |
|---|---|---|---|
| 一、裁剪拼帧 | 对原图做几何变换 | 完全一致 | 不会,只有镜头在动 |
| 二、序列帧切分 | 一次生成一张网格图,再切开 | 较一致 | 会 |
| 三、多帧生成模型 | 模型一次输出多帧GIF | 简单画面一致,复杂画面会抖 | 会 |
| 四、视频模型转码 | 先生成视频,再转GIF | 一致 | 会,动作最连贯 |
路线一:裁剪拼帧
不需要任何模型。思路是对原图做一组逐步收缩的裁剪,再统一缩放回第一帧的尺寸,得到推进效果。
裁剪框的计算:设原图宽W₀、高H₀,第i帧缩放系数为s(例如每帧缩小10%,s=0.9),保持原比例并以中心为锚点:
Wᵢ = W₀ × sⁱ
Hᵢ = H₀ × sⁱ
Xᵢ = (W₀ − Wᵢ) / 2
Yᵢ = (H₀ − Hᵢ) / 2
768×1024的图片,三帧的结果是:
| 帧 | X | Y | W | H |
|---|---|---|---|---|
| 1 | 0 | 0 | 768 | 1024 |
| 2 | 38 | 51 | 691 | 922 |
| 3 | 77 | 102 | 614 | 819 |
想做平移,就固定W和H,让X线性变化。
拼帧时注意三点:
- 输出尺寸以第一帧为准,后续帧缩放到同一尺寸,推进效果就来自这一步。
- 帧序列做成1、2、3、2,循环回到第一帧时位移最小,不会突兀。
- 帧间隔:慢推进用500毫秒左右;GIF的延时单位是1/100秒,低于20毫秒的值很多播放器会当成100毫秒处理。

路线二:序列帧切分
逐张生成每一帧,角色会一张一个样。更稳的做法是让图像模型一次画出一张网格图(sprite sheet),所有帧在同一次推理里生成,角色一致性好得多。
提示词里要写清楚三件事:帧数和网格(例如16帧、4×4)、每格里主体大小和位置不变、格子之间画细分割线:
Sprite sheet of a cute orange cat waving its paw, 16 frames of one smooth
animation loop arranged in a 4×4 grid. Same character, same size and same
position in every cell, plain white background, thin black divider lines
between cells, no text.

切分时,不能简单按图片宽高四等分,因为模型画的分割线位置不一定精确。可以这样找分割线:
- 把图片转成灰度,按列求每一列的平均亮度,按行求每一行的平均亮度。
- 分割线是又暗又细的连续区域,在亮度曲线上表现为窄而深的谷。
- 在预期位置(宽度的1/4、2/4、3/4)附近找谷底,得到实际分割线坐标。
- 按分割线切开,每块再向内裁掉几像素,去掉残留的线。
切片按从左到右、从上到下编号,就是帧的顺序。16帧、120毫秒一帧,正好约2秒一个循环:

分辨率的取舍:2048像素的网格图每帧512像素;1024像素的每帧256像素,做聊天表情已经够用。
路线三:多帧生成模型直接输出GIF
2026年11月,OpenAI的GPT Image 2.6加入了直接输出GIF的能力。相当于把路线二的「网格图+切分+拼帧」放进了模型内部,调用一次就拿到GIF。
常见的可控参数:
- 画面比例:1:1、4:3、3:4、16:9、9:16
- 帧数:2到16
- 时长:1、2、3、5秒
- 参考图:用自己的图片作为第一帧的依据
提示词只描述动作,不用再描述图片内容。四条经验:只写一个动作;写清楚怎么回到起始状态(then back to the start);写fixed camera固定镜头;背景越简单越好。
我们用同一组参数(1:1、12帧、2秒)测了两张图。
白底耳机,每一帧外形都很稳定,不过动作集中在前几帧:

带厨房背景的水彩插画,人物位置和背景每一帧都在变,画面会闪:

原因在于每一帧都是单独生成的,模型没有帧间约束,画面里能变的细节越多,帧与帧的差异就越大。另外,开启GIF输出时不能用透明背景,也不能选2K、4K。这条路线适合白底产品、贴纸、图标这类画面。
路线四:视频模型生成后转GIF
如果要的是自然的动作,就先用图生视频模型把图片生成一段短视频,再转成GIF。视频模型在时间维度上建模,帧与帧之间是连续的。
同样两张图,用视频模型生成5秒视频后转成GIF:


厨房背景不动,只有人物在笑。
转码可以用ffmpeg,先生成调色板再套用,GIF只有256色,不这样做颜色会明显失真:
ffmpeg -i input.mp4 \
-vf "fps=8,scale=360:-1:flags=lanczos,split[a][b];[a]palettegen[p];[b][p]paletteuse" \
-loop 0 output.gif
参数取舍:
- fps:8帧每秒在流畅度和体积之间比较平衡,12以上体积会明显变大。
- scale:宽360像素适合聊天和网页;要更清楚可以用480,体积大约翻一倍。
- 能用视频就用视频:同样内容,MP4通常只有GIF的几分之一大小,画质还更好。只有在对方只收图片的场景,比如部分论坛、文档、邮件,才需要GIF。
怎么选
- 不想用模型、图片不能外传:路线一,纯本地处理。
- 角色循环动作、要帧数多:路线二。
- 白底产品、贴纸、图标,要一步出结果:路线三。
- 照片、带背景的插画,要动作自然:路线四。