AnimatedGIFImageSerialization 编码教程:如何把 UIImage 序列导出为 GIF(duration 与 loopCount 详解)
AnimatedGIFImageSerialization 编码教程:如何把 UIImage 序列导出为 GIF(duration 与 loopCount 详解)【免费下载链接】AnimatedGIFImageSerializationComplete Animated GIF Support for iOS, with Functions, NSJSONSerialization-style Class, and (Optional) UIImage Swizzling项目地址: https://gitcode.com/gh_mirrors/an/AnimatedGIFImageSerializationAnimatedGIFImageSerialization 是 iOS 开发中非常经典的动图处理库它提供了两大核心能力把 UIImage 序列导出为 GIF编码与把 GIF 解码为 UIImageAPI 风格模仿系统自带的 NSJSONSerialization上手成本极低。本篇文章是一份面向初学者的 GIF 编码教程重点讲透导出 GIF 时最容易被忽视、也最影响效果的两个参数duration每帧时长与loopCount循环次数。看完你就能用animatedGIFDataWithImage:一行代码把自己的多张 UIImage 打包成 GIF 动图。为什么需要把 UIImage 序列导出为 GIF很多新手会踩同一个坑UIImage原生并不支持保存成 GIF。在 iOS 13 之前系统只默认帮你导出 PNG / JPEG 静态图想把一组图片做成动图就得自己折腾 ImageIO 和CGImageDestination代码又长又容易出错。AnimatedGIFImageSerialization 正是为了解决这个问题而生提供类似 NSJSONSerialization 的一键式 API编码解码各一行搞定底层基于 ImageIO自动处理帧延迟与循环次数的写入可选开启 UIImage 方法交换Swizzling让[UIImage imageNamed:xxx.gif]直接支持 GIF 解码。所有公开 API 声明都集中在头文件 AnimatedGIFImageSerialization.h 中核心实现则在 AnimatedGIFImageSerialization.m 里源码清晰很适合当作学习 ImageIO 编码的范例。快速上手animatedGIFDataWithImage 一键导出 GIF编码入口非常简单只需一行调用NSData *data [AnimatedGIFImageSerialization animatedGIFDataWithImage:image duration:1.0 loopCount:0 error:nil];其中image可以是由多帧组成的动态 UIImage内部通过image.images取出每一帧也可以是单张静态图duration整段动画的总时长秒loopCountGIF 循环次数0表示无限循环error可选的错误信息输出参数失败时返回nil。如果不传 duration 和 loopCount还有更简短的版本animatedGIFDataWithImage:error:内部默认按duration 0、loopCount 0处理。拿到NSData后写入文件或上传服务器都随你。duration 参数详解如何控制 GIF 动画速度动画快慢是 GIF 观感的关键而它完全由duration决定。源码里的换算逻辑如下库会先取帧数frameCount image.images.count每帧时长 总时长 ÷ 帧数frameDuration duration / frameCount由于 GIF 格式的帧延迟只能以百分之一秒厘秒为单位存储库会四舍五入lrint(frameDuration * 100)也就是精度约为 0.01 秒最终把这个厘秒值写入每一帧的kCGImagePropertyGIFDelayTime。举个例子你有 10 帧图片想让每帧显示 0.1 秒那么传duration 1.0即可1 秒 ÷ 10 帧 0.1 秒/帧。还有一个实用的小细节当duration传0或负数时库会自动回退使用image.duration / frameCount也就是沿用 UIImage 自带的总时长信息。这意味着用[UIImage animatedImageWithImages:duration:]创建的动态图直接交给编码方法也能得到合理的速度无需手动算时长。loopCount 参数详解GIF 循环次数怎么设循环次数是另一个高频问题。在 GIF 规范中循环计数写入的是kCGImagePropertyGIFLoopCountAnimatedGIFImageSerialization 通过CGImageDestinationSetProperties在文件头写入该值。它的取值含义如下loopCount 取值效果0无限循环默认值最常用1只播放一次播完停住N循环播放 N 次所以如果你想要播一次就停的效果传loopCount 1想要表情包那种无限转圈就用默认的0。值得注意的是传0恰恰是无限循环很多新手误以为 0 表示不循环结果做出永远停不下来的 GIF搞清这个语义能帮你少踩一个坑。完整编码示例多张 UIImage 组装成 GIF把编码教程落到实处最常见的场景是把一组静态图拼成动图完整代码如下// 1. 准备多帧图片 NSMutableArrayUIImage * *frames [NSMutableArray array]; for (int i 0; i 10; i) { [frames addObject:[UIImage imageNamed:[NSString stringWithFormat:frame_%d, i]]]; } // 2. 组装成动态 UIImage设置总时长 2 秒 UIImage *animatedImage [UIImage animatedImageWithImages:frames duration:2.0]; // 3. 导出 GIF每帧 0.2 秒无限循环 NSData *gifData [AnimatedGIFImageSerialization animatedGIFDataWithImage:animatedImage duration:2.0 loopCount:0 error:nil]; // 4. 写入沙盒或相册 [gifData writeToFile:somePath atomically:YES];整个流程就四步不需要手动创建CGImageDestination也不需要逐个帧写属性——这些脏活累活都封装在了UIImageAnimatedGIFRepresentation这个函数里。解码也不难imageNamed 直接加载 GIF既然是完整的 GIF 解决方案解码同样值得体验。默认情况下库通过 Method Swizzling 增强了UIImage的imageNamed:、imageWithData:、initWithContentsOfFile:等方法你只需要像加载普通图片一样写UIImageView *imageView ...; imageView.image [UIImage imageNamed:animated.gif];GIF 就能自动解码成动画。它还会自动适配2x、3x以及不同屏幕高度-568h、-667h、-736h的资源命名细节相当贴心。如果你不希望改动 UIImage 的默认行为可以在构建环境定义宏ANIMATED_GIF_NO_UIIMAGE_INITIALIZER_SWIZZLING来关闭 Swizzling。常见问题与避坑指南围绕 duration 和 loopCount这里再总结几个高频问题时长精度GIF 帧延迟最小单位为 0.01 秒过小的帧间隔会被四舍五入别指望做 60fps 的细腻动画duration 传 0 的含义不是零时长而是自动用 image.duration语义要记牢loopCount 传 0 的含义不是不循环而是无限循环错误处理编码失败时返回nil并把错误信息写入error错误域为AnimatedGIFImageErrorDomaincom.compuserve.gif.image.error建议正式项目务必检查返回值iOS 13 的替代方案作者已在 README 中声明本项目不再维护苹果从 iOS 13 / macOS 10.15 起提供了原生接口CGAnimateImageAtURLWithBlock新项目可优先考虑系统方案老项目或需要自定义帧率、循环次数时这套库依然非常顺手。获取源码与总结想亲自跑一遍这个编码教程可以直接克隆仓库git clone https://gitcode.com/gh_mirrors/an/AnimatedGIFImageSerialization仓库自带完整的 Xcode 工程示例见Example/Animated GIF Example里面有现成的演示 GIF 和 AppDelegate 样例配合本教程上手更快。核心文件就两个头文件AnimatedGIFImageSerialization/AnimatedGIFImageSerialization.h查看全部 API实现文件AnimatedGIFImageSerialization/AnimatedGIFImageSerialization.mduration 换算、loopCount 写入的完整逻辑都在这里。总结一句话把 UIImage 序列导出为 GIF记住 duration 控制速度总时长 ÷ 帧数 每帧时长、loopCount 控制循环0 无限循环再配合animatedGIFDataWithImage:的一行式 API你就能快速为自己的 App 加入动图导出能力了。如果对 GIF 的帧延迟、循环语义还有疑问欢迎对照源码逐行阅读相信会有更深的收获【免费下载链接】AnimatedGIFImageSerializationComplete Animated GIF Support for iOS, with Functions, NSJSONSerialization-style Class, and (Optional) UIImage Swizzling项目地址: https://gitcode.com/gh_mirrors/an/AnimatedGIFImageSerialization创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考