众所周知,iOS默认是不支持gif类型图片的显示的,但是我们项目中常常是需要显示gif为动态图片。那肿么办?第三方库?是的 ,很多第三方都支持gif , 如果一直只停留在用第三方上,技术难有提高。上版本的 Kingfisher 也支持gif ,研究了一番,也在网上搜索了一番,稍微了解了下iOS实现gif的显示,在此略做记录。
本篇文章要实现的效果如图:
可以开始和暂停gif的播放,滑动时停止播放,这个简书也是这么做得,好多app为了滑动时顺畅,停止了gif。
下面要进入正文啦!
分解gif帧进行显示
我们一般从网络上下载的gif图片其实是将很多帧静态图片循环播放产生的动态效果,那么在iOS中,如果我们想要显示动态图,同样需要先把gif资源解析为一阵一阵的UIImage
然后设定间隔时长,不断播放即可。思路是不是很简单呢?那么看看如何实现。
分几个步骤:
- 将gif图片转为
NSData
。 - 根据
NSData
获取CGImageSource
对象 - 获取帧数
- 根据帧数获取每一帧对应的
UIImage
对象和时间间隔 - 循环播放
首先我们需要引入import ImageIO
, 提供了很多对图片操作的函数。
这里我们从网上down了一个gif的图片,其实下载也是一样的 ,我们需要的是NSData
类型的数据,用NSURLSession
下载也可以得到NSData
类型的数据,这里下载的数据如何判断是否为gif呢?
Kingfisher
库中给出了解决方案,每种格式的图片前面几位都是固定的。所以只需要对比就能判断出类型,这里给出Kingfisher
判断类型的代码。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
private let pngHeader: [UInt8] = [0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A] private let jpgHeaderSOI: [UInt8] = [0xFF, 0xD8] private let jpgHeaderIF: [UInt8] = [0xFF] private let gifHeader: [UInt8] = [0x47, 0x49, 0x46] enum ImageFormat { case Unknown, PNG, JPEG, GIF } extension NSData { var kf_imageFormat: ImageFormat { var buffer = [UInt8](count: 8, repeatedValue: 0) self.getBytes(&buffer, length: 8) if buffer == pngHeader { return .PNG } else if buffer[0] == jpgHeaderSOI[0] && buffer[1] == jpgHeaderSOI[1] && buffer[2] == jpgHeaderIF[0] { return .JPEG } else if buffer[0] == gifHeader[0] && buffer[1] == gifHeader[1] && buffer[2] == gifHeader[2] { return .GIF } return .Unknown } } |
有了这个扩展判断起来就方便很多了。
为了使demo简单,我们直接将gif放在本地沙盒。下载好直接拖进项目就OK了。
这样就可以很容易的得到NSData
类型的数据
1 2 |
let path = NSBundle.mainBundle().pathForResource("xxx", ofType: "gif") let data = NSData(contentsOfFile: path!) |
第一步已经完成啦。
然后通过CGImageSourceCreateWithData
方法创建一个CGImageSource
对象 。
1 2 3 4 5 6 |
// kCGImageSourceShouldCache : 表示是否在存储的时候就解码 // kCGImageSourceTypeIdentifierHint : 指明source type let options: NSDictionary = [kCGImageSourceShouldCache as String: NSNumber(bool: true), kCGImageSourceTypeIdentifierHint as String: kUTTypeGIF] guard let imageSource = CGImageSourceCreateWithData(data, options) else { return } |
这里的options是为了显示优化。提前解码,指定类型。
拿到CGImageSource
对象就可以为所欲为了。
1 2 3 4 5 gif study
众所周知,iOS默认是不支持gif类型图片的显示的,但是我们项目中常常是需要显示gif为动态图片。那肿么办?第三方库?是的 ,很多第三方都支持gif , 如果一直只停留在用第三方上,技术难有提高。上版本的 Kingfisher 也支持gif ,研究了一番,也在网上搜索了一番,稍微了解了下iOS实现gif的显示,在此略做记录。 本篇文章要实现的效果如图: gif显示效果
可以开始和暂停gif的播放,滑动时停止播放,这个简书也是这么做得,好多app为了滑动时顺畅,停止了gif。 下面要进入正文啦! 期待…
分解gif帧进行显示我们一般从网络上下载的gif图片其实是将很多帧静态图片循环播放产生的动态效果,那么在iOS中,如果我们想要显示动态图,同样需要先把gif资源解析为一阵一阵的 分几个步骤:
首先我们需要引入 这里我们从网上down了一个gif的图片,其实下载也是一样的 ,我们需要的是
有了这个扩展判断起来就方便很多了。 为了使demo简单,我们直接将gif放在本地沙盒。下载好直接拖进项目就OK了。 这样就可以很容易的得到
第一步已经完成啦。 然后通过
这里的options是为了显示优化。提前解码,指定类型。 拿到
|