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文件内,如下图所示

Loading.png
- (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

但是很遗憾,SDWebImagesd_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是个什么样的东东:

img.png

我们发现:

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文件就简单多了。最简单的方法,我们只需要使用SDWebImagesd_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文件

直接使用SDWebImagesd_setImageWithURL:这个方法传入Gif文件是url地址即可

............................................................

PS:简单小Demo


作者:镜花水月_I
链接:http://www.jianshu.com/p/f0530a75c7af
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

iOS之加载Gif图片的更多相关文章

  1. iOS网络加载图片缓存策略之ASIDownloadCache缓存优化

    iOS网络加载图片缓存策略之ASIDownloadCache缓存优化   在我们实际工程中,很多情况需要从网络上加载图片,然后将图片在imageview中显示出来,但每次都要从网络上请求,会严重影响用 ...

  2. iOS WebView 加载本地资源(图片,文件等)

    https://www.cnblogs.com/dhui69/p/5596917.html iOS WebView 加载本地资源(图片,文件等) NSString *path = [[NSBundle ...

  3. WebView加载HTML图片大小自适应与文章自动换行

    http://www.brighttj.com/ios/ios-webview-load-html-image-adaptive.html 在很多App中都会使用到webview,尤其是在加载新闻内容 ...

  4. 简易仿ios菊花加载loading图

    原文链接:https://mp.weixin.qq.com/s/wBbQgOfr59wntNK9ZJ5iRw 项目中经常会用到加载数据的loading显示图,除了设计根据app自身设计的动画loadi ...

  5. iOS webview加载时序和缓存问题总结

    iOS webView的加载时序 UIWebView加载顺序: - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSU ...

  6. iOS开发——加载、滑动翻阅大量图片解决方案详解

    加载.滑动翻阅大量图片解决方案详解     今天分享一下私人相册中,读取加载.滑动翻阅大量图片解决方案,我想强调的是,编程思想无关乎平台限制. 我要详细说一下,在缩略图界面点击任意小缩略图后,进入高清 ...

  7. Android ListView 图片异步加载和图片内存缓存

    开发Android应用经常需要处理图片的加载问题.因为图片一般都是存放在服务器端,需要联网去加载,而这又是一个比较耗时的过程,所以Android中都是通过开启一个异步线程去加载.为了增加用户体验,给用 ...

  8. WPF中加载高分辨率图片性能优化

    在最近的项目中,遇到一个关于WPF中同时加载多张图片时,内存占用非常高的问题. 问题背景: 在一个ListView中同时加载多张图片,注意:我们需要加载的图片分辨率非常高. 代码: XAML: < ...

  9. Fresco 使用笔记(一):加载gif图片并播放

    项目总结 --------------------------------------------------------------------- 前言: 项目中图文混合使用的太多太多了,但是绝大部 ...

随机推荐

  1. HDU 2955_Robberies 小偷抢银行【01背包】

    <题目链接> 题意: 先是给出几组数据,每组数据第一行是总被抓概率p(最后求得的总概率必须小于他,否则被抓),然后是想抢的银行数n.然后n行,每行分别是该银行能抢的钱数m[i]和被抓的概率 ...

  2. P2648 赚钱

    P2648 赚钱对于不知道起点在哪里的最短路,先建立一个超级源点,然后从超级源点跑最长路,并判正环即可. #include<iostream> #include<cstdio> ...

  3. [漏洞分析]thinkphp 5.1.25 insert、insetAll、update方法注入

    0x00 前言 这个洞,早在9月29号的时候我提交给先知,那时候tp还是5.1.25的版本,天还很蓝,我也还很年轻.时至今日这个洞依旧没有审核,而tp在这期间都已经更新到了5.1.29.在最近我去跟踪 ...

  4. 【xxl-job】轻松实现分布式定时任务demo实例

    [项目描述]前段时间专门独立了一个spring boot服务,用于做和第三方erp系统的对接工作.此服务的第一个需求工作就是可以通过不同的规则,设置不同的定时任务,从而获取erp系统的商品数据.所以, ...

  5. (华中科大)江南雨烟 C++ STL 专栏

    本文转载来自,华中科技大学江南雨烟的C/C++专栏部分STL剖析文章,以作学习之用. [1]  [C++ STL学习之一]容器的共通能力和共通操作总结 [2]  [C++ STL学习之二]容器vect ...

  6. 移动端html页面优化

    对于访问量大的网站来说,前端的优化是必须的,即使是优化1KB的大小对其影响也很大,下面来看看来自ISUX的米随随讲讲移动手机平台的HTML5前端优化,或许对你有帮助和启发. 概述 1. PC优化手段在 ...

  7. restful开发API

    http://blog.csdn.net/kkkloveyou/article/details/21391033 小示例http://blog.csdn.net/u011645059/article/ ...

  8. SimpleDateFormat 格式化参数说明

    字母 日期或时间元素 表示 示例 G Era 标志符 Text AD y 年 Year 1996; 96 M 年中的月份 Month July; Jul; 07 w 年中的周数 Number 27 W ...

  9. JTAG 引脚自动识别 JTAG Finder, JTAG Pinout Tool, JTAG Pin Finder, JTAG pinout detector, JTAGULATOR, Easy-JTAG, JTAG Enumeration

    JTAG Finder Figuring out the JTAG Pinouts on a Device is usually the most time-consuming and frustra ...

  10. jconsole工具使用

    Jconsole,Java Monitoring and Management Console. Jconsole是JDK自带的监控工具,在JDK/bin目录下可以找到.它用于连接正在运行的本地或者远 ...