本系列博客是本人的开发笔记。为了方便讨论,本人新建了一个微信群(iOS技术讨论群),想要加入的,请添加本人微信:zhujinhui207407,【加我前请备注:iOS 】,本人博客http://www.kyson.cn 也在不停的更新中,欢迎一起讨论
在开发iOS的过程中一开始只是讲求功能的完善,后期会逐渐对UI的展示提出越来越高的要求。大家可能首先会想到动画,比如CAAnimation,OpenGL等库。但有时为了偷懒,或者有特别难以实现的动画我们可以通过动图来实现。本文就动图实现的原理以及各种方案做个探究。
原理
大家都知道,动图是由一张张静态图片在一定时间内播放形成的。其中的每一张静态图片我们称为一帧(Frame),播放出来的动画也称为逐帧动画。iPhone的每秒帧数是60,当每秒播放帧数(FPS:Frames Per Second)低于24的时候就会给人以卡顿的感觉。因此假设我们有个ImageView,如果我们循环往复的按同等时间间隔替换里面的图片,那按道理就会给我们一种动画的感觉:
逐帧动画具体实现
UIKit
UIImageView
已经为我们提供了相应的加载动图的属性:
属性 | 含义 |
---|---|
animationImages | 图片数组 |
animationDuration | 持续时间 |
animationRepeatCount | 重复次数 |
相应地,UIImage
中也提供了对动画的支持:
方法或属性 | 含义 |
---|---|
animatedImageNamed: duration: | 动图初始化 |
images | 包含的图片数组(如果有) |
因此我们只需要准备一系列的JPG或PNG图片数组,然后将其依次加载并添加进数组中,设置好动画时间以及其他的一些参数即可实现。
Gif
UIImage
本身不支持加载Gif,如果使用[UIImage imageWithData:];
方法只会加载Gif的第一帧。幸好SDWebImage
已经支持了加载Gif图:
NSData *imageData = [NSData dataWithContentsOfURL:url];
UIImage *image = [UIImage sd_animatedGIFWithData:imageData];
imageView.image = image;
如果我们查看SDWebImage
的源码会发现其原理跟本文第一种方式是类似的,都是先获取每一帧,然后将其赋值给UIImageView
。
方法 | 介绍 |
---|---|
CGImageSourceGetCount | 获取帧数 |
[UIImage imageWithCGImage:imageRef] | 获取每一帧图像 |
表中的imageRef
是通过CoreGraphics中提供的方法获取的图片引用。这里不多做介绍,大家可以参考苹果官方文档。
WebP
使用Gif的缺点是图片太大,文件加载也会消耗I/O资源。因此谷歌设计了另外一个图片格式:WebP,它的优点在于更优的图像数据压缩算法,更小的图片体积,而且拥有肉眼识别无差异的图像质量。下图展示了一份Gif与WebP的图片对比图:
Webp VS gif目前谷歌的全系列产品都支持WebP格式,也为谷歌带来了很多效益。不过iOS系统对于WebP的支持并不是特别理想,系统没有提供对应的支持。我们只能通过SDWebImage
来实现WebP图片的加载:
- 通过
pod 'SDWebImage/WebP'
让SDWebImage
支持WebP。 - 通过
sd_setImageWithURL
实现对WebP图片的加载。
总结
本文介绍了iOS中动图的加载方式及其原理,作为对动画的一个补充,动图在某些场合还是比较简单高效的。但逐帧动画相对于关键帧动画(对关键帧动画不了解的同学可以自行谷歌)确实性能差很多,因此大家谨慎选择。为了便于大家理解,我写了一个和本文配套的Demo:https://github.com/zjh171/WebPDemo,希望对大家有所帮助。
网友评论