iOS:Gif動畫功能(顯示gif動畫、獲取gif動畫時長、獲取gif動畫執行次數)


一、簡單介紹

gif動畫是iOS開發中很常用的一個功能,有的是為了顯示加載視頻的過程,更多的是為了顯示一個結果狀態(動畫更直觀)。

那么如何執行gif動畫,方法有很多。(這里只寫一下方法三,前兩種之前都用過)

方法一使用UIWebView來顯示;

方法二使用UIImageView的幀動畫顯示;

方法三使用SDWebImage這個三方框架來顯示。

 

二、簡單使用

1、顯示gif動畫(三方框架SDWebImage的UIImage+GIF分類) 

#import "UIImage+GIF.h"
#import "SDWebImageGIFCoder.h"
#import "NSImage+WebCache.h"

@implementation UIImage (GIF)

+ (UIImage *)sd_animatedGIFWithData:(NSData *)data {
    if (!data) {
        return nil;
    }
    return [[SDWebImageGIFCoder sharedCoder] decodedImageWithData:data];
}

- (BOOL)isGIF {
    return (self.images != nil);
}

@end
//使用
NSData *gifData = [NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"live_sign" ofType:@"gif"]];
UIImage  *signSuccessGifImg = [UIImage sd_animatedGIFWithData:gifData];
self.imageView.image = signSuccessGifImg;

2、獲取gif動畫時長

//獲取gif圖片的總時長
- (NSTimeInterval)durationForGifData:(NSData *)data{
    
    //將GIF圖片轉換成對應的圖片源
    CGImageSourceRef gifSource = CGImageSourceCreateWithData((__bridge CFDataRef)data, NULL);
    
    //獲取其中圖片源個數,即由多少幀圖片組成
    size_t frameCout = CGImageSourceGetCount(gifSource);

    //定義數組存儲拆分出來的圖片
    NSMutableArray* frames = [[NSMutableArray alloc] init];
    NSTimeInterval totalDuration = 0;
    for (size_t i=0; i<frameCout; i++) {

        //從GIF圖片中取出源圖片
        CGImageRef imageRef = CGImageSourceCreateImageAtIndex(gifSource, i, NULL);

        //將圖片源轉換成UIimageView能使用的圖片源
        UIImage* imageName = [UIImage imageWithCGImage:imageRef];

        //將圖片加入數組中
        [frames addObject:imageName];
        NSTimeInterval duration = [self gifImageDeleyTime:gifSource index:i];
        totalDuration += duration;
        CGImageRelease(imageRef);
    }
    
    //獲取循環次數
    NSInteger loopCount;//循環次數
    CFDictionaryRef properties = CGImageSourceCopyProperties(gifSource, NULL);
    if (properties) {
        CFDictionaryRef gif = CFDictionaryGetValue(properties, kCGImagePropertyGIFDictionary);
        if (gif) {
            CFTypeRef loop = CFDictionaryGetValue(gif, kCGImagePropertyGIFLoopCount);
            if (loop) {
                //如果loop == NULL,表示不循環播放,當loopCount  == 0時,表示無限循環;
                CFNumberGetValue(loop, kCFNumberNSIntegerType, &loopCount);
            };
        }
    }
    CFRelease(gifSource);
    return totalDuration;
}
//獲取GIF圖片每幀的時長
- (NSTimeInterval)gifImageDeleyTime:(CGImageSourceRef)imageSource index:(NSInteger)index {
    NSTimeInterval duration = 0;
    CFDictionaryRef imageProperties = CGImageSourceCopyPropertiesAtIndex(imageSource, index, NULL);
    if (imageProperties) {
        CFDictionaryRef gifProperties;
        BOOL result = CFDictionaryGetValueIfPresent(imageProperties, kCGImagePropertyGIFDictionary, (const void **)&gifProperties);
        if (result) {
            const void *durationValue;
            if (CFDictionaryGetValueIfPresent(gifProperties, kCGImagePropertyGIFUnclampedDelayTime, &durationValue)) {
                duration = [(__bridge NSNumber *)durationValue doubleValue];
                if (duration < 0) {
                    if (CFDictionaryGetValueIfPresent(gifProperties, kCGImagePropertyGIFDelayTime, &durationValue)) {
                        duration = [(__bridge NSNumber *)durationValue doubleValue];
                    }
                }
            }
        }
    }
    
    return duration;
}

3、獲取gif動畫執行次數

//獲取gif圖片的循環次數
-(NSInteger)repeatCountForGifData:(NSData *)data{
    
    //將GIF圖片轉換成對應的圖片源
    CGImageSourceRef gifSource = CGImageSourceCreateWithData((__bridge CFDataRef)data, NULL);
    
    //獲取循環次數
    NSInteger loopCount = 0;//循環次數
    CFDictionaryRef properties = CGImageSourceCopyProperties(gifSource, NULL);
    if (properties) {
        CFDictionaryRef gif = CFDictionaryGetValue(properties, kCGImagePropertyGIFDictionary);
        if (gif) {
            CFTypeRef loop = CFDictionaryGetValue(gif, kCGImagePropertyGIFLoopCount);
            if (loop) {
                //如果loop == NULL,表示不循環播放,當loopCount  == 0時,表示無限循環;
                CFNumberGetValue(loop, kCFNumberNSIntegerType, &loopCount);
            };
        }
    }
    CFRelease(gifSource);
    
    return loopCount;
}

 

三、創建分類

#import "UIImageView+GIFProperty.h"

//
//  UIImageView+GIFProperty.h
//  YuwenParent
//
//  Created by 夏遠全 on 2019/4/11.
//  Copyright © 2019年 xiaoshuang. All rights reserved.
//

#import <UIKit/UIKit.h>

NS_ASSUME_NONNULL_BEGIN

@interface UIImageView (GIFProperty)
-(NSTimeInterval)durationForGifData:(NSData *)data;//獲取gif動畫總時長
-(NSInteger)repeatCountForGifData:(NSData *)data;  //獲取gif動畫循環總次數 0:表示無限循環
@end

NS_ASSUME_NONNULL_END
View Code
//
//  UIImageView+GIFProperty.m
//  YuwenParent
//
//  Created by 夏遠全 on 2019/4/11.
//  Copyright © 2019年 xiaoshuang. All rights reserved.
//

#import "UIImageView+GIFProperty.h"

@implementation UIImageView (GIFProperty)

//獲取gif圖片的總時長
- (NSTimeInterval)durationForGifData:(NSData *)data{
    
    //將GIF圖片轉換成對應的圖片源
    CGImageSourceRef gifSource = CGImageSourceCreateWithData((__bridge CFDataRef)data, NULL);
    
    //獲取其中圖片源個數,即由多少幀圖片組成
    size_t frameCout = CGImageSourceGetCount(gifSource);

    //定義數組存儲拆分出來的圖片
    NSMutableArray* frames = [[NSMutableArray alloc] init];
    NSTimeInterval totalDuration = 0;
    for (size_t i=0; i<frameCout; i++) {

        //從GIF圖片中取出源圖片
        CGImageRef imageRef = CGImageSourceCreateImageAtIndex(gifSource, i, NULL);

        //將圖片源轉換成UIimageView能使用的圖片源
        UIImage* imageName = [UIImage imageWithCGImage:imageRef];

        //將圖片加入數組中
        [frames addObject:imageName];
        NSTimeInterval duration = [self gifImageDeleyTime:gifSource index:i];
        totalDuration += duration;
        CGImageRelease(imageRef);
    }
    
    //獲取循環次數
    NSInteger loopCount;//循環次數
    CFDictionaryRef properties = CGImageSourceCopyProperties(gifSource, NULL);
    if (properties) {
        CFDictionaryRef gif = CFDictionaryGetValue(properties, kCGImagePropertyGIFDictionary);
        if (gif) {
            CFTypeRef loop = CFDictionaryGetValue(gif, kCGImagePropertyGIFLoopCount);
            if (loop) {
                //如果loop == NULL,表示不循環播放,當loopCount  == 0時,表示無限循環;
                CFNumberGetValue(loop, kCFNumberNSIntegerType, &loopCount);
            };
        }
    }
    CFRelease(gifSource);
    return totalDuration;
}

//獲取gif圖片的循環次數
-(NSInteger)repeatCountForGifData:(NSData *)data{
    
    //將GIF圖片轉換成對應的圖片源
    CGImageSourceRef gifSource = CGImageSourceCreateWithData((__bridge CFDataRef)data, NULL);
    
    //獲取循環次數
    NSInteger loopCount = 0;//循環次數
    CFDictionaryRef properties = CGImageSourceCopyProperties(gifSource, NULL);
    if (properties) {
        CFDictionaryRef gif = CFDictionaryGetValue(properties, kCGImagePropertyGIFDictionary);
        if (gif) {
            CFTypeRef loop = CFDictionaryGetValue(gif, kCGImagePropertyGIFLoopCount);
            if (loop) {
                //如果loop == NULL,表示不循環播放,當loopCount  == 0時,表示無限循環;
                CFNumberGetValue(loop, kCFNumberNSIntegerType, &loopCount);
            };
        }
    }
    CFRelease(gifSource);
    
    return loopCount;
}

//獲取GIF圖片每幀的時長
- (NSTimeInterval)gifImageDeleyTime:(CGImageSourceRef)imageSource index:(NSInteger)index {
    NSTimeInterval duration = 0;
    CFDictionaryRef imageProperties = CGImageSourceCopyPropertiesAtIndex(imageSource, index, NULL);
    if (imageProperties) {
        CFDictionaryRef gifProperties;
        BOOL result = CFDictionaryGetValueIfPresent(imageProperties, kCGImagePropertyGIFDictionary, (const void **)&gifProperties);
        if (result) {
            const void *durationValue;
            if (CFDictionaryGetValueIfPresent(gifProperties, kCGImagePropertyGIFUnclampedDelayTime, &durationValue)) {
                duration = [(__bridge NSNumber *)durationValue doubleValue];
                if (duration < 0) {
                    if (CFDictionaryGetValueIfPresent(gifProperties, kCGImagePropertyGIFDelayTime, &durationValue)) {
                        duration = [(__bridge NSNumber *)durationValue doubleValue];
                    }
                }
            }
        }
    }
    
    return duration;
}

@end
View Code

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM