iOS中播放gif动态图

一、引言

在iOS开发中,UIImageView类专门来负责图片数据的渲染,并且UIImageView也有帧动画的方法来播放一组图片,但是对于gif类型的数据,UIImageView中并没有现成的接口提供给开发者使用,在iOS中一般可以通过两种方式来播放gif动态图,一种方式是通过ImageIO框架中的方法将gif文件中的数据进行解析,再使用coreAnimation核心动画来播放gif动画,另一种方式计较简单,可以直接通过webView来渲染gif图。

二、为原生的UIImageView添加类别来支持gif动态图的播放

gif动态图文件中包含了一组图片及其信息,信息主要记录着每一帧图片播放的时间,我们如果获取到了gif文件中所有的图片同时又获取到每一帧图片播放的时间,就可以为UIImageView添加核心动画的方法来让其播放gif的内容了。

-(void)getGifImageWithUrk:(NSURL*)url returnData:(void(^)(

NSArray * imageArray,

NSArray*timeArray,

CGFloat totalTime,

NSArray* widths,

NSArray* heights))dataBlock{

//通过文件的url来将gif文件读取为图片数据引用

CGImageSourceRef source =CGImageSourceCreateWithURL((CFURLRef)url,NULL);

//获取gif文件中图片的个数

size_t count =CGImageSourceGetCount(source);

//定义一个变量记录gif播放一轮的时间

float allTime=0;

//存放所有图片

NSMutableArray* imageArray = [[NSMutableArrayalloc]init];

//存放每一帧播放的时间

NSMutableArray* timeArray = [[NSMutableArrayalloc]init];

//存放每张图片的宽度 (一般在一个gif文件中,所有图片尺寸都会一样)

NSMutableArray* widthArray = [[NSMutableArrayalloc]init];

//存放每张图片的高度

NSMutableArray* heightArray = [[NSMutableArrayalloc]init];

//遍历

for(size_t i=0; i<count;i++){

CGImageRef image = CGImageSourceCreatImageAtIndex(sources,NULL);

[imageArray addObject:(_bridge UIImage*)(image)];

CGImageRelease(image)

//获取图片信息

NSDictionary *info =(_bridge NSDictionary*)CGImageSourceCopyPropertiesAtIndex(sources,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 NNString *)kCGImagePropertyGIFDictionary];

CGFloat time = [[timeDic objectForKey:(_bridge NNString*)kCGImagePropertyGIFDelatime] floatValue];

allTime +=time;

[timeArray addObject:[NSnumber numberWithFloat:time]];

CFRelease(info)

}

CFRelease(source);

dataBlock(imageArray,timeArray,allTime,widthArray,heightArray)

}

为UIImageView 添加一个设置gif图内容的方法

-(void)setImage:(NSURL*)imageUrl{

__weak id __self = self;

[self getGifImageWithUrk:imageUrl returnData:^(NSArray *imageArray,NSArray *timeArray,CGFloattotalTime,NSArray *widths,NSArray *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 setTimingFunchtion:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear]];

//设置循环

animation.repeatCount = MaxFLOAT;

//设置播放总时长

animation.duration = totalTime;

[[(UIImageView*)_self layer]  addAnimation:animation forKey:@"gifAnimation"];

}]

}

三、使用UIwebView来加载gif动态图数据

NSData *gifData = [ NSData dataWithContentsOfURL:imageUrl];

WKWebView *wkbview = [WkWebView alloc]initWithFrame:CGRectMake(0,0,self.frame.size.width,self.frame.size.height);

wkbview.backgroundColor =[UIColor clearColor];

wkbview.scalesPageToFit = YES;

[wkbview loadData:gitData MIMEType:@"image/gif" textEncodingName:nil baseURL:nil]

经过测试,从加载速度上来说,通过UIImageView类别加载的方式更加快速,UIWebView的方式加载时间会稍长,但是从性能上来比较,WebView的方式性能更优,播放的gif动态图更加流畅。在开发中,可以根据需求,适当选择,例如虽然WebView加载的方式性能更好,但是在许多情况下,原生的UIImageView能够更加自由的让开发者进行扩展


参考牛人,珲少的文章:https://my.oschina.net/u/2340880/blog/608560;

推荐阅读更多精彩内容