配色: 字号:
iOS开发中实现显示gif图片的方法
2016-11-08 | 阅:  转:  |  分享 
  
iOS开发中实现显示gif图片的方法

这篇文章主要介绍了iOS开发中实现显示gif图片的方法,代码基于传统的Objective-C,需要的朋友可以参考下

我们知道Gif是由一阵阵画面组成的,而且每一帧画面播放的时常可能会不相等,观察上面两个例子,发现他们都没有对Gif中每一帧的显示时常做处理,这样的结果就是整个Gif中每一帧画面都是以固定的速度向前播放,很显然这并不总会符合需求。



于是自己写一个解析Gif的工具类,解决每一帧画面并遵循每一帧所对应的显示时间进行播放。



程序的思路如下:



1、首先使用ImageIO库中的CGImageSource家在Gif文件。



2、通过CGImageSource获取到Gif文件中的总的帧数,以及每一帧的显示时间。



3、通过CAKeyframeAnimation来完成Gif动画的播放。



下面直接上我写的解析和播放Gif的工具类的代码:

复制代码代码如下:

//

//SvGifView.h

//SvGifSample

//

//Createdbymapleon3/28/13.

//Copyright(c)2013smileEvday.Allrightsreserved.

//



#import

@interfaceSvGifView:UIView



/

@briefdesingatedinitializer

/

-(id)initWithCenter:(CGPoint)centerfileURL:(NSURL)fileURL;

/

@briefstartGifAnimation

/

-(void)startGif;

/

@briefstopGifAnimation

/

-(void)stopGif;

/

@briefgetframesimage(CGImageRef)inGif

/

+(NSArray)framesInGif:(NSURL)fileURL;



@end



//

//SvGifView.m

//SvGifSample

//

//Createdbymapleon3/28/13.

//Copyright(c)2013smileEvday.Allrightsreserved.

//

#import"SvGifView.h"

#import

#import

/

@briefresolvinggifinformation

/

voidgetFrameInfo(CFURLRefurl,NSMutableArrayframes,NSMutableArraydelayTimes,CGFloattotalTime,CGFloatgifWidth,CGFloatgifHeight)

{

CGImageSourceRefgifSource=CGImageSourceCreateWithURL(url,NULL);



//getframecount

size_tframeCount=CGImageSourceGetCount(gifSource);

for(size_ti=0;i
//geteachframe

CGImageRefframe=CGImageSourceCreateImageAtIndex(gifSource,i,NULL);

[framesaddObject:(id)frame];

CGImageRelease(frame);



//getgifinfowitheachframe

NSDictionarydict=(NSDictionary)CGImageSourceCopyPropertiesAtIndex(gifSource,i,NULL);

NSLog(@"kCGImagePropertyGIFDictionary%@",[dictvalueForKey:(NSString)kCGImagePropertyGIFDictionary]);



//getgifsize

if(gifWidth!=NULL&&gifHeight!=NULL){

gifWidth=[[dictvalueForKey:(NSString)kCGImagePropertyPixelWidth]floatValue];

gifHeight=[[dictvalueForKey:(NSString)kCGImagePropertyPixelHeight]floatValue];

}



//kCGImagePropertyGIFDictionary中kCGImagePropertyGIFDelayTime,kCGImagePropertyGIFUnclampedDelayTime值是一样的

NSDictionarygifDict=[dictvalueForKey:(NSString)kCGImagePropertyGIFDictionary];

[delayTimesaddObject:[gifDictvalueForKey:(NSString)kCGImagePropertyGIFDelayTime]];



if(totalTime){

totalTime=totalTime+[[gifDictvalueForKey:(NSString)kCGImagePropertyGIFDelayTime]floatValue];

}

}

}

@interfaceSvGifView(){

NSMutableArray_frames;

NSMutableArray_frameDelayTimes;



CGFloat_totalTime;//seconds

CGFloat_width;

CGFloat_height;

}

@end

@implementationSvGifView



-(id)initWithCenter:(CGPoint)centerfileURL:(NSURL)fileURL;

{

self=[superinitWithFrame:CGRectZero];

if(self){



_frames=[[NSMutableArrayalloc]init];

_frameDelayTimes=[[NSMutableArrayalloc]init];



_width=0;

_height=0;



if(fileURL){

getFrameInfo((CFURLRef)fileURL,_frames,_frameDelayTimes,&_totalTime,&_width,&_height);

}



self.frame=CGRectMake(0,0,_width,_height);

self.center=center;

}



returnself;

}

+(NSArray)framesInGif:(NSURL)fileURL

{

NSMutableArrayframes=[NSMutableArrayarrayWithCapacity:3];

NSMutableArraydelays=[NSMutableArrayarrayWithCapacity:3];



getFrameInfo((CFURLRef)fileURL,frames,delays,NULL,NULL,NULL);



returnframes;

}

-(void)startGif

{

CAKeyframeAnimationanimation=[CAKeyframeAnimationanimationWithKeyPath:@"contents"];



NSMutableArraytimes=[NSMutableArrayarrayWithCapacity:3];

CGFloatcurrentTime=0;

intcount=_frameDelayTimes.count;

for(inti=0;i
[timesaddObject:[NSNumbernumberWithFloat:(currentTime/_totalTime)]];

currentTime+=[[_frameDelayTimesobjectAtIndex:i]floatValue];

}

[animationsetKeyTimes:times];



NSMutableArrayimages=[NSMutableArrayarrayWithCapacity:3];

for(inti=0;i
[imagesaddObject:[_framesobjectAtIndex:i]];

}



[animationsetValues:images];

[animationsetTimingFunction:[CAMediaTimingFunctionfunctionWithName:kCAMediaTimingFunctionLinear]];

animation.duration=_totalTime;

animation.delegate=self;

animation.repeatCount=5;



[self.layeraddAnimation:animationforKey:@"gifAnimation"];

}

-(void)stopGif

{

[self.layerremoveAllAnimations];

}

//removecontentswww.hunanwang.netwhenanimationend

-(void)animationDidStop:(CAAnimation)animfinished:(BOOL)flag

{

self.layer.contents=nil;

}

//OnlyoverridedrawRect:ifyouperformcustomdrawing.

//Anemptyimplementationwww.visa158.comadverselyaffectsperformanceduringanimation.

-(void)drawRect:(CGRect)rect

{

//Drawingcode

}



@end



代码很短也比较容易,就不一一解释了。最开始的那个C函数主要就是用来解析Gif的,之所以用C函数是因为我要返回多个信息,而Objective-c只能返回一个参数,而且Objective-c和C语言可以很方便的混合编程。

另外再介绍两种使用UIImageView的方法:

1.使用UIWebView播放

复制代码代码如下:



//设定位置和大小

CGRectframe=CGRectMake(50,50,0,0);

frame.size=[UIImageimageNamed:@"guzhang.gif"].size;

//读取gif图片数据

NSDatagif=[NSDatadataWithContentsOfFile:[[NSBundlemainBundle]pathForResource:@"guzhang"ofType:@"gif"]];

//view生成

UIWebViewwebView=[[UIWebViewalloc]initWithFrame:frame];

webView.userInteractionEnabled=NO;//用户不可交互

[webViewloadData:gifMIMEType:@"image/gif"textEncodingName:nilbaseURL:nil];

[self.viewaddSubview:webView];

[webViewrelease];

2.将gif图片分解成多张png图片,使用UIImageView播放。

代码如下:

复制代码代码如下:



UIImageViewgifImageView=[[UIImageViewalloc]initWithFrame:[[UIScreenmainScreen]bounds]];

NSArraygifArray=[NSArrayarrayWithObjects:[UIImageimageNamed:@"1"],

[UIImageimageNamed:@"2"],

[UIImageimageNamed:@"3"],

[UIImageimageNamed:@"4"],

[UIImageimageNamed:@"5"],

[UIImageimageNamed:@"6"],

[UIImageimageNamed:@"7"],

[UIImageimageNamed:@"8"],

[UIImageimageNamed:@"9"],

[UIImageimageNamed:@"10"],

[UIImageimageNamed:@"11"],

[UIImageimageNamed:@"12"],

[UIImageimageNamed:@"13"],

[UIImageimageNamed:@"14"],

[UIImageimageNamed:@"15"],

[UIImageimageNamed:@"16"],

[UIImageimageNamed:@"17"],

[UIImageimageNamed:@"18"],

[UIImageimageNamed:@"19"],

[UIImageimageNamed:@"20"],

[UIImageimageNamed:@"21"],

[UIImageimageNamed:@"22"],nil];

gifImageView.animationImages=gifArray;//动画图片数组

gifImageView.animationDuration=5;//执行一次完整动画所需的时长

gifImageView.animationRepeatCount=1;//动画重复次数

[gifImageViewstartAnimating];

[self.viewaddSubview:gifImageView];

[gifImageViewrelease];



注意:这个方法,如果gif动画每桢间的时间间隔不同,不能达到此效果。























献花(0)
+1
(本文系白狐一梦首藏)