iOS 播放gif动态图的方式探讨
原文链接:http://my.oschina.net/u/2340880/blog/608560
摘要
iOS中没有现成的接口来展示gif动态图,但可以通过其他的方式来处理gif图的展示。
iOS中播放gif动态图的方式探讨
一、引言
在iOS开发中,UIImageView类专门来负责图片数据的渲染,并且UIImageView也有帧动画的方法来播放一组图片,但是对于gif类型的数据,UIImageView中并没有现成的接口提供给开发者使用,在iOS中一般可以通过两种方式来播放gif动态图,一种方式是通过ImageIO框架中的方法将gif文件中的数据进行解析,再使用coreAnimation核心动画来播放gif动画,另一种方式计较简单,可以直接通过webView来渲染gif图。
二、为原生的UIImageView添加类别来支持gif动态图的播放
gif动态图文件中包含了一组图片及其信息,信息主要记录着每一帧图片播放的时间,我们如果获取到了gif文件中所有的图片同时又获取到每一帧图片播放的时间,就可以为UIImageView添加核心动画的方法来让其播放gif的内容了。
首先解析gif文件中的数据,代码如下:
//要引入ImageIO库
#import <ImageIO/ImageIO.h>
//解析gif文件数据的方法 block中会将解析的数据传递出来
-(void)getGifImageWithUrk:(NSURL *)url
returnData:(void(^)(NSArray<UIImage *> * imageArray,
NSArray<NSNumber *>*timeArray,
CGFloat totalTime,
NSArray<NSNumber *>* widths,
NSArray<NSNumber *>* heights))dataBlock{
//通过文件的url来将gif文件读取为图片数据引用
CGImageSourceRef source = CGImageSourceCreateWithURL((CFURLRef)url, NULL);
//获取gif文件中图片的个数
size_t count = CGImageSourceGetCount(source);
//定义一个变量记录gif播放一轮的时间
float allTime=0;
//存放所有图片
NSMutableArray * imageArray = [[NSMutableArray alloc]init];
//存放每一帧播放的时间
NSMutableArray * timeArray = [[NSMutableArray alloc]init];
//存放每张图片的宽度 (一般在一个gif文件中,所有图片尺寸都会一样)
NSMutableArray * widthArray = [[NSMutableArray alloc]init];
//存放每张图片的高度
NSMutableArray * heightArray = [[NSMutableArray alloc]init];
//遍历
for (size_t i=0; i<count; i++) {
CGImageRef image = CGImageSourceCreateImageAtIndex(source, i, NULL);
[imageArray addObject:(__bridge UIImage *)(image)];
CGImageRelease(image);
//获取图片信息
NSDictionary * info = (__bridge NSDictionary*)CGImageSourceCopyPropertiesAtIndex(source, i, NULL);
CGFloat width = [[info objectForKey:(__bridge NSString *)kCGImagePropertyPixelWidth] floatValue];
CGFloat height = [[info objectForKey:(__bridge NSString *)kCGImagePropertyPixelHeight] floatValue];
[widthArray addObject:[NSNumber numberWithFloat:width]];
[heightArray addObject:[NSNumber numberWithFloat:height]];
NSDictionary * timeDic = [info objectForKey:(__bridge NSString *)kCGImagePropertyGIFDictionary];
CGFloat time = [[timeDic objectForKey:(__bridge NSString *)kCGImagePropertyGIFDelayTime]floatValue];
allTime+=time;
[timeArray addObject:[NSNumber numberWithFloat:time]];
}
dataBlock(imageArray,timeArray,allTime,widthArray,heightArray);
}
为UIImageView添加一个设置gif图内容的方法:
-(void)yh_setImage:(NSURL *)imageUrl{
__weak id __self = self;
[self getGifImageWithUrk:imageUrl returnData:^(NSArray<UIImage *> *imageArray, NSArray<NSNumber *> *timeArray, CGFloat totalTime, NSArray<NSNumber *> *widths, NSArray<NSNumber *> *heights) {
//添加帧动画
CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"contents"];
NSMutableArray * times = [[NSMutableArray alloc]init];
float currentTime = 0;
//设置每一帧的时间占比
for (int i=0; i<imageArray.count; i++) {
[times addObject:[NSNumber numberWithFloat:currentTime/totalTime]];
currentTime+=[timeArray[i] floatValue];
}
[animation setKeyTimes:times];
[animation setValues:imageArray];
[animation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear]];
//设置循环
animation.repeatCount= MAXFLOAT;
//设置播放总时长
animation.duration = totalTime;
//Layer层添加
[[(UIImageView *)__self layer]addAnimation:animation forKey:@"gifAnimation"];
}];
}
使用代码示例如下:
UIImageView * imageView = [[UIImageView alloc]initWithFrame:CGRectMake(0,0 , 320, 200)];
NSURL * url = [[NSURL alloc]initFileURLWithPath:[[NSBundle mainBundle] pathForResource:imageName ofType:nil]];
[imageView yh_setImage:url];
[self.view addSubview:imageView];
三、使用UIWebView来加载gif动态图数据
iOS中的UIWebView功能十分强大,可以通过UIWebView为载体,来展示gif图。并且这种方法也十分简单,代码如下:
//读取gif数据
NSData *gifData = [NSData dataWithContentsOfURL:imageUrl];
UIWebView *webView = [[UIWebView alloc] initWithFrame:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)];
//取消回弹效果
webView.scrollView.bounces=NO;
webView.backgroundColor = [UIColor clearColor];
//设置缩放模式
webView.scalesPageToFit = YES;
//用webView加载数据
[webView loadData:gifData MIMEType:@"image/gif" textEncodingName:nil baseURL:nil];
四、两种加载gif动态图方式的优劣
经过测试,从加载速度上来说,通过UIImageView类别加载的方式更加快速,UIWebView的方式加载时间会稍长,但是从性能上来比较,WebView的方式性能更优,播放的gif动态图更加流畅。在开发中,可以根据需求,适当选择,例如虽然WebView加载的方式性能更好,但是在许多情况下,原生的UIImageView能够更加自由的让开发者进行扩展。
iOS 播放gif动态图的方式探讨的更多相关文章
- iOS 播放GIF动态图片!!!!!
////////////////////////////////////////////////////////////////////////////////////////// //// Vie ...
- iOS制作gif动态图
NSMutableArray * array = [NSMutableArray array]; for (int i = 1; i < 6; i++) { NSString * string ...
- iOS保存gif动态图
- (void)saveImageToPhotos:(NSData*)gifData { /***注意先倒入库 #import <AssetsLibrary/AssetsLibrary.h> ...
- iOS 中使用.9图
背景 .9图来源于Android.为了设计出一套图,兼容Android和iOS,使用.9图的方式来对图片进行拉伸以适应不同的屏幕.在iOS中没有.9图的概念,只能先了解Android的.9图再进行模拟 ...
- iOS播放gif图方式
转发:http://www.cnblogs.com/jerehedu/ 图片分为静态和动态两种,图片的格式有很多种,在开发中比较常见的是.png和.jpg的静态图片,但有的时候在App中需要播放动态图 ...
- iOS播放动态GIF图片
<转> 图片分为静态和动态两种,图片的格式有很多种,在开发中比较常见的是.png和.jpg的静态图片,但有的时候在App中需要播放动态图片,比如.gif格式的小表情头像,在IOS中并没有提 ...
- IOS 播放动态Gif图片
图片分为静态和动态两种,图片的格式有很多种,在开发中比较常见的是.png和.jpg的静态图片,但有的时候在App中需要播放动态图片,比如.gif格式的小表情头像,在IOS中并没有提供直接显示动态图片的 ...
- C# 动态创建SQL数据库(二) 在.net core web项目中生成二维码 后台Post/Get 请求接口 方式 WebForm 页面ajax 请求后台页面 方法 实现输入框小数多 自动进位展示,编辑时实际值不变 快速掌握Gif动态图实现代码 C#处理和对接HTTP接口请求
C# 动态创建SQL数据库(二) 使用Entity Framework 创建数据库与表 前面文章有说到使用SQL语句动态创建数据库与数据表,这次直接使用Entriy Framwork 的ORM对象关 ...
- iOS开发中在UIWebView中添加Gif动态图
开发是一件很有趣的事,偶尔在程序中添加一些小东西,会给你的应用增色不少.比如,当你的某些功能暂时还不准备上线时,可以先一个放展示Gif动态图的UIWebView上去,既可以告诉用户APP以后会有的功能 ...
随机推荐
- PCL点云曲面重建(1)
在测量较小的数据时会产生一些误差,这些误差所造成的不规则数据如果直接拿来曲面重建的话,会使得重建的曲面不光滑或者有漏洞,可以采用对数据重采样来解决这样问题,通过对周围的数据点进行高阶多项式插值来重建表 ...
- CNDS账号密码
您购买的CSDN 100下载积分 发货如下:CSDN账号:masunwei0961CSDN密码:sangsang3邮箱:lao42981894zh@163.com邮箱密码:songsong3
- html传值及接收传值
传值:url?para1=value1¶2=value2 接收传值: <script type="text/javascript"> function ...
- pymysql和MySQLdb
MySQLdb创建mysql数据库表 其实mysqldb创建表是有限制的,要求是5.1-5.5版本 pymsql是Python中操作MySQL的模块,其使用方法和MySQLdb几乎相同. 1.下载 首 ...
- C++ 面向对象 类成员函数this指针
每个类成员函数都只涉及一个对象, 即调用它的对象. 但有时候方法可能涉及到两个对象, 在这种情况下需要使用C++ 的 this 指针 假设将方法命名为topval(), 则函数调用stock1.top ...
- 【转】【Centos】nginx配置:location配置方法及实例详解
location匹配的是nginx的哪个变量? $request_uri location的匹配种类有哪些? 格式 location [ 空格 | = | ~ | ~* |^~ | !~ | !~* ...
- Zend Framework2 入门教程(转)
转载自: http://my.oschina.net/lai1362000/blog/201301 重申:这本书作者的截图我都放上去了,没侵权啊. 别问那么多,我只是一个安静的搬砖工. 摘要 Zend ...
- MyBatis环境配置及入门
Mybatis 开发环境搭建,选择: MyEclipse8.5 版本,mysql 5.5, jdk 1.8, mybatis3.2.3.jar 包.这些软件工具均可以到各自的官方网站上下载. 整个过程 ...
- 利用CA私钥和证书创建中间CA
本文借助实验环境下创建的root CA私钥和证书进一步创建中间CA.为了便于区分,我们将创建中间CA(intermediate CA)的CA称为根CA(root CA). 关于如何使用OpenSSL创 ...
- Java Decompiler Plugin For Eclipse IDE
1. 下载JAD , 1.5.8版本的jad在 http://www.softpedia.com/progDownload/JAD-Download-85911.html 将展开后的jad.exe放到 ...