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图片并播放
项目总结 --------------------------------------------------------------------- 前言: 项目中图文混合使用的太多太多了,但是绝大部 ...
随机推荐
- P1356 数列的整数性
P1356 数列的整数性打的骗分,在多组数据的情况下还能骗到分,可以了.又TMD是dp.f[i][j]表示+-第i个数能否达到%p后的余数j,如果f[n][0]==true就可以. #include& ...
- epoll使用详解
目录 epoll介绍 Epoll的优点: 1.支持一个进程打开大数目的socket描述符(FD) 2.IO效率不随FD数目增加而线性下降 3.支持边缘触发模式 4.使用mmap加速内核与用户空间的消息 ...
- shell 环境变量
Ubuntu系统设置的环境变量 .profile .bashrc 在 .profile中 有一段代码: if [ -d "$HOME/bin" ] ; then PATH=&quo ...
- vue 之 加载 iframe 的处理
vue中加载 iframe 会出现跨域问题.以及iframe的高度自适应问题,以下是本人的解决办法: getGoodsContentHtml---- 你的iframe页面的地址, 如不同域的情况下 ...
- VB定义变量
定义变量可以使用显式或隐式两种方式定义: 1.显式定义:Dim 变量名 As 类型 2.隐式定义:使用类型说明符 类型说明符如下: %——整型 &——长整型 !——单精度浮点数 #——双精度浮 ...
- Scratch儿童项目式编程--接球游戏 Scratch children program programming - catching a ball
Scratch儿童项目式编程--接球游戏 Scratch children program programming - catching a ball 作者:韩梦飞沙 Author:han_meng_ ...
- Java 之递归遍历目录
Java 之递归遍历目录 一.内容 输出指定目录(文件夹)下的所有文件(包括目录)的绝对路径 二.源代码:RecursiveListDirectory.java package cn.com.zfc. ...
- Codeforces.542E.Playing on Graph(二分图)
题目链接 \(Description\) 给出一个n个点m条边的无向图. 你每次需要选择两个没有边相连的点,将它们合并为一个新点,直到这张图变成了一条链. 最大化这条链的长度,或输出无解. n< ...
- 潭州课堂25班:Ph201805201 爬虫基础 第六课 选择器 (课堂笔记)
HTML解析库BeautifulSoup4 BeautifulSoup 是一个可以从HTML或XML文件中提取数据的Python库,它的使用方式相对于正则来说更加的简单方便,常常能够节省我们大量的时间 ...
- 数据结构+算法面试100题~~~摘自CSDN
数据结构+算法面试100题~~~摘自CSDN,作者July 1.把二元查找树转变成排序的双向链表(树) 题目:输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表.要求不能创建任何新的结点,只调 ...