首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >FLAnimatedImage -ios gif图片加载框架介绍

FLAnimatedImage -ios gif图片加载框架介绍

作者头像
xiangzhihong
修改于 2025-07-03 09:28:01
修改于 2025-07-03 09:28:01
4.2K00
代码可运行
举报
文章被收录于专栏:向治洪向治洪
运行总次数:0
代码可运行

简介

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处理后的动画数据。

  1. 使用NSData初始化FLAnimatedImage,然后将FLAnimatedImage赋值给FLAnimatedImageView
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 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接口介绍

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@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接口

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@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/

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2016-12-24 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
FLAnimatedImage -ios gif图片加载框架介绍
简介 FLAnimatedImage 是 Flipboard 团队开发的在它们 App 中渲染 GIF 图片使用的库。 后来 Flipboard 将 FLAnimatedImage 开源出来供大家使用。本文章主要是介绍FLAnimatedImage框架的GIF动画加载和播放流程,旨在说明流程和主要细节点。 ios原有加载缺陷分析 大家知道在 iOS 中处理过 GIF 图片, 如果通过原生系统提供的能力, 可能只有两种方式。 并且这两种方式都不是专门针对于 GIF 的解决方案,更像是一种 hack。 第一种方
xiangzhihong
2018/01/26
1.8K0
iOS 图片加载框架SDWebImage详解
在使用SDWebImage加载图片时,尤其是加载gif等大图时,SDWebImage会将图片缓存在内存中,这样是非常吃内存的,这时我们就需要在适当的时候去释放一下SDWebImage的内存缓存,才不至于造成APP闪退。 SDWebImage 提供了 UIImageView、UIButton 、MKAnnotationView 的图片下载分类,只要一行代码就可以实现图片异步下载和缓存功能。 这样开发者就无须花太多精力在图片下载细节上,专心处理业务逻辑。
网罗开发
2021/01/29
2.8K0
【iOS】教你用ZFPlayer+KTVHTTPCache搭建缓存,预加载的播放器
mgr实现ZFPlayerMediaPlayback协议,然后在初始化时,开启本地服务器
MapleYe
2020/03/31
8.4K7
【iOS】教你用ZFPlayer+KTVHTTPCache搭建缓存,预加载的播放器
iOS广告启动页
产品需求:启动页逻辑: 上部分为广告区域,可在运营后台配置图片+跳转页(同No.2);首次开 APP,则请求一次配置,失败或无配置则不显示,一旦有网了即刻请求一次并 做好缓存; 客户端每4小时请求一次;每两小时显示一次广告页内容 用户点击则跳转已配置页面;启动页上有5s倒计时,时间到了启动页关闭,也 可手动点击跳过启动页,广告已过期也不显示。 服务端返回模型: { “image” : “http://www.baidu.com“, “link” : “跳转链接”, “start” : “2017-0
czjwarrior
2018/05/28
9300
iOS高质量的动画实现解决方案——Lottie
    真心的认为Lottie是一款十分优秀且实用的动画开发库,不只对于iOS和android原生开发者来说其让复杂动画的实现几乎没有成本,对于设计师来说,它的所见即所得,不需导出帧图像等优势也十分明显。本篇博客主要以iOS平台为例,简单介绍和总结Lottie动画库的使用方式。
珲少
2018/08/15
4.2K0
iOS高质量的动画实现解决方案——Lottie
iOS中播放gif动态图的方式探讨 原
    在iOS开发中,UIImageView类专门来负责图片数据的渲染,并且UIImageView也有帧动画的方法来播放一组图片,但是对于gif类型的数据,UIImageView中并没有现成的接口提供给开发者使用,在iOS中一般可以通过两种方式来播放gif动态图,一种方式是通过ImageIO框架中的方法将gif文件中的数据进行解析,再使用coreAnimation核心动画来播放gif动画,另一种方式计较简单,可以直接通过webView来渲染gif图。
珲少
2018/08/15
2K0
iOS中播放gif动态图的方式探讨
                                                                            原
UITableView图文混排自动布局滑动优化实战
毫无疑问,使用AutoLayout会明显的比手动计算高度慢,那么我为什么要用AutoLayout呢,因为实在太方便了,而且视图太复杂,产品改的太频繁,手动计算实在工作量太大,维护起来超级麻烦。 而且新的技术出来了,不用不是亏了吗。
xferris
2019/12/30
1.5K0
Objective-c 多线程操作 自定义NSOperation 模拟下载写在前面效果分析代码DEMO地址
使用多线程下载图片,使用内存缓存和磁盘缓存。 这里只为理解NSOperation及其派生类 真要应用到APP中 请下载成熟的第三方库
gwk_iOS
2018/08/23
5050
Objective-c 多线程操作 自定义NSOperation 模拟下载写在前面效果分析代码DEMO地址
SDWebImage源码分析 原
     SDWebImage是iOS开发中非常流行的一个网络图片加载库,如果你观察其源码,会发现其中的文件非常多,虽然文件数很多,但是作者的代码结构和条理却是非清晰。SDWebImage的代码结构基本可以分为3块:应用层类别、核心功能类、工具类与类别。其中我们最常使用的是应用层的类别。例如UIImageView的图片加载,UIButton的图片加载等。
珲少
2018/08/15
1.1K0
SDWebImage源码分析
                                                                            原
SDWebImage 源码阅读(缓存)
在 SDWebImage 中,设计了两种缓存 1.SDMemoryCache:它继承自 NSCache 用来实现内存缓存 2.NSFileManager:使用文件的方式来实现磁盘缓存 先来看一下 SDImageCache 的内存缓存的实现 @interface SDMemoryCache <KeyType, ObjectType> () @property (nonatomic, strong, nonnull) NSMapTable<KeyType, ObjectType> *weakCache;
用户2215591
2018/06/13
1.4K0
【IOS 开发】基本 UI 控件详解 (UISegmentedControl | UIImageView | UIProgressView | UISlider | UIAlertView )
转载请注明出处 : http://blog.csdn.net/shulianghan/article/details/50163725
韩曙亮
2023/03/27
4K0
【IOS 开发】基本 UI 控件详解 (UISegmentedControl | UIImageView | UIProgressView | UISlider | UIAlertView )
分分钟解决iOS开发中App启动广告的功能
allluckly.cn 前不久有朋友需要一个启动广告的功能,我说网上有挺多的,他说,看的不是很理想。想让我写一个,于是乎,抽空写了一个,代码通俗易懂,简单的封装了一下,各种事件用block回调的,有俩种样式的广告,一种是全屏广告,另一种是下面露logo的,类似网页新闻的启动广告。依赖SDWebImage主要用来下载网络的广告图片,一般项目里面网络图片都用的这个框架,所以在此不做过多的阐述。下面让我们来看看我封装的过程,对于新手来说,可以学习一下这种封装的思想。 1.首先建一个继承View的LBLaunch
Bison
2018/07/04
3.5K0
两种通过Plist加载图片的方法及问题,九宫格的算法,字典转模型1. 序列帧动画实现2. 图片浏览器-两种加载plist的方式3. 图片浏览器-内存问题4 MVC简单介绍和类前缀5 应用管理-两种加载
1. 序列帧动画实现 1方式1: [UIImage animatedImageWithImages:**动画图片数组** duration:**持续时间**]; // 可以获取一个能做动画的UIImage对象"gif图片" 2 方式2: self.imageView.animationImages = array; // 装图片的数组(需要做动画的图片数组) self.imageView.animationDuration = 2; // 动画时间 self.imageView.animationRep
stanbai
2018/06/28
1.1K0
[iOS源码笔记]·第三方网络图片处理框架:SDWebImage网络下载及缓存管理策略
typedef void(^SDExternalCompletionBlock)(UIImage * _Nullable image, NSError * _Nullable error, SDImageCacheType cacheType, NSURL * _Nullable imageURL);
陈满iOS
2018/09/10
2.3K0
[iOS源码笔记]·第三方网络图片处理框架:SDWebImage网络下载及缓存管理策略
YYImage 源码剖析:图片处理技巧
图片是现代化 APP 界面设计里应用广泛的东西,精美的图片可以带来视觉上的享受,提高用户体验。由此给技术上带来了一些挑战,比如动图的处理、图片显示流畅程度的优化、图片包大小的优化、超大图片的处理等。
波儿菜
2018/08/02
1.6K0
iOS AVDemo(10):视频解封装,从 MP4 解出 H.264/H.265丨音视频工程示例
iOS/Android 客户端开发同学如果想要开始学习音视频开发,最丝滑的方式是对音视频基础概念知识有一定了解后,再借助 iOS/Android 平台的音视频能力上手去实践音视频的采集 → 编码 → 封装 → 解封装 → 解码 → 渲染过程,并借助音视频工具来分析和理解对应的音视频数据。
关键帧
2022/06/13
7040
iOS AVDemo(10):视频解封装,从 MP4 解出 H.264/H.265丨音视频工程示例
iOS中UIPopoverController使用详解
        UIPopoverController是Pad设备中常用的一种视图控制器,其在UI表现上为在当前视图控制器上面弹出一个子视图控制器,通常用来展示交互列表。示例如下图:
珲少
2018/08/15
2K0
iOS中UIPopoverController使用详解
老司机出品———疯狂造轮子之图片异步下载类
SDWebImage,我估计没有一个做iOS的不知道这个三方库吧,他为我们提供了简洁的图片异步下载方式。在他为我一句api带来这么大便利的同时,你有没有想过他是怎么实现的呢?让我们先来看看他为我们做了什么?
老司机Wicky
2018/08/22
5500
老司机出品———疯狂造轮子之图片异步下载类
iOS开发之微信聊天页面实现
  在上篇博客(iOS开发之微信聊天工具栏的封装)中对微信聊天页面下方的工具栏进行了封装,本篇博客中就使用之前封装的工具栏来进行聊天页面的编写。在聊天页面中主要用到了TableView的知识,还有如何在俩天中显示我们发送的表情,具体请参考之前的博客:IOS开发之显示微博表情,在这儿就不做赘述啦。在聊天页面用到了三对,六种Cell,不过cell的复杂度要比之前的新浪微博(IOS开发之新浪围脖)简单的多。废话少说吧,还是先来几张效果图,在给出实现代码吧。   聊天界面的效果图如下:在下面的聊天界面中中用到了3类
lizelu
2018/01/11
4.5K0
iOS开发之微信聊天页面实现
iOS-多线程详解
欢迎大家指出文章中需要改正或者需要补充的地方,我会及时更新,非常感谢。 一. 多线程基础 1. 进程 进程是指在系统中正在运行的一个应用程序 每个进程之间是独立的,每个进程均运行在其专用且受保护的内存空间内 2.线程 1个进程要想执行任务,必须得有线程(每1个进程至少要有1条线程,称为主线程) 一个进程(程序)的所有任务都在线程中执行 3. 进程和线程的比较 1.线程是CPU调用(执行任务)的最小单位。 2.进程是CPU分配资源的最小单位。 3.一个进程中至少要有一个线程。 4
xx_Cc
2018/05/10
2.3K0
推荐阅读
相关推荐
FLAnimatedImage -ios gif图片加载框架介绍
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档