GIF 怎么做:先算体积预算,再定尺寸与帧率(附两遍编码命令)
把几张照片做成 GIF,工具几步就能搞定。真正难的是后面:做出来 8MB,微信发不出去;帧率调高了画面反而变卡;颜色数一减,人物脸上一块一块。这些都不是工具的问题,是没有先算体积预算。
这篇先给一张"目标体积 → 尺寸 / 帧率"的反推表,再讲清 GIF 的硬限制(256 色、帧延迟按厘秒存),最后是三条优化路径和什么情况下该放弃 GIF 改用视频。
先认 GIF 的硬限制:两个数字决定一切
- 256 色:GIF 是索引色格式,一帧最多 256 种颜色。照片里渐变的天空、皮肤、光影,一定会被"归纳"成 256 色,这就是色带的来源;
- 帧延迟以 1/100 秒存:所以帧率只能取整到厘秒。10fps = 10cs,12fps = 8cs(83ms),15fps = 7cs(67ms)。而且大多数浏览器把小于 20ms 的延迟强行当成 100ms,写 1cs 不会变快,只会变得不可预测。
记住这两条,很多"玄学问题"就解释清了:为什么 GIF 永远没有视频细腻(256 色),为什么设了 50fps 播放却像 10fps(延迟被截断)。
先定体积,再定参数
GIF 的体积大致正比于每帧的像素量 × 帧数,再乘以内容复杂度(运动越多、变化越大,帧间优化越难省)。所以控制的顺序是固定的:尺寸 → 帧数 → 颜色数。
| 用途 | 建议宽度 | 帧率 | 典型体积(3~5 秒) |
|---|---|---|---|
| 微信表情包 | 240px | 10~12fps | 300KB~800KB |
| 聊天 / 社媒配图 | 480px | 12fps | 1~3MB |
| 网页教程演示 | 600~800px | 10~15fps | 2~5MB |
| 产品展示 | 640px | 20fps | 4~8MB |
如果目标体积是硬限制(比如微信表情 1MB),倒推的顺序是:先砍宽度到 240 → 再看时长能不能压到 3 秒内 → 最后把颜色从 256 降到 128 或 64。不要一上来就减颜色,那是最后手段——颜色一减,最先崩的是人物脸和渐变背景。
三种做法,按数量选
做法一:在线工具(几张图,最省事)
- 把图片放同一个文件夹,按顺序命名(
01.jpg、02.jpg),多数工具会按文件名排序; - 一次全部拖进去,缩略图出现后先检查顺序,不对就拖拽调整;
- 设帧延迟:幻灯片 1000~2000ms,前后对比 800~1200ms,定格动画 80~150ms;
- 选宽度(480px 是通用默认)、循环方式(一般都选"永远循环");
- 生成后先看体积,超了就回上一步调宽度。
第 2 步的顺序检查最容易被跳过。文件名是 1.jpg, 10.jpg, 2.jpg 这种没补零的,排序一定乱——补零命名是准备工作里最值钱的一分钟。
做法二:命令行(批量、可复现)
FFmpeg 的标准做法是两遍:第一遍分析所有帧生成最优调色板,第二遍用这个调色板编码。一步到位的做法会使用通用调色板,颜色明显差一截。
# 第一遍:生成调色板
ffmpeg -framerate 12 -i frame_%03d.png -vf "scale=480:-1,palettegen=max_colors=256" palette.png
# 第二遍:用调色板编码,无限循环
ffmpeg -framerate 12 -i frame_%03d.png -i palette.png -lavfi "scale=480:-1,paletteuse=dither=floyd_steinberg" -loop 0 out.gif
scale=480:-1:宽度 480,高度按比例;这一行比任何参数都影响体积;dither=floyd_steinberg:抖动算法,用噪点模拟超出 256 色的颜色,渐变不容易出色带;-loop 0:无限循环(-loop 1是播一次);- 最后可加
gifsicle -O3 --lossy=80再压一轮,通常还能再小 20%~40%。
做法三:从视频转(最省事的高质量路线)
已经有录屏或视频时,别先导出帧再拼,直接转:
ffmpeg -i input.mp4 -vf "fps=12,scale=480:-1,palettegen" palette.png
ffmpeg -i input.mp4 -i palette.png -lavfi "fps=12,scale=480:-1[x];[x][1:v]paletteuse" out.gif
fps=12 会在转的时候直接抽帧,比先导 300 张图再拼快得多。
优化三条路径,按效果排序
| 顺序 | 动作 | 体积影响 | 画质代价 |
|---|---|---|---|
| 1 | 缩小尺寸(1080 → 480) | 像素量降约 80% | 小屏几乎无损 |
| 2 | 抽帧 / 降帧率 | 体积近似线性下降 | 动作变顿 |
| 3 | 减颜色(256 → 128/64) | 再降 20%~40% | 渐变出色带、人脸发花 |
| 4 | 帧间优化(只存变化区域) | 10%~40% | 无损 |
| 5 | gifsicle --lossy | 20%~40% | 轻微噪点 |
第 4 条经常被忽略:GIF 支持"只存与上一帧不同的像素",背景不动、只有小物体在动的动画,优化后体积能掉一大截。gifsicle -O3 就是干这个的,属于无损优化,跑一下不吃亏。
什么时候该放弃 GIF
如果三个条件里中了两个,就该换格式:
- 时长超过 10 秒;
- 画面里有大面积渐变或真实人脸(256 色撑不住);
- 压到目标体积后已经明显糊。
换成 MP4(H.264)通常能小 90% 以上,画质还更好,而且在微信、微博、浏览器里都能自动播放。代价是不支持"无限循环 + 透明背景"这类 GIF 特有的用法。现代网页另一个选择是 WebP 动图或 AV1/VP9 视频,体积更小,兼容性看目标环境。格式的整体取舍见图片格式对比。
几个常见问题
为什么我做出来的 GIF 一卡一卡的?
三个常见原因:一是帧率太低(低于 8fps 就明显顿),二是原始帧数不够(想表现 2 秒动作只拍了 6 张),三是帧延迟被截断——设了小于 20ms 的值会被浏览器当成 100ms,节奏直接乱掉。优先检查第三点。
GIF 能做成透明背景吗?
能,但只有"全透明或全不透明"两种,没有半透明。所以抠图边缘会出现锯齿白边,这是格式限制,不是工具问题。要半透明边缘只能用 WebP 动图或视频(带 alpha 通道)。
为什么颜色数减到 128,人脸就花了?
因为肤色是连续过渡,256 色已经是勉强够用,减到 128 就出现断层,再叠上抖动就变成"噪点脸"。解决办法不是加回颜色,而是先缩小尺寸——尺寸小了,同样的色数覆盖的细节更集中,观感反而更好。
GIF 能放进 PPT / 网页吗?
都能,但要注意体积:网页上一张 5MB 的 GIF 会让页面加载明显变慢,移动端更糟。网页用建议控制在 1MB 内,或者干脆用视频 + 静音自动播放替代。网页图片的体积控制见压缩到 200KB。
手机能直接做 GIF 吗?
能,iPhone 的"实况照片"可以转成循环播放,很多 App 也支持选图合成。但手机的调节项少、体积不可控,做表情包够用,做教程演示还是电脑上做。素材先在手机上准备好(裁好、按顺序命名),传输方法见手机照片传到电脑。
小结
做 GIF 的完整思路是:先算体积预算 → 定宽度和帧率 → 排好帧顺序 → 两遍编码(先生成调色板)→ 用 gifsicle 做无损优化。记住两个硬限制:256 色和厘秒级延迟;记住一个顺序:先缩尺寸、再减帧、最后减颜色。如果内容长、渐变多、又要小,那它本来就不该是 GIF。