• 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
  • 相关阅读:
    minicap编译示例
    uniapp H5项目中使用腾讯地图sdk
    腾讯地图打车乘客端小车平滑移动-安卓篇
    地图定位打卡功能示例
    腾讯位置服务个性化图层创建及发布
    腾讯位置服务GPS轨迹回放
    使用腾讯地图实现汽车沿轨迹行驶功能
    地图GPS轨迹录制
    腾讯地图实现微信小程序地图定位教程
    基于腾讯地图定位组件实现周边POI远近排序分布图
  • 原文地址:https://www.cnblogs.com/XYQ-208910/p/10708980.html
Copyright © 2020-2023  润新知