加载JIF动画的几种方法

来源:互联网 发布:Java 动态条件计算 编辑:程序博客网 时间:2024/05/16 01:48

1、使用UIWebView

// 读取gif图片数据 注意:传入nil参数可能有警告    NSData *data = [NSData dataWithContentsOfFile: [[NSBundle mainBundle] pathForResource:@"001" ofType:@"gif"]];        UIWebView *webView = [[UIWebView alloc] initWithFrame:CGRectMake(0,0,200,200)];    [webView loadData:data MIMEType:@"image/gif" textEncodingName:nil baseURL:nil];    [self.view addSubview:webView];

使用UIWebView的弊端在于,不能设置Gif动画的播放时间。

2、将Gif拆分成多张图片,使用UIImageView播放

UIImageView *gifImageView = [[UIImageView alloc] initWithFrame:CGRectMake((SCREENWIDTH-100)/2, (SCREENHEIGHT-NAVGATIONBRHEIGHT-200)/2, 100, 200)];NSArray *array = @[[UIImage imageNamed:@"shuaxin1"],[UIImage imageNamed:@"shuaxin2"],[UIImage imageNamed:@"shuaxin3"],[UIImage imageNamed:@"shuaxin4"]];gifImageView.animationImages = array; //获取Gif图片列表gifImageView.animationDuration = 1.5;     //执行一次完整动画所需的时长gifImageView.animationRepeatCount = 1;  //动画重复次数[gifImageView startAnimating];[self.view addSubview:gifImageView];

3、使用SDWebImage

SDWebImage这个库里有一个UIImage+GIF的类别,里面为UIImage扩展了三个方法

//name直接传GIF的名字,不用带扩展名+ (UIImage *)sd_animatedGIFNamed:(NSString *)name;+ (UIImage *)sd_animatedGIFWithData:(NSData *)data;- (UIImage *)sd_animatedImageByScalingAndCroppingToSize:(CGSize)size;

举例:

NSString *path = [[NSBundle mainBundle] pathForResource:@"gifTest" ofType:@"gif"];NSData *data = [NSData dataWithContentsOfFile:path];UIImage *image = [UIImage sd_animatedGIFWithData:data];gifImageView.image = image; 

可以在 .m 文件中设置动画的持续时间

4、加载网络Gif文件

加载网络的Gif文件就简单多了。最简单的方法,我们只需要使用SDWebImage 的 sd_setImageWithURL:这个方法传入Gif文件是url地址即可。
纠其原因:稍微仔细看了SDWebImage内部实现就可以清楚,大概是以下几个步骤:

1、SDWebImage根据url将Gif文件下载下来,格式为一个NSData2、如果判断是Gif格式,则会调用 sd_animatedGIFWithData: 将Data转换成我们需要的Gif格式3、通过上面的方法二即可显示出Gif图片

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

程序的思路如下:

  1. 首先使用ImageIO库中的CGImageSource家在Gif文件。
  2. 通过CGImageSource获取到Gif文件中的总的帧数,以及每一帧的显示时间。
  3. 通过CAKeyframeAnimation来完成Gif动画的播放。

.H文件

////  SvGifView.h//  SvGifSample////  Created by maple on 3/28/13.//  Copyright (c) 2013 smileEvday. All rights reserved.//\#import <UIKit/UIKit.h>@interface SvGifView : UIView/* * @brief desingated initializer */- (id)initWithCenter:(CGPoint)center fileURL:(NSURL*)fileURL;/* * @brief start Gif Animation */- (void)startGif;/* * @brief stop Gif Animation */- (void)stopGif;/* * @brief get frames image(CGImageRef) in Gif */+ (NSArray*)framesInGif:(NSURL*)fileURL;@end

.M文件

////  SvGifView.m//  SvGifSample////  Created by maple on 3/28/13.//  Copyright (c) 2013 smileEvday. All rights reserved.//\#import "SvGifView.h"\#import <ImageIO/ImageIO.h>\#import <QuartzCore/CoreAnimation.h>/* * @brief resolving gif information */void getFrameInfo(CFURLRef url, NSMutableArray *frames, NSMutableArray *delayTimes, CGFloat *totalTime,CGFloat *gifWidth, CGFloat *gifHeight){    CGImageSourceRef gifSource = CGImageSourceCreateWithURL(url, NULL);    // get frame count    size_t frameCount = CGImageSourceGetCount(gifSource);    for (size_t i = 0; i < frameCount; ++i) {        // get each frame        CGImageRef frame = CGImageSourceCreateImageAtIndex(gifSource, i, NULL);        [frames addObject:(id)frame];        CGImageRelease(frame);        // get gif info with each frame        NSDictionary *dict = (NSDictionary*)CGImageSourceCopyPropertiesAtIndex(gifSource, i, NULL);        NSLog(@"kCGImagePropertyGIFDictionary %@", [dict valueForKey:(NSString*)kCGImagePropertyGIFDictionary]);        // get gif size        if (gifWidth != NULL && gifHeight != NULL) {            *gifWidth = [[dict valueForKey:(NSString*)kCGImagePropertyPixelWidth] floatValue];            *gifHeight = [[dict valueForKey:(NSString*)kCGImagePropertyPixelHeight] floatValue];        }        // kCGImagePropertyGIFDictionary中kCGImagePropertyGIFDelayTime,kCGImagePropertyGIFUnclampedDelayTime值是一样的        NSDictionary *gifDict = [dict valueForKey:(NSString*)kCGImagePropertyGIFDictionary];        [delayTimes addObject:[gifDict valueForKey:(NSString*)kCGImagePropertyGIFDelayTime]];        if (totalTime) {            *totalTime = *totalTime + [[gifDict valueForKey:(NSString*)kCGImagePropertyGIFDelayTime] floatValue];        }    }}@interface SvGifView() {    NSMutableArray *_frames;    NSMutableArray *_frameDelayTimes;    CGFloat _totalTime;         // seconds    CGFloat _width;    CGFloat _height;}@end@implementation SvGifView- (id)initWithCenter:(CGPoint)center fileURL:(NSURL*)fileURL;{    self = [super initWithFrame:CGRectZero];    if (self) {        _frames = [[NSMutableArray alloc] init];        _frameDelayTimes = [[NSMutableArray alloc] 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;    }    return self;}+ (NSArray*)framesInGif:(NSURL *)fileURL{    NSMutableArray *frames = [NSMutableArray arrayWithCapacity:3];    NSMutableArray *delays = [NSMutableArray arrayWithCapacity:3];    getFrameInfo((CFURLRef)fileURL, frames, delays, NULL, NULL, NULL);    return frames;}- (void)startGif{    CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"contents"];    NSMutableArray *times = [NSMutableArray arrayWithCapacity:3];    CGFloat currentTime = 0;    int count = _frameDelayTimes.count;    for (int i = 0; i < count; ++i) {        [times addObject:[NSNumber numberWithFloat:(currentTime / _totalTime)]];        currentTime += [[_frameDelayTimes objectAtIndex:i] floatValue];    }    [animation setKeyTimes:times];    NSMutableArray *images = [NSMutableArray arrayWithCapacity:3];    for (int i = 0; i < count; ++i) {        [images addObject:[_frames objectAtIndex:i]];    }    [animation setValues:images];    [animation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear]];    animation.duration = _totalTime;    animation.delegate = self;    animation.repeatCount = 5;    [self.layer addAnimation:animation forKey:@"gifAnimation"];}- (void)stopGif{    [self.layer removeAllAnimations];}// remove contents when animation end- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag{    self.layer.contents = nil;}// Only override drawRect: if you perform custom drawing.// An empty implementation adversely affects performance during animation.- (void)drawRect:(CGRect)rect{    // Drawing code}@end 
1 0
原创粉丝点击