iOS gif 图片播放实现方法 (image 扩展方案)

来源:互联网 发布:中国移动网络测速 编辑:程序博客网 时间:2024/04/29 12:26

1 image 扩展方案:

1.导入头文件

#import <ImageIO/ImageIO.h>#import <UIKit/UIKit.h>#if __has_feature(objc_arc)#define toCF (__bridge CFTypeRef)#define fromCF (__bridge id)#else#define toCF (CFTypeRef)#define fromCF (id)#endif/**        UIImage (animatedGIF)    This category adds class methods to `UIImage` to create an animated `UIImage` from an animated GIF.*/@interface UIImage (animatedGIF)

2.声明方法:

+ (UIImage * _Nullable)animatedImageWithAnimatedGIFData:(NSData * _Nonnull)theData;+ (UIImage * _Nullable)animatedImageWithAnimatedGIFURL:(NSURL * _Nonnull)theURL;

3.实现方法:

@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) {            NSNumber *number = fromCF CFDictionaryGetValue(gifProperties, kCGImagePropertyGIFUnclampedDelayTime);            if (number == NULL || [number doubleValue] == 0) {                number = fromCF CFDictionaryGetValue(gifProperties, kCGImagePropertyGIFDelayTime);            }            if ([number doubleValue] > 0) {                // Even though the GIF stores the delay as an integer number of centiseconds, ImageIO “helpfully” converts that to seconds for us.                delayCentiseconds = (int)lrint([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

2 web view 方案(todo )

使用webview 直接加载gif 直接可以播放(代码有空再帖)

3 将gif分解为N张图片(todo)

然后导入工程依次播放.(代码有空再帖)

0 0
原创粉丝点击