How to use .GIF image in IPhone App?

1. First Import 2 class in Project: 

—UIImage+animatedGIF.h

—UIImage+animatedGIF.m

 

2.Import ‘UIImage+animatedGIF.m‘ into viewcontroller.m file.

 

3.Now use below code to use .gif image:

NSURL *url = [[NSBundle mainBundle] URLForResource:@”VideoIcon” withExtension:@”gif”];

[videoBtn setImage:[UIImage animatedImageWithAnimatedGIFURL:url] forState:UIControlStateNormal];

 

4.UIImage+animatedGIF.h

 

#import <UIKit/UIKit.h>

 

/**

UIImage (animatedGIF)

This category adds class methods to `UIImage` to create an animated `UIImage` from an animated GIF.

*/

@interface UIImage (animatedGIF)

 

/*

UIImage *animation = [UIImage animatedImageWithAnimatedGIFData:theData];

I interpret `theData` as a GIF.  I create an animated `UIImage` using the source images in the GIF.

The GIF stores a separate duration for each frame, in units of centiseconds (hundredths of a second).  However, a `UIImage` only has a single, total `duration` property, which is a floating-point number.

To handle this mismatch, I add each source image (from the GIF) to `animation` a varying number of times to match the ratios between the frame durations in the GIF.

For example, suppose the GIF contains three frames.  Frame 0 has duration 3.  Frame 1 has duration 9.  Frame 2 has duration 15.  I divide each duration by the greatest common denominator of all the durations, which is 3, and add each frame the resulting number of times.  Thus `animation` will contain frame 0 3/3 = 1 time, then frame 1 9/3 = 3 times, then frame 2 15/3 = 5 times.  I set `animation.duration` to (3+9+15)/100 = 0.27 seconds.

*/

+ (UIImage *)animatedImageWithAnimatedGIFData:(NSData *)theData;

 

/*

UIImage *image = [UIImage animatedImageWithAnimatedGIFURL:theURL];

I interpret the contents of `theURL` as a GIF.  I create an animated `UIImage` using the source images in the GIF.

I operate exactly like `+[UIImage animatedImageWithAnimatedGIFData:]`, except that I read the data from `theURL`.  If `theURL` is not a `file:` URL, you probably want to call me on a background thread or GCD queue to avoid blocking the main thread.

*/

+ (UIImage *)animatedImageWithAnimatedGIFURL:(NSURL *)theURL;

 

@end

 

5.UIImage+animatedGIF.m

 

#import “UIImage+animatedGIF.h”

#import <ImageIO/ImageIO.h>

 

#if __has_feature(objc_arc)

#define toCF (__bridge CFTypeRef)

#define fromCF (__bridge id)

#else

#define toCF (CFTypeRef)

#define fromCF (id)

#endif

 

@implementation UIImage (animatedGIF)

 

static int delayCentisecondsForImageAtIndex(CGImageSourceRef const source, size_t const i) {

int delayCentiseconds = 1;

CFDictionaryRef const properties = CGImageSourceCopyPropertiesAtIndex(source, i, NULL);

if (properties) {

CFDictionaryRef const gifProperties = CFDictionaryGetValue(properties, kCGImagePropertyGIFDictionary);

if (gifProperties) {

CFNumberRef const number = CFDictionaryGetValue(gifProperties, kCGImagePropertyGIFDelayTime);

// Even though the GIF stores the delay as an integer number of centiseconds, ImageIO “helpfully” converts that to seconds for us.

delayCentiseconds = (int)lrint([fromCF number doubleValue] * 100);

}

CFRelease(properties);

}

return delayCentiseconds;

}

 

static void createImagesAndDelays(CGImageSourceRef source, size_t count, CGImageRef imagesOut[count], int delayCentisecondsOut[count]) {

for (size_t i = 0; i < count; ++i) {

imagesOut[i] = CGImageSourceCreateImageAtIndex(source, i, NULL);

delayCentisecondsOut[i] = delayCentisecondsForImageAtIndex(source, i);

}

}

 

static int sum(size_t const count, int const *const values) {

int theSum = 0;

for (size_t i = 0; i < count; ++i) {

theSum += values[i];

}

return theSum;

}

 

static int pairGCD(int a, int b) {

if (a < b)

return pairGCD(b, a);

while (true) {

int const r = a % b;

if (r == 0)

return b;

a = b;

b = r;

}

}

 

static int vectorGCD(size_t const count, int const *const values) {

int gcd = values[0];

for (size_t i = 1; i < count; ++i) {

// Note that after I process the first few elements of the vector, `gcd` will probably be smaller than any remaining element.  By passing the smaller value as the second argument to `pairGCD`, I avoid making it swap the arguments.

gcd = pairGCD(values[i], gcd);

}

return gcd;

}

 

static NSArray *frameArray(size_t const count, CGImageRef const images[count], int const delayCentiseconds[count], int const totalDurationCentiseconds) {

int const gcd = vectorGCD(count, delayCentiseconds);

size_t const frameCount = totalDurationCentiseconds / gcd;

UIImage *frames[frameCount];

for (size_t i = 0, f = 0; i < count; ++i) {

UIImage *const frame = [UIImage imageWithCGImage:images[i]];

for (size_t j = delayCentiseconds[i] / gcd; j > 0; –j) {

frames[f++] = frame;

}

}

return [NSArray arrayWithObjects:frames count:frameCount];

}

 

static void releaseImages(size_t const count, CGImageRef const images[count]) {

for (size_t i = 0; i < count; ++i) {

CGImageRelease(images[i]);

}

}

 

static UIImage *animatedImageWithAnimatedGIFImageSource(CGImageSourceRef const source) {

size_t const count = CGImageSourceGetCount(source);

CGImageRef images[count];

int delayCentiseconds[count]; // in centiseconds

createImagesAndDelays(source, count, images, delayCentiseconds);

int const totalDurationCentiseconds = sum(count, delayCentiseconds);

NSArray *const frames = frameArray(count, images, delayCentiseconds, totalDurationCentiseconds);

UIImage *const animation = [UIImage animatedImageWithImages:frames duration:(NSTimeInterval)totalDurationCentiseconds / 100.0];

releaseImages(count, images);

return animation;

}

 

static UIImage *animatedImageWithAnimatedGIFReleasingImageSource(CGImageSourceRef CF_RELEASES_ARGUMENT source) {

if (source) {

UIImage *const image = animatedImageWithAnimatedGIFImageSource(source);

CFRelease(source);

return image;

} else {

return nil;

}

}

 

+ (UIImage *)animatedImageWithAnimatedGIFData:(NSData *)data {

return animatedImageWithAnimatedGIFReleasingImageSource(CGImageSourceCreateWithData(toCF data, NULL));

}

 

+ (UIImage *)animatedImageWithAnimatedGIFURL:(NSURL *)url {

return animatedImageWithAnimatedGIFReleasingImageSource(CGImageSourceCreateWithURL(toCF url, NULL));

}

 

@end