FLAnimatedImage -ios gif图片加载框架介绍
简介
FLAnimatedImage 是 Flipboard 团队开发的在它们 App 中渲染 GIF 图片使用的库。 后来 Flipboard 将 FLAnimatedImage 开源出来供大家使用。本文章主要是介绍FLAnimatedImage框架的GIF动画加载和播放流程,旨在说明流程和主要细节点。
ios原有加载缺陷分析
大家知道在 iOS 中处理过 GIF 图片, 如果通过原生系统提供的能力, 可能只有两种方式。 并且这两种方式都不是专门针对于 GIF 的解决方案,更像是一种 hack。
第一种方式, UIImage 虽然提供了一种创建连续切换的动画图片的能力, 但这个能力更像是为了那些简单动画而服务的。 比如加载数据时候显示的 loading 图片。 如果将 GIF 图片通过这种能力来显示,会带来诸多问题。
第二种方式,可能是大家用的最多的了。 就是创建一个 UIWebView 然后在这里面把 GIF 显示出来。 但从原理上来想, UIWebView 并不是为了显示 GIF 图片而生的。
gif渲染原理分析
为什么说 FLAnimatedImage 相对于 iOS 原生的几种 hack 方式更趋近于最佳实践呢? 咱们简单聊聊 FLAnimatedImage 渲染 GIF 图片的原理。FLAnimatedImage 会有两个线程同时在运转。 其中一个线程负责渲染 GIF 的每一帧的图片内容(所谓的渲染,大体上就是加载 GIF 文件数据,然后抽取出来当前需要哪一帧)。这个加载图片的过程是在异步线程进行的。
然后 FLAnimatedImage 会有一个内存区域专门放置这些渲染好的帧。 这时候,在主线程中的 ImageView 会根据当前需要,从这个内存区域中读取相应的帧。这是一个典型的生产者-消费者问题。
FLAnimatedImage
FLAnimatedImage项目的流程比较简单,FLAnimatedImage就是负责GIF数据的处理,然后提供给FLAnimatedImageView一个UIImage对象。FLAnimatedImageView拿到UIImage对象显示出来就可以了。
实例
使用FLAnimatedImage 加载GIF,有三个关键函数:使用FLAnimatedImage处理GIF动画数据,使用FLAnimatedImageView展示FLAnimatedImage处理后的动画数据。
- 使用NSData初始化FLAnimatedImage,然后将FLAnimatedImage赋值给FLAnimatedImageView
if (!self.imageView1) {
self.imageView1 = [[FLAnimatedImageView alloc] init];
self.imageView1.contentMode = UIViewContentModeScaleAspectFill;
self.imageView1.clipsToBounds = YES;
}
[self.view addSubview:self.imageView1];
self.imageView1.frame = CGRectMake(0.0, 120.0, self.view.bounds.size.width, 447.0);
NSURL *url1 = [[NSBundle mainBundle] URLForResource:@"rock" withExtension:@"gif"];
NSData *data1 = [NSData dataWithContentsOfURL:url1];
FLAnimatedImage *animatedImage1 = [FLAnimatedImage animatedImageWithGIFData:data1];
self.imageView1.animatedImage = animatedImage1;
2.使用URL初始化FLAnimatedImage,然后将FLAnimatedImage赋值给FLAnimatedImageView
if (!self.imageView2) {
self.imageView2 = [[FLAnimatedImageView alloc] init];
self.imageView2.contentMode = UIViewContentModeScaleAspectFill;
self.imageView2.clipsToBounds = YES;
}
[self.view addSubview:self.imageView2];
self.imageView2.frame = CGRectMake(0.0, 577.0, 379.0, 447.0);
NSURL *url2 = [NSURL URLWithString:@"https://cloud.githubusercontent.com/assets/1567433/10417835/1c97e436-7052-11e5-8fb5-69373072a5a0.gif"];
[self loadAnimatedImageWithURL:url2 completion:^(FLAnimatedImage *animatedImage) {
self.imageView2.animatedImage = animatedImage;
}];
FLAnimatedImage项目介绍
FLAnimatedImage项目采用了“生产者和消费者”模型来处理这个GIF动画的播放问题。一个线程负责生产数据,另一个线程负责消费数据。生产者FLAnimatedImage负责提供帧UIImage对象,消费者FLAnimatedImageView负责显示该UIImage对象。
FLAnimatedImage接口介绍
@property (nonatomic, strong, readonly) UIImage *posterImage;//GIF动画的封面帧图片
@property (nonatomic, assign, readonly) CGSize size; //GIF动画的封面帧图片的尺寸
@property (nonatomic, assign, readonly) NSUInteger loopCount; //GIF动画的循环播放次数
@property (nonatomic, strong, readonly) NSDictionary *delayTimesForIndexes; // GIF动画中的每帧图片的显示时间集合
@property (nonatomic, assign, readonly) NSUInteger frameCount; //GIF动画的帧数量
@property (nonatomic, assign, readonly) NSUInteger frameCacheSizeCurrent; //当前被缓存的帧图片的总数量
@property (nonatomic, assign) NSUInteger frameCacheSizeMax; // 允许缓存多少帧图片
// Intended to be called from main thread synchronously; will return immediately.
// If the result isn't cached, will return `nil`; the caller should then pause playback, not increment frame counter and keep polling.
// After an initial loading time, depending on `frameCacheSize`, frames should be available immediately from the cache.
// 取出对应索引的帧图片
- (UIImage *)imageLazilyCachedAtIndex:(NSUInteger)index;
// Pass either a `UIImage` or an `FLAnimatedImage` and get back its size
// 计算该帧图片的尺寸
+ (CGSize)sizeForImage:(id)image;
// 初始化方法
// On success, the initializers return an `FLAnimatedImage` with all fields initialized, on failure they return `nil` and an error will be logged.
- (instancetype)initWithAnimatedGIFData:(NSData *)data;
// Pass 0 for optimalFrameCacheSize to get the default, predrawing is enabled by default.
- (instancetype)initWithAnimatedGIFData:(NSData *)data optimalFrameCacheSize:(NSUInteger)optimalFrameCacheSize predrawingEnabled:(BOOL)isPredrawingEnabled NS_DESIGNATED_INITIALIZER;
+ (instancetype)animatedImageWithGIFData:(NSData *)data;
//初始化数据
@property (nonatomic, strong, readonly) NSData *data; // The data the receiver was initialized with; read-only
FLAnimatedImage函数解析
关键方法解析
a、对传进来的数据进行合法性判断,至少不能为nil。
b、初始化对应的变量,用于存储各类辅助数据。
c、将传进来的数据处理成图片数据,其中设置。kCGImageSourceShouldCache为NO,可以避免系统对图片进行缓存。
d、从数据中读取图片类型,判断该图片是不是GIF动画类型。
e、读取GIF动画中的动画信息,包括动画循环次数,有几帧图片等。
f、遍历GIF动画中的所有帧图片,取出并保存帧图片的播放信息,设置GIF动画的封面帧图片
g、根据设置或者GIF动画的占用内存大小,与缓存策略对比,确认缓存策略。
FLAnimatedImageView接口
@interface FLAnimatedImageView : UIImageView
// Setting `[UIImageView.image]` to a non-`nil` value clears out existing `animatedImage`.
// And vice versa, setting `animatedImage` will initially populate the `[UIImageView.image]` to its `posterImage` and then start animating and hold `currentFrame`.
@property (nonatomic, strong) FLAnimatedImage *animatedImage;//设置GIF动画数据
@property (nonatomic, copy) void(^loopCompletionBlock)(NSUInteger loopCountRemaining);//GIF动画播放一次之后的回调Block
@property (nonatomic, strong, readonly) UIImage *currentFrame;//GIF动画当前显示的帧图片
@property (nonatomic, assign, readonly) NSUInteger currentFrameIndex;//GIF动画当前显示的帧图片索引
// The animation runloop mode. Enables playback during scrolling by allowing timer events (i.e. animation) with NSRunLoopCommonModes.
// To keep scrolling smooth on single-core devices such as iPhone 3GS/4 and iPod Touch 4th gen, the default run loop mode is NSDefaultRunLoopMode. Otherwise, the default is NSDefaultRunLoopMode.
@property (nonatomic, copy) NSString *runLoopMode;
FLAnimatedImageView解析:
关键对象解析:
a、判断新旧FLAnimatedImage对象是否一致,一致就不需要继续操作了
b、设置GIF动画的封面帧图片,当前帧索引,GIF动画的循环播放次数,播放时间累加器
c、更新是否发起动画的标志位,判断是否启动GIF动画
d、刷新View的layer
参考:http://swiftcafe.io/2016/12/08/fl-image/
http://engineering.flipboard.com/2014/05/animated-gif/
FLAnimatedImage -ios gif图片加载框架介绍的更多相关文章
- YYWebImage——iOS异步图片加载框架
本文转载至 http://www.mobile-open.com/2015/86582.html YYWebImage 是一个异步图片加载框架 (YYKit 组件之一). 其设计目的是试图替代 S ...
- iOS图片加载框架-SDWebImage解读
在iOS的图片加载框架中,SDWebImage可谓是占据大半壁江山.它支持从网络中下载且缓存图片,并设置图片到对应的UIImageView控件或者UIButton控件.在项目中使用SDWebImage ...
- iOS 图片加载框架- SDWebImage 解读
在iOS的图片加载框架中,SDWebImage可谓是占据大半壁江山.它支持从网络中下载且缓存图片,并设置图片到对应的UIImageView控件或者UIButton控件.在项目中使用SDWebImage ...
- Android中常见的图片加载框架
图片加载涉及到图片的缓存.图片的处理.图片的显示等.而随着市面上手机设备的硬件水平飞速发展,对图片的显示要求越来越高,稍微处理不好就会造成内存溢出等问题.很多软件厂家的通用做法就是借用第三方的框架进行 ...
- 强大的图片加载框架Fresco的使用
前面在卓新科技有限公司实习的时候,在自己的爱吖头条APP中,在图片异步加载的时候和ListView的滑动中,总会出现卡顿,这是因为图片的缓存做的不是足够到位,在项目监理的帮助下,有使用Xutils框架 ...
- Android之图片加载框架Fresco基本使用(一)
PS:Fresco这个框架出的有一阵子了,也是现在非常火的一款图片加载框架.听说内部实现的挺牛逼的,虽然自己还没研究原理.不过先学了一下基本的功能,感受了一下这个框架的强大之处.本篇只说一下在xml中 ...
- android Glide图片加载框架的初探
一.Glide图片加载框架的简介 谷歌2014年开发者论坛会上介绍的图片加载框架,它让我们在处理不管是网路下载的图片还是本地的图片,减轻了很多工作量, 二.开发步骤: 1.添加链接库 compile ...
- 一起写一个Android图片加载框架
本文会从内部原理到具体实现来详细介绍如何开发一个简洁而实用的Android图片加载缓存框架,并在内存占用与加载图片所需时间这两个方面与主流图片加载框架之一Universal Image Loader做 ...
- Android项目框架之图片加载框架的选择
本文来自http://blog.csdn.net/liuxian13183/ ,引用必须注明出处! 从Android爆发以后,自定义的控件如EditTextWithDelete.ActionBar.P ...
随机推荐
- Linux OpenGL 实践篇-3 绘制三角形
本次实践是绘制两个三角形,重点理解顶点数组对象和OpenGL缓存的使用. 顶点数组对象 顶点数组对象负责管理一组顶点属性,顶点属性包括位置.法线.纹理坐标等. OpenGL缓存 OpenGL缓存实质上 ...
- ios、移动端 input type=date无法点击的问题解决方法
正常用input type = "text",获取焦点的时候,将type 改成 date即可. <div class="form-item"> &l ...
- Mysql数据库事务隔离级别
事务(transaction)是数据库管理系统的执行单位,可以是一个数据库操作(如Select操作)或者是一组操作序列.事务ACID属性,即原子性(Atomicity).一致性(Consistency ...
- POJ1743 Musical Theme(二分+后缀数组)
题目大概是给n个数组成的串,求是否有多个“相似”且不重叠的子串的长度大于等于5,两个子串相似当且仅当长度相等且每一位的数字差都相等. 这题是传说中楼教主男人八题之一,虽然已经是用后缀数组解决不可重叠最 ...
- 2015 多校联赛 ——HDU5386(暴力)
Sample Input 1 3 5 2 2 1 2 3 3 2 1 3 3 3 3 3 3 3 3 3 3 H 2 3 L 2 2 H 3 3 H 1 3 L 2 3 Sample Output ...
- poj 3525 凸多边形多大内切圆
Most Distant Point from the Sea Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 4758 ...
- 【Codeforces Round #430 (Div. 2) A C D三个题】
·不论难度,A,C,D自己都有收获! [A. Kirill And The Game] ·全是英文题,述大意: 给出两组区间端点:l,r,x,y和一个k.(都是正整数,保证区间不为空),询问是否 ...
- 【LA 3027 Corporative Network】
·一些很可爱的询问和修改,放松地去用并查集解决. ·英文题,述大意: 输入n(5<=n<=20000)表示树有n个节点,并且会EOF结束地读入不超过 20000个操作,一共有两种: ...
- poj 3904(莫比乌斯反演)
POJ 3904 题意: 从n个数中选择4个数使他们的GCD = 1,求总共有多少种方法 Sample Input 4 2 3 4 5 4 2 4 6 8 7 2 3 4 5 7 6 8 Sample ...
- [bzoj4828][Ah/Hnoi2017]大佬
来自FallDream的博客,未经允许,请勿转载,谢谢. 人们总是难免会碰到大佬.他们趾高气昂地谈论凡人不能理解的算法和数据结构,走到任何一个地方,大佬的气场就能让周围的人吓得瑟瑟发抖,不敢言语. 你 ...