iOS之加载Gif图片
Gif图片是非常常见的图片格式,尤其是在聊天的过程中,Gif表情使用地很频繁。但是iOS竟然没有现成的支持加载和播放Gif的类。
简单地汇总了一下,大概有以下几种方法:
一、加载本地Gif文件
1、使用UIWebView
// 读取gif图片数据
UIWebView *webView = [[UIWebView alloc] initWithFrame:CGRectMake(0,0,200,200)];
[self.view addSubview:webView];
NSString *path = [[NSBundle mainBundle] pathForResource:@"001" ofType:@"gif"];
/*
NSData *data = [NSData dataWithContentsOfFile:path];
使用loadData:MIMEType:textEncodingName: 则有警告
[webView loadData:data MIMEType:@"image/gif" textEncodingName:nil baseURL:nil];
*/
NSURL *url = [NSURL URLWithString:path];
[webView loadRequest:[NSURLRequest requestWithURL:url]];
但是使用UIWebView的弊端在于,不能设置Gif动画的播放时间。
2、将Gif拆分成多张图片,使用UIImageView播放
最好把所需要的Gif图片打包到Bundle文件内,如下图所示
- (NSArray *)animationImages
{
NSFileManager *fielM = [NSFileManager defaultManager];
NSString *path = [[NSBundle mainBundle] pathForResource:@"Loading" ofType:@"bundle"];
NSArray *arrays = [fielM contentsOfDirectoryAtPath:path error:nil];
NSMutableArray *imagesArr = [NSMutableArray array];
for (NSString *name in arrays) {
UIImage *image = [UIImage imageNamed:[(@"Loading.bundle") stringByAppendingPathComponent:name]];
if (image) {
[imagesArr addObject:image];
}
}
return imagesArr;
}
- (void)viewDidLoad {
[super viewDidLoad];
UIImageView *gifImageView = [[UIImageView alloc] initWithFrame:frame];
gifImageView.animationImages = [self animationImages]; //获取Gif图片列表
gifImageView.animationDuration = 5; //执行一次完整动画所需的时长
gifImageView.animationRepeatCount = 0; //动画重复次数
[gifImageView startAnimating];
[self.view addSubview:gifImageView];
}
3、使用SDWebImage
但是很遗憾,SDWebImage 的 sd_setImageWithURL:placeholderImage:这个方法是不能播放本地Gif的,它只能显示Gif的第一张图片而已。So,此方法行不通
UIImageView *gifImageView = [[UIImageView alloc] initWithFrame:frame];
[gifImageView sd_setImageWithURL:nil placeholderImage:[UIImage imageNamed:@"gifTest.gif"]];
其实,在SDWebImage这个库里有一个UIImage+GIF的类别,里面为UIImage扩展了三个方法:
@interface UIImage (GIF)
+ (IImage *)sd_animatedGIFNamed:(NSString *)name;
+ (UIImage *)sd_animatedGIFWithData:(NSData *)data;
- (UIImage *)sd_animatedImageByScalingAndCroppingToSize:(CGSize)size;
@end
大家一看就知道,我们要获取处理后的Gif图片,其实只要调用前面两个中的其中一个方法就行了
注意:第一个只需要传Gif的名字,而不需要带扩展名(如Gif图片名字为001@2x.gif,只需传001即可)
我们就使用第二个方法试一试效果:
NSString *path = [[NSBundle mainBundle] pathForResource:@"gifTest" ofType:@"gif"];
NSData *data = [NSData dataWithContentsOfFile:path];
UIImage *image = [UIImage sd_animatedGIFWithData:data];
gifImageView.image = image;
然后通过断点,我们看下获取到的image是个什么样的东东:
我们发现:
image的isa指针指向了_UIAnimatedImage ,说明它是一个叫作_UIAnimatedImage 的类(当然,这个_UIAnimatedImage 苹果是不会直接让我们使用的)
_images 表示:这个Gif包含了多少张图片
_duration表示:执行一次完整动画所需的时长
其实,动画执续时间_duration也可以更改!
我们来看下此方法的内部实现:
+ (UIImage *)sd_animatedGIFWithData:(NSData *)data {
if (!data) {
return nil;
}
CGImageSourceRef source = CGImageSourceCreateWithData((__bridge CFDataRef)data, NULL);
size_t count = CGImageSourceGetCount(source);
UIImage *animatedImage;
if (count <= 1) {
animatedImage = [[UIImage alloc] initWithData:data];
}
else {
NSMutableArray *images = [NSMutableArray array];
NSTimeInterval duration = 0.0f;
for (size_t i = 0; i < count; i++) {
CGImageRef image = CGImageSourceCreateImageAtIndex(source, i, NULL);
duration += [self sd_frameDurationAtIndex:i source:source];
[images addObject:[UIImage imageWithCGImage:image scale:[UIScreen mainScreen].scale orientation:UIImageOrientationUp]];
CGImageRelease(image);
}
if (!duration) {
duration = (1.0f / 10.0f) * count;
}
animatedImage = [UIImage animatedImageWithImages:images duration:duration];
}
CFRelease(source);
return animatedImage;
}
很明显,duration是可以随意更改的,只不过此方法设置了一个默认值
(duration = (1.0f / 10.0f) * count)
归根到底,创建新的动态的Image其实是调用了系统提供的一个UIImage的类方法而已:
UIImage *animatedImage = [UIImage animatedImageWithImages:images duration:duration];
二、加载网络Gif文件
加载网络的Gif文件就简单多了。最简单的方法,我们只需要使用SDWebImage 的 sd_setImageWithURL:这个方法传入Gif文件是url地址即可。
纠其原因:稍微仔细看了SDWebImage内部实现就可以清楚,大概是以下几个步骤:
1、SDWebImage根据url将Gif文件下载下来,格式为一个NSData
2、如果判断是Gif格式,则会调用** sd_animatedGIFWithData:** 将Data转换成我们需要的Gif格式
3、通过上面的方法二即可显示出Gif图片
UIImage *image = [UIImage sd_animatedGIFWithData:data];
gifImageView.image = image;
............................................................
总结
一、加载本地Gif文件
1、使用UIWebView不可以设置duration,其他两种方法都可设置。而且方法1的容器为UIWebView ,其余两种的容器都是大家熟悉的UIImageView
2、方法2和方法3需要对应看应用场景
如:下拉、上拉加载控件需要一个根据拉动距离设置特定的Image,则需要使用方法2
直接显示Gif图片,则使用方法3会更方便
二、加载网络Gif文件
直接使用SDWebImage 的 sd_setImageWithURL:这个方法传入Gif文件是url地址即可
............................................................
PS:简单小Demo
作者:镜花水月_I
链接:http://www.jianshu.com/p/f0530a75c7af
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
iOS之加载Gif图片的更多相关文章
- iOS网络加载图片缓存策略之ASIDownloadCache缓存优化
iOS网络加载图片缓存策略之ASIDownloadCache缓存优化 在我们实际工程中,很多情况需要从网络上加载图片,然后将图片在imageview中显示出来,但每次都要从网络上请求,会严重影响用 ...
- iOS WebView 加载本地资源(图片,文件等)
https://www.cnblogs.com/dhui69/p/5596917.html iOS WebView 加载本地资源(图片,文件等) NSString *path = [[NSBundle ...
- WebView加载HTML图片大小自适应与文章自动换行
http://www.brighttj.com/ios/ios-webview-load-html-image-adaptive.html 在很多App中都会使用到webview,尤其是在加载新闻内容 ...
- 简易仿ios菊花加载loading图
原文链接:https://mp.weixin.qq.com/s/wBbQgOfr59wntNK9ZJ5iRw 项目中经常会用到加载数据的loading显示图,除了设计根据app自身设计的动画loadi ...
- iOS webview加载时序和缓存问题总结
iOS webView的加载时序 UIWebView加载顺序: - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSU ...
- iOS开发——加载、滑动翻阅大量图片解决方案详解
加载.滑动翻阅大量图片解决方案详解 今天分享一下私人相册中,读取加载.滑动翻阅大量图片解决方案,我想强调的是,编程思想无关乎平台限制. 我要详细说一下,在缩略图界面点击任意小缩略图后,进入高清 ...
- Android ListView 图片异步加载和图片内存缓存
开发Android应用经常需要处理图片的加载问题.因为图片一般都是存放在服务器端,需要联网去加载,而这又是一个比较耗时的过程,所以Android中都是通过开启一个异步线程去加载.为了增加用户体验,给用 ...
- WPF中加载高分辨率图片性能优化
在最近的项目中,遇到一个关于WPF中同时加载多张图片时,内存占用非常高的问题. 问题背景: 在一个ListView中同时加载多张图片,注意:我们需要加载的图片分辨率非常高. 代码: XAML: < ...
- Fresco 使用笔记(一):加载gif图片并播放
项目总结 --------------------------------------------------------------------- 前言: 项目中图文混合使用的太多太多了,但是绝大部 ...
随机推荐
- 【值得收藏】一份非常完整的Mysql规范
做一个积极的人 编码.改bug.提升自己 我有一个乐园,面向编程,春暖花开! 本文从芋道源码转载,在原有内容基础上结合阿里巴巴Java开发手册中Mysql数据库章节的介绍,加上自己的理解和说明,整理而 ...
- Java中十个常见的违规编码
摘要:作者Veera Sundar在清理代码工作时发现一些常见的违规编码,因此,Veera Sundar把针对常见的一些违规编码总结成一份列表,以便帮助Java爱好者提高代码的质量和可维护性. 最近, ...
- GIF录制
韩梦飞沙 韩亚飞 313134555@qq.com yue31313 han_meng_fei_sha ============= 快手电脑版_快手_gif快手电脑版 GIF动画录制工具|GI ...
- POJ.1769.Minimizing maximizer(线段树 DP)
题目链接 /* 题意:有m个区间,问最少要多少个区间能覆盖[1,n] 注:区间要按原区间的顺序,不能用排序贪心做 设dp[i]表示最右端端点为i时的最小值 dp[e[i]]=min{dp[s[i]]~ ...
- [NOIp2013普及组]车站分级
思路: 对于每一趟车,将区间内所有经停的站和所有未经停的站连一条边,表示前者优先级一定高于后者,然后用Kahn跑一遍拓扑排序即可.然而这样会创造大量多余的边,会TLE1个点.考虑一种优化:因为每趟车本 ...
- API使用
至于什么是API我想不用累述了,百科上面有,其实就是别人写好了一大堆功能性的代码,然后你可以拿来用.一般的二次开发都是使用api来开发,包括现在的高级程序设计,很少自己写基本代码了,像.netFram ...
- C# Invoke方法
留下备用,具体如下: Invoke()方法是U3D的一种委托机制: 1.它可以在脚本的生命周期(Start.Update.OnGUI.FixedUpdate.LateUpdate)中调用. 2.Inv ...
- springboot之启动原理解析及源码阅读
前言 SpringBoot为我们做的自动配置,确实方便快捷,但是对于新手来说,如果不大懂SpringBoot内部启动原理,以后难免会吃亏.所以这次博主就跟你们一起一步步揭开SpringBoot的神秘面 ...
- 奇怪吸引子---NoseHoover
奇怪吸引子是混沌学的重要组成理论,用于演化过程的终极状态,具有如下特征:终极性.稳定性.吸引性.吸引子是一个数学概念,描写运动的收敛类型.它是指这样的一个集合,当时间趋于无穷大时,在任何一个有界集上出 ...
- Android APK反编译详解(附图) (转)
这段时间在学Android应用开发,在想既然是用Java开发的应该很好反编译从而得到源代码吧,google了一下,确实很简单,以下是我的实践过程. 在此郑重声明,贴出来的目的不是为了去破解人家的软件, ...