We know that GIF is made up of waves of pictures, and each frame of the screen playback may be unequal, observe the above two examples, found that they do not have a GIF in each frame of the display often do processing, the result is that the entire GIF frame screen is at a fixed speed to play forward, Obviously it doesn't always fit the demand.
So I write an analytic GIF tool class, solve each frame picture and follow each frame corresponding to the display time to play.
The idea of the procedure is as follows:
1, first use the ImageIO library in the Cgimagesource home in GIF files.
2, through the Cgimagesource to obtain the total number of frames in the GIF file, and the display time of each frame.
3, through the cakeyframeanimation to complete GIF animation playback.
Below, I write the code to parse and play the GIF tool class directly:
Copy Code code as follows:
//
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
//
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 the 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];
}
The Kcgimagepropertygifdelaytime,kcgimagepropertygifunclampeddelaytime value in Kcgimagepropertygifdictionary is the same
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.
-(void) DrawRect: (cgrect) rect
{
Drawing Code
}
@end
The code is short and easy to explain. The first C function is mainly used to parse GIF, the C function is because I want to return multiple information, and OBJECTIVE-C can only return one parameter, and objective-c and C language can be very convenient mixed programming.
Two other ways to use Uiimageview are introduced:
1. Play with UIWebView
Copy Code code as follows:
Set position and size
CGRect frame = CGRectMake (50,50,0,0);
Frame.size = [UIImage imagenamed:@ "Guzhang.gif"].size;
Reading GIF image data
NSData *gif = [NSData datawithcontentsoffile: [[NSBundle Mainbundle] pathforresource:@ "Guzhang" ofType:@ "GIF"]];
View Build
UIWebView *webview = [[UIWebView alloc] initwithframe:frame];
webview.userinteractionenabled = no;//User is not interactive
[WebView loaddata:gif mimetype:@ "Image/gif" Textencodingname:nil Baseurl:nil];
[Self.view Addsubview:webview];
[WebView release];
2. Split the GIF image into PNG pictures and play with Uiimageview.
The code is as follows:
Copy Code code as follows:
Uiimageview *gifimageview = [[Uiimageview alloc] initwithframe:[[uiscreen mainscreen] bounds]];
Nsarray *gifarray = [Nsarray arraywithobjects:[uiimage imagenamed:@ "1"],
[UIImage imagenamed:@ "2"],
[UIImage imagenamed:@ "3"],
[UIImage imagenamed:@ "4"],
[UIImage imagenamed:@ "5"],
[UIImage imagenamed:@ "6"],
[UIImage imagenamed:@ "7"],
[UIImage imagenamed:@ "8"],
[UIImage imagenamed:@ "9"],
[UIImage imagenamed:@ "10"],
[UIImage imagenamed:@ "11"],
[UIImage imagenamed:@ "12"],
[UIImage imagenamed:@ "13"],
[UIImage imagenamed:@ "14"],
[UIImage imagenamed:@ "15"],
[UIImage imagenamed:@ "16"],
[UIImage imagenamed:@ "17"],
[UIImage imagenamed:@ "18"],
[UIImage imagenamed:@ "19"],
[UIImage imagenamed:@ "20"],
[UIImage imagenamed:@ "21"],
[UIImage imagenamed:@ "],nil];
Gifimageview.animationimages = Gifarray; Animated picture Array
Gifimageview.animationduration = 5; The length of time required to perform a full animation
Gifimageview.animationrepeatcount = 1; Animation repetition times
[Gifimageview startanimating];
[Self.view Addsubview:gifimageview];
[Gifimageview release];
Note: This method, if the GIF animation of each frame between the time interval is different, can not achieve this effect.