图片分为静态和动态两种,图片的格式有很多种,在开发中比较常见的是.png和.jpg的静态图片,但有的时候在App中需要播放动态图片,比如.gif格式的小表情头像,在IOS中并没有提供直接显示动态图片的控件,下面就介绍几种显示动态图片的方式。
<一> UIImageView用来显示图片, 使用UIImageView中的动画数组来实现图片的动画效果
1 //创建UIImageView,添加到界面 2 UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(20, 20, 100, 100)]; 3 [self.view addSubview:imageView]; 4 //创建一个数组,数组中按顺序添加要播放的图片(图片为静态的图片) 5 NSMutableArray *imgArray = [NSMutableArray array]; 6 for (int i=1; i<7; i++) { 7 UIImage *image = [UIImage imageNamed:[NSString stringWithFormat:@"clock%02d.png",i]]; 8 [imgArray addObject:image]; 9 } 10 //把存有UIImage的数组赋给动画图片数组 11 imageView.animationImages = imgArray; 12 //设置执行一次完整动画的时长 13 imageView.animationDuration = 6*0.15; 14 //动画重复次数 (0为重复播放) 15 imageView.animationRepeatCount = 0; 16 //开始播放动画 17 [imageView startAnimating]; 18 //停止播放动画 - (void)stopAnimating; 19 //判断是否正在执行动画 - (BOOL)isAnimating;
<二> 用UIWebView来显示动态图片
1 //得到图片的路径 2 NSString *path = [[NSBundle mainBundle] pathForResource:@"happy" ofType:@"gif"]; 3 //将图片转为NSData 4 NSData *gifData = [NSData dataWithContentsOfFile:path]; 5 //创建一个webView,添加到界面 6 UIWebView *webView = [[UIWebView alloc] initWithFrame:CGRectMake(0, 150, 200, 200)]; 7 [self.view addSubview:webView]; 8 //自动调整尺寸 9 webView.scalesPageToFit = YES; 10 //禁止滚动 11 webView.scrollView.scrollEnabled = NO; 12 //设置透明效果 13 webView.backgroundColor = [UIColor clearColor]; 14 webView.opaque = 0; 15 //加载数据 16 [webView loadData:gifData MIMEType:@"image/gif" textEncodingName:nil baseURL:nil];
<三> 用第三方GifView显示本地图片
GifView是封装好的一个类,可以直接导入程序中,然后创建对象,来显示动态图片;需要注意的是,GifView是MRC的,因此在ARC工程中使用它,需要修改标记 –fno-objc-arc
1 //方式一:显示本地Gif图片 2 //将图片转为NSData数据 3 NSData *localData = [NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"bird" ofType:@"gif"]]; 4 //创建一个第三方的View显示图片 5 GifView *dataView = [[GifView alloc] initWithFrame:CGRectMake(0, 300, 200, 100) data:localData]; 6 [self.view addSubview:dataView]; 7 //方式二:显示本地Gif图片 8 //得到图片的路径 9 NSString *path = [[NSBundle mainBundle] pathForResource:@"cat" ofType:@"gif"]; 10 //创建一个第三方的View显示图片 11 GifView *dataView2 = [[GifView alloc] initWithFrame:CGRectMake(200, 300, 150, 100) filePath:path]; 12 [self.view addSubview:dataView2]; 13 //方式三:显示从网络获取的Gif图片 14 // 网络图片 15 NSData *urlData = [NSData dataWithContentsOfURL:[NSURL URLWithString:@"http://pic19.nipic.com/20120222/8072717_124734762000_2.gif"]]; 16 //创建一个第三方的View显示图片 17 GifView *dataViewWeb = [[GifView alloc] initWithFrame:CGRectMake(20, 420, 280, 100) data:urlData]; 18 [self.view addSubview:dataViewWeb];
GifView.h
1 #import <UIKit/UIKit.h> 2 #import <ImageIO/ImageIO.h> 3 @interface GifView : UIView { 4 CGImageSourceRef gif; 5 NSDictionary *gifProperties; 6 size_t index; 7 size_t count; 8 NSTimer *timer; 9 } 10 - (id)initWithFrame:(CGRect)frame filePath:(NSString *)_filePath; 11 - (id)initWithFrame:(CGRect)frame data:(NSData *)_data; 12 @end
GifView.m
1 #import "GifView.h" 2 #import <QuartzCore/QuartzCore.h> 3 @implementation GifView 4 - (id)initWithFrame:(CGRect)frame filePath:(NSString *)_filePath{ 5 self = [super initWithFrame:frame]; 6 if (self) { 7 gifProperties = [[NSDictionary dictionaryWithObject:[NSDictionary dictionaryWithObject:[NSNumber numberWithInt:0] forKey:(NSString *)kCGImagePropertyGIFLoopCount] 8 forKey:(NSString *)kCGImagePropertyGIFDictionary] retain]; 9 gif = CGImageSourceCreateWithURL((CFURLRef)[NSURL fileURLWithPath:_filePath], (CFDictionaryRef)gifProperties); 10 count =CGImageSourceGetCount(gif); 11 timer = [NSTimer scheduledTimerWithTimeInterval:0.12 target:self selector:@selector(play) userInfo:nil repeats:YES]; 12 [timer fire]; 13 } 14 return self; 15 } 16 - (id)initWithFrame:(CGRect)frame data:(NSData *)_data{ 17 self = [super initWithFrame:frame]; 18 if (self) { 19 gifProperties = [[NSDictionary dictionaryWithObject:[NSDictionary dictionaryWithObject:[NSNumber numberWithInt:0] forKey:(NSString *)kCGImagePropertyGIFLoopCount] 20 forKey:(NSString *)kCGImagePropertyGIFDictionary] retain]; 21 gif = CGImageSourceCreateWithData((CFDataRef)_data, (CFDictionaryRef)gifProperties); 22 count =CGImageSourceGetCount(gif); 23 timer = [NSTimer scheduledTimerWithTimeInterval:0.12 target:self selector:@selector(play) userInfo:nil repeats:YES]; 24 [timer fire]; 25 } 26 return self; 27 } 28 -(void)play 29 { 30 index ++; 31 index = index%count; 32 CGImageRef ref = CGImageSourceCreateImageAtIndex(gif, index, (CFDictionaryRef)gifProperties); 33 self.layer.contents = (id)ref; 34 CFRelease(ref); 35 } 36 -(void)removeFromSuperview 37 { 38 NSLog(@"removeFromSuperview"); 39 [timer invalidate]; 40 timer = nil; 41 [super removeFromSuperview]; 42 } 43 - (void)dealloc { 44 NSLog(@"dealloc"); 45 CFRelease(gif); 46 [gifProperties release]; 47 [super dealloc]; 48 } 49 @end
<四> 总结
1、通过UIImageView显示动画效果,实际上是把动态的图拆成了一组静态的图,放到数组中,播放的时候依次从数组中取出。如果播放的图片比较少占得内存比较小或者比较常用(比如工具条上一直显示的动态小图标),可以选择用imageNamed:方式获取图片,但是通过这种方式加到内存中,使用结束,不会自己释放,多次播放动画会造成内存溢出问题。因此,对于大图或经常更换的图,在取图片的时候可以选择imageWithContentsOfFile:方式获取图片,优化内存。
2、使用UIWebView显示图片需要注意显示图片的尺寸与UIWebView尺寸的设置,如果只是为了显示动态图片,可以禁止UIWebView滚动。在显示动态图片的时候,即使是动图的背景处为透明,默认显示出来是白色背景,这个时候需要手动设置UIWebView的透明才能达到显示动图背景透明的效果。
3、第三方的GifView使用比较简单,把类导入即可。但是GifView是MRC的,因此在ARC环境下,需要对类进行标识。
4、UIImageView与第三方的GifView都是通过定时器来控制图片模拟的动画,播放的时候是设置每一帧的时长,因此在使用的时候,要尽量与动图原本的时长靠近,不然动画效果会有些奇怪。而通过UIWebView加载Gif动图的时候会保持原有的帧速,不需要再次设置。