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动画每桢间的时间间隔不同,不能达到此效果。
|
|