iOS 4种方法显示GIF
【摘要】
GIF作为一种淘汰的图像类型文件,和flash一样,直至现在依然存在于我们生活中的每一个角落。
有时候在iOS中使用GIF会比使用帧动画来的更加方便。
iOS中加载GIF的方法大致分为以下几类:
(1)使用UIWebView播放GIF数据流。弊端是GIF图片只能播放一次(网上的很多博客都说可以播放,不知道是不是iOS版本的问题,还...
GIF作为一种淘汰的图像类型文件,和flash一样,直至现在依然存在于我们生活中的每一个角落。
有时候在iOS中使用GIF会比使用帧动画来的更加方便。
iOS中加载GIF的方法大致分为以下几类:
(1)使用UIWebView播放GIF数据流。弊端是GIF图片只能播放一次(网上的很多博客都说可以播放,不知道是不是iOS版本的问题,还是这可以播放指的就是1次)
(2)将GIF制作成一个本地网页,用UIVebView显示这个网页。弊端是GIF同样只能播放一次。
(2)预先将GIF中的图片提取出来,然后UIImageView每隔一定间隔显示一张图片。
(3)在运行时,通过代码提取GIF中的每一帧和间隔时间,通过帧动画CAKeyframeAnimation来播放。(该方法有点问题,每一帧的信息都能获取的到,但是动画无法播放,因此我还在调试,敬请期待)。
下面是实现以上技术的关键代码:
1、ViewController.m
-
//
-
// ViewController.m
-
// GifDemo
-
//
-
// Created by 555chy on 6/17/16.
-
// Copyright © 2016 555chy. All rights reserved.
-
//
-
-
#import "ViewController.h"
-
//#import <MobileCoreServices/MobileCoreServices.h>
-
#import "GifView.h"
-
-
-
#define IMAGE_NAME @"resource/20140830549"
-
#define IMAGE_TYPE @"gif"
-
-
@interface ViewController () {
-
CGRect contentRect;
-
}
-
-
@end
-
-
@implementation ViewController
-
-
CGRect screenRect;
-
-
- (void)viewDidLoad {
-
[super viewDidLoad];
-
// Do any additional setup after loading the view, typically from a nib.
-
-
self.navigationItem.title = @"chy龙神";
-
[self getContentRect];
-
-
/*
-
extern const CFStringRef kUTTypeJPEG __OSX_AVAILABLE_STARTING(__MAC_10_4,__IPHONE_3_0);
-
extern const CFStringRef kUTTypeJPEG2000 __OSX_AVAILABLE_STARTING(__MAC_10_4,__IPHONE_3_0);
-
extern const CFStringRef kUTTypeTIFF __OSX_AVAILABLE_STARTING(__MAC_10_4,__IPHONE_3_0);
-
extern const CFStringRef kUTTypePICT __OSX_AVAILABLE_STARTING(__MAC_10_4,__IPHONE_3_0);
-
extern const CFStringRef kUTTypeGIF __OSX_AVAILABLE_STARTING(__MAC_10_4,__IPHONE_3_0);
-
extern const CFStringRef kUTTypePNG __OSX_AVAILABLE_STARTING(__MAC_10_4,__IPHONE_3_0);
-
extern const CFStringRef kUTTypeQuickTimeImage __OSX_AVAILABLE_STARTING(__MAC_10_4,__IPHONE_3_0);
-
extern const CFStringRef kUTTypeAppleICNS __OSX_AVAILABLE_STARTING(__MAC_10_4,__IPHONE_3_0);
-
extern const CFStringRef kUTTypeBMP __OSX_AVAILABLE_STARTING(__MAC_10_4,__IPHONE_3_0);
-
extern const CFStringRef kUTTypeICO __OSX_AVAILABLE_STARTING(__MAC_10_4,__IPHONE_3_0);
-
extern const CFStringRef kUTTypeRawImage __OSX_AVAILABLE_STARTING(__MAC_10_10,__IPHONE_8_0);
-
extern const CFStringRef kUTTypeScalableVectorGraphics __OSX_AVAILABLE_STARTING(__MAC_10_10,__IPHONE_8_0);
-
extern const CFStringRef kUTTypeLivePhoto __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_9_1);
-
*/
-
-
[self loadGifInWebView1];
-
[self loadGifInWebView2];
-
[self loadGifInImageView];
-
[self loadGifInGifView];
-
}
-
-
-(void)getContentRect {
-
screenRect = [UIScreen mainScreen].bounds;
-
contentRect = self.navigationController.navigationBar.frame;
-
NSLog(@"navigationRect = (%f,%f) %f*%f", contentRect.origin.x, contentRect.origin.y, contentRect.size.width, contentRect.size.height);
-
contentRect.origin.y = contentRect.size.height;
-
contentRect.size.height = screenRect.size.height - contentRect.size.height;
-
}
-
-
//使用webview加载gif只能不放一轮,不能循环播放
-
-(void)loadGifInWebView1 {
-
NSString *path = [[NSBundle mainBundle] pathForResource:IMAGE_NAME ofType:IMAGE_TYPE];
-
NSData *gifData = [NSData dataWithContentsOfFile:path];
-
UIWebView *webView = [[UIWebView alloc] initWithFrame:CGRectMake(contentRect.origin.x, contentRect.origin.y, contentRect.size.width/2, contentRect.size.height/2)];
-
//禁止回弹
-
webView.scrollView.bounces = NO;
-
webView.scrollView.scrollEnabled = NO;
-
webView.scalesPageToFit = YES;
-
//设置透明背景(webview的默认背景上灰色的)
-
webView.backgroundColor = [UIColor clearColor];
-
webView.opaque = 0;
-
//禁止交互
-
webView.userInteractionEnabled = NO;
-
[webView loadData:gifData MIMEType:@"image/gif" textEncodingName:@"UTF-8" baseURL:[NSURL fileURLWithPath:@""]];
-
[self.view addSubview:webView];
-
}
-
-
-(void)loadGifInWebView2 {
-
NSURL *resourceUrl = [NSBundle mainBundle].resourceURL;
-
NSString *html = [NSString stringWithFormat:@"<html><body><img src=\"%@.%@\"></body></html>", IMAGE_NAME, IMAGE_TYPE];
-
UIWebView *webView = [[UIWebView alloc] initWithFrame:CGRectMake(contentRect.origin.x+contentRect.size.width/2, contentRect.origin.y, contentRect.size.width/2, contentRect.size.height/2)];
-
[webView loadHTMLString:html baseURL:resourceUrl];
-
[self.view addSubview:webView];
-
}
-
-
//普通的UIImage只能显示gif图片的第一帧
-
-(void)loadGifInImageView {
-
NSArray *gifImageNameArray = [[NSArray alloc] initWithObjects:@"1",@"5",@"10",@"16", nil];
-
NSMutableArray *gifImageArray = [NSMutableArray array];
-
for(int i=0; i<gifImageNameArray.count; i++) {
-
NSString *name = [NSString stringWithFormat:@"resource/gif/%@", [gifImageNameArray objectAtIndex:i]];
-
NSString *path = [[NSBundle mainBundle] pathForResource:name ofType:@"jpg"];
-
UIImage *image = [UIImage imageWithContentsOfFile:path];
-
[gifImageArray addObject:image];
-
}
-
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(contentRect.origin.x, contentRect.origin.y+contentRect.size.height/2, contentRect.size.width/2, contentRect.size.height/2)]; [self.view addSubview:imageView];
-
imageView.animationImages = gifImageArray;
-
//动画执行的总时长
-
imageView.animationDuration = 4*0.15;
-
//动画重复次数(0为重复播放)
-
imageView.animationRepeatCount = 0;
-
[imageView startAnimating];
-
/*
-
typedef NS_ENUM(NSInteger, UIViewContentMode) {
-
UIViewContentModeScaleToFill,
-
UIViewContentModeScaleAspectFit, // contents scaled to fit with fixed aspect. remainder is transparent
-
UIViewContentModeScaleAspectFill, // contents scaled to fill with fixed aspect. some portion of content may be clipped.
-
UIViewContentModeRedraw, // redraw on bounds change (calls -setNeedsDisplay)
-
UIViewContentModeCenter, // contents remain same size. positioned adjusted.
-
UIViewContentModeTop,
-
UIViewContentModeBottom,
-
UIViewContentModeLeft,
-
UIViewContentModeRight,
-
UIViewContentModeTopLeft,
-
UIViewContentModeTopRight,
-
UIViewContentModeBottomLeft,
-
UIViewContentModeBottomRight,
-
};
-
*/
-
imageView.contentMode = UIViewContentModeScaleToFill;
-
//imageView.contentMode = UIViewContentModeScaleAspectFit;
-
//imageView.contentMode = UIViewContentModeScaleAspectFill;
-
//imageView.contentScaleFactor = [UIScreen mainScreen].scale;
-
//imageView.autoresizingMask = UIViewAutoresizingFlexibleWidth;
-
imageView.backgroundColor = [UIColor yellowColor];
-
[self.view addSubview:imageView];
-
}
-
-
-(void)loadGifInGifView {
-
NSString *path = [[NSBundle mainBundle] pathForResource:IMAGE_NAME ofType:IMAGE_TYPE];
-
GifView *gifView = [[GifView alloc] initWithFrame:CGRectMake(contentRect.origin.x+contentRect.size.width/2, contentRect.origin.y+contentRect.size.height/2, contentRect.size.width/2, contentRect.size.height/2) gifFileURL:[NSURL fileURLWithPath:path]];
-
//[gifView startGif];
-
[self.view addSubview:gifView];
-
}
-
-
- (void)didReceiveMemoryWarning {
-
[super didReceiveMemoryWarning];
-
// Dispose of any resources that can be recreated.
-
}
-
-
@end
2、GifView.h
-
//
-
// GifView.h
-
// GifDemo
-
//
-
// Created by 555chy on 6/18/16.
-
// Copyright © 2016 555chy. All rights reserved.
-
//
-
-
#import <UIKit/UIKit.h>
-
#import <ImageIO/ImageIO.h>
-
#import <QuartzCore/QuartzCore.h>
-
-
@interface GifView : UIImageView
-
-
-(id) initWithFrame:(CGRect)frame gifFileURL:(NSURL *)fileURL;
-
-(BOOL) startGif;
-
-(void) stopGif;
-
-
@end
3、GifView.m
-
//
-
// GifView.m
-
// GifDemo
-
//
-
// Created by 555chy on 6/18/16.
-
// Copyright © 2016 555chy. All rights reserved.
-
//
-
-
#import "GifView.h"
-
-
void getFrameInfo(CFURLRef url, NSMutableArray *frames, NSMutableArray *delayTimes, CGFloat *totalTime, CGFloat *gifWidth, CGFloat *gifHeight) {
-
CGImageSourceRef gifSource = CGImageSourceCreateWithURL(url, NULL);
-
size_t frameCount = CGImageSourceGetCount(gifSource);
-
NSLog(@"gif frame count = %ld", frameCount);
-
-
for(size_t i=0; i<frameCount; i++) {
-
//get each frame
-
CGImageRef frame = CGImageSourceCreateImageAtIndex(gifSource, i, NULL);
-
//[frames addObject:(id)frame];
-
//Cast of C pointer type 'CGImageRef' (aka 'struct CGImage *') to Objective-C pointer type 'id' requires a bridged cast
-
[frames addObject:(id)CFBridgingRelease(frame)];
-
//这边不需要手动释放了,因为CFBridgingRelease已经把管理权交给ARC了
-
//CGImageRelease(frame);
-
-
//get gif info with each frame
-
//Cast of C pointer type 'CGImageRef' (aka 'struct CGImage *') to Objective-C pointer type 'id' requires a bridged cast
-
//NSDictionary *dict = (NSDictionary*)CGImageSourceCopyPropertiesAtIndex(gifSource, i, NULL);
-
NSDictionary *dict = (NSDictionary*)CFBridgingRelease(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];
-
NSLog(@"%ld. gif width*height = %f*%f", i, *gifWidth, *gifHeight);
-
}
-
-
//get gif property
-
NSDictionary *gifPropertyDict = [dict valueForKey:(NSString*)kCGImagePropertyGIFDictionary];
-
-
//kCGImagePropertyGifDictionary中kCGImagePropertyGIFDelayTime, kCGImagePropertyGIFUnclampedDelayTime的值是一样的
-
id delayTimeObj = [gifPropertyDict valueForKey:(NSString*)kCGImagePropertyGIFDelayTime];
-
NSLog(@"delayTimeObject = %@", delayTimeObj);
-
[delayTimes addObject:delayTimeObj];
-
id unclampedDelayTimeObj = [gifPropertyDict valueForKey:(NSString*)kCGImagePropertyGIFUnclampedDelayTime];
-
NSLog(@"unclampedDelayTimeObj = %@", unclampedDelayTimeObj);
-
//[delayTimes addObject:unclampedDelayTimeObj];
-
-
if(totalTime) {
-
*totalTime = *totalTime + [delayTimeObj floatValue];
-
}
-
}
-
NSLog(@"totalTime = %f", *totalTime);
-
CFRelease(gifSource);
-
}
-
-
@interface GifView() {
-
NSMutableArray *_gifFrames;
-
NSMutableArray * _gifFrameDelayTimes;
-
-
CGFloat _gifTotalTime;
-
CGFloat _gifWidth;
-
CGFloat _gifHeight;
-
}
-
@end
-
-
@implementation GifView
-
-
- (id) initWithFrame:(CGRect)frame gifFileURL:(NSURL *)fileURL {
-
self = [super initWithFrame:frame];
-
if(self) {
-
_gifFrames = [[NSMutableArray alloc] init];
-
_gifFrameDelayTimes = [[NSMutableArray alloc] init];
-
-
_gifWidth = 0;
-
_gifHeight = 0;
-
-
if(fileURL) {
-
getFrameInfo((__bridge CFURLRef) fileURL, _gifFrames, _gifFrameDelayTimes, &_gifTotalTime, &_gifWidth, &_gifHeight);
-
}
-
}
-
return self;
-
}
-
-
- (BOOL) startGif
-
{
-
CGFloat currentTime = 0;
-
unsigned int count = (unsigned int)_gifFrameDelayTimes.count;
-
NSLog(@"gif frame count = %u", count);
-
if(count <= 0 || _gifTotalTime <= 0) {
-
return NO;
-
}
-
CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"contents"];
-
-
NSMutableArray *times = [NSMutableArray arrayWithCapacity:count];
-
for(unsigned int i=0; i<count; i++) {
-
[times addObject:[NSNumber numberWithFloat:(currentTime/_gifTotalTime)]];
-
currentTime += [[_gifFrameDelayTimes objectAtIndex:i] floatValue];
-
}
-
[animation setKeyTimes:times];
-
-
NSMutableArray *images = [NSMutableArray arrayWithCapacity:count];
-
for(unsigned int i=0; i<count; i++) {
-
NSString *path = [[NSBundle mainBundle] pathForResource:@"resource/gif/1" ofType:@"jpg"];
-
UIImage *image = [UIImage imageWithContentsOfFile:path];
-
[images addObject:image];
-
//[images addObject:[_gifFrames objectAtIndex:i]];
-
}
-
[animation setValues: images];
-
-
//[animation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear]];
-
animation.duration = _gifTotalTime;
-
animation.delegate = self;
-
/* The repeat count of the object. May be fractional. Defaults to 0. */
-
animation.repeatCount = 5;
-
[self.layer addAnimation:animation forKey:@"gifAnimation"];
-
-
return YES;
-
}
-
-
- (void) stopGif {
-
[self.layer removeAllAnimations];
-
}
-
-
- (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
文章来源: blog.csdn.net,作者:福州-司马懿,版权归原作者所有,如需转载,请联系作者。
原文链接:blog.csdn.net/chy555chy/article/details/51703446
【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)