Github:https://github.com/bahlo/SwiftGif

这个extension代码不多,主要通过Apple的ImageIO框架进行解析GIF。

整个扩展最核心还是下面的函数,搞了半天还是Apple的UIImage的类函数。所以重点就是找到GIF中的每一帧图片和每一帧的延迟是多少。

只要通过该函数返回的UIImage就是一个带动画的UIImage(记得我当年切了几个图还新建NSTimer实现动画…)

可见会调用API的重要性…

let animation = UIImage.animatedImageWithImages(frames,duration: Double(duration) / 1000.0)

大致过程如下:

1.imageName.GIF文件 -> NSData

contentsOfURL函数:

2.NSdata -> CGImageSource

CGImageSourceCreateWithData函数

3.从CGImageSource的对象中取得图片张数

CGImageSourceGetCount(source)

4.创建CGImage类型的数组,将CGImageSource中的图片一张张的添加到该数组中

CGImageSourceCreateImageAtIndex(source, i, nil)

5.创建delay数组,将CGImageSource中的每一帧的图片的延迟加入数组,这个函数比较麻烦

先是取得CGImageSource中的某个实体,类型是CFDictionary:

let cfProperties = CGImageSourceCopyPropertiesAtIndex(source, index, nil)

然后取得该字典中的Gif类型的字典,类型是CFDictionaryRef(CFDictionary的引用,是一样的)

let gifProperties: CFDictionaryRef = unsafeBitCast(

CFDictionaryGetValue(cfProperties,

unsafeAddressOf(kCGImagePropertyGIFDictionary)),

CFDictionary.self)
然后从GIF字典中取得延迟时间,这里取2次,先是尝试了kCGImagePropertyGIFUnclampedDelayTime,再尝试kCGImagePropertyGIFDelayTime:

var delayObject: AnyObject = unsafeBitCast(

CFDictionaryGetValue(gifProperties,

unsafeAddressOf(kCGImagePropertyGIFUnclampedDelayTime)),

AnyObject.self)

if delayObject.doubleValue == 0 {

delayObject = unsafeBitCast(CFDictionaryGetValue(gifProperties,

unsafeAddressOf(kCGImagePropertyGIFDelayTime)), AnyObject.self)

}

6.这样大概就按顺序构建起了2个数组,一个是CGImage数组,一个是延迟大小。

7.然后把CGImage的数组转成UIImage的数组,因为UIImage.animatedImageWithImages(frames,duration)需要传入的frames是IImage的数组。

从中我感受到,CoreImage、CoreAnimation等图像有关的框架非常强大,其中有很多useful的API

iOS 分析一个支持GIF的UIImage扩展:SwiftGIF的更多相关文章

  1. iOS 模仿一个小项目,总结一下里边的模块

      ManoBoo:  参考链接:http://www.jianshu.com/p/fd4c46c31508  这个小的项目是参考ManoBoo的简书的,链接在上方,自己在仿做的过程中,也离不开Man ...

  2. iOS UIImage扩展方法(category):放大、旋转、合并UIImage、增加渐变层、添加阴影、调节透明度、保存到相册

    一有用的 UIImage 扩展,支持(等比例)放大和旋转可在许多 App 中使用. UIImage-Extensions.h #import <Foundation/Foundation.h&g ...

  3. iOS工程如何支持64-bit(转)

    苹果在2014年10月20号发布了一条消息:从明年的二月一号开始,提交到App Store的应用必须支持64-bit.详细消息地址为:https://developer.apple.com/news/ ...

  4. iOS工程如何支持64-bit

    苹果在2014年10月20号发布了一条消息:从明年的二月一号开始,提交到App Store的应用必须支持64-bit.详细消息地址为:https://developer.apple.com/news/ ...

  5. dubbo源码分析之基于SPI的强大扩展

    https://blog.csdn.net/luoyang_java/article/details/86609045 Dubbo采用微内核+插件体系,使得设计优雅,扩展性强.那所谓的微内核+插件体系 ...

  6. 一个支持高网络吞吐量、基于机器性能评分的TCP负载均衡器gobalan

    一个支持高网络吞吐量.基于机器性能评分的TCP负载均衡器gobalan 作者最近用golang实现了一个TCP负载均衡器,灵感来自grpc.几个主要的特性就是: 支持高网络吞吐量 实现了基于机器性能评 ...

  7. FizzlerEx —— 另一个HtmlAgilityPack的CSS选择器扩展,

    之前我介绍过HtmlAgilityPack的CSS选择器扩展——ScrapySharp,它可以非常方便的实现通过CSS选择器表达式来查询HtmlNode.今天在使用的过程中,发现它不支持nth-chi ...

  8. python 开发一个支持多用户在线的FTP

    ### 作者介绍:* author:lzl### 博客地址:* http://www.cnblogs.com/lianzhilei/p/5813986.html### 功能实现 作业:开发一个支持多用 ...

  9. Postman 是一个非常棒的Chrome扩展,提供功能强大的API & HTTP 请求调试

    Postman 是一个非常棒的Chrome扩展,提供功能强大的API & HTTP 请求调试   需要FQ才能安装,使用时应该不用FQ了,除非使用postman的历史记录功能:   非常棒的C ...

随机推荐

  1. select、poll、epoll区别总结

    1 本质上都是同步I/O 三者都是I/O复用,本质上都属于同步I/O.因为三者只是负责通知应用程序什么时候数据准备好了,实际的I/O操作还是在由应用程序处理:如果是异步I/O的话,实际I/O由内核处理 ...

  2. 不能在DropDownList 中选择多个项

    在绑定DropDownList时如果出现多次绑定,会出错以下错误: “不能在DropDownList 中选择多个项” 经了解,只需要在选中值是清空选择即可:xxDropDownList.ClearSe ...

  3. 最新版Android开发工具

    最新版Android开发工具 JUN 27TH, 2014 Android Tools ADT Bundle ADT Bundle包含了Eclipse.ADT插件和SDK Tools,是已经集成好的I ...

  4. [转载]Linux Bond的原理及其不足

    本文转自http://www.yunweipai.com/archives/1969.html 支持原创.尊重原创,分享知识! 在企业及电信Linux服务器环境上,网络配置都会使用Bonding技术做 ...

  5. LoadRunner:视频教程、课件

    LoadRunner 视频教程地址: 51 自学网LoadRunner入门视频教程 (这个网站的网址粘不上来,可能与博客园有过节吧)视频中的课件下载地址:链接: http://pan.baidu.co ...

  6. SQLite学习笔记(九)&&pager模块

    概述 通过上一篇文章的分析,我们知道了pager模块在整个sqlite中所处的位置.它是sqlite的核心模块,充当了多种重要角色.作为一个事务管理器,它通过并发控制和故障恢复实现事务的ACID特性, ...

  7. .NET并行编程实践(一:.NET并行计算基本介绍、并行循环使用模式)

    阅读目录: 1.开篇介绍 2.NET并行计算基本介绍 3.并行循环使用模式 3.1并行For循环 3.2并行ForEach循环 3.3并行LINQ(PLINQ) 1]开篇介绍 最近这几天在捣鼓并行计算 ...

  8. [Java入门笔记] 面向对象编程基础(三):成员变量和局部变量

    在类中,变量根据定义的位置不同,可以分为成员变量和局部变量.

  9. swift判断是否真机or模拟器

    之前一直用的这种,不知道为什么不怎么靠谱 #if TARGET_IPHONE_SIMULATOR//模拟器 #else//真机 #endif 现在用这种: if Platform.isSimulato ...

  10. Pause/Resume Instance 操作详解 - 每天5分钟玩转 OpenStack(34)

    本节通过日志详细分析 Nova Pause/Resume 操作. 有时需要短时间暂停 instance,可以通过 Pause 操作将 instance 的状态保存到宿主机的内存中.当需要恢复的时候,执 ...