美文网首页
iOS开发笔记 -- 一次播放多个Gif

iOS开发笔记 -- 一次播放多个Gif

作者: feb961880dc1 | 来源:发表于2020-04-23 10:45 被阅读0次

开发时遇到一个需求,就是要多个gif合并播放

1、单个gif播放

 #import <UIImage+GIF.h>

 NSString *path = [[NSBundle mainBundle] pathForResource:@"gif" ofType:@"gif"];
 NSData *imgData = [NSData dataWithContentsOfFile:path];
 self.image.image = [UIImage sd_animatedGIFWithData:imgData];

查看 <UIImage+GIF.h>,发现只是用了简单的封装

#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

继续查看 SDWebImageGIFCoder.h ,发现 gif 转UIImage主要用到了这个方法:
(UIImage *)decodedImageWithData:(NSData *)data

- (UIImage *)decodedImageWithData:(NSData *)data {
    if (!data) {
        return nil;
    }
    
#if SD_MAC
    SDAnimatedImageRep *imageRep = [[SDAnimatedImageRep alloc] initWithData:data];
    NSImage *animatedImage = [[NSImage alloc] initWithSize:imageRep.size];
    [animatedImage addRepresentation:imageRep];
    return animatedImage;
#else
    
    CGImageSourceRef source = CGImageSourceCreateWithData((__bridge CFDataRef)data, NULL);
    if (!source) {
        return nil;
    }
    size_t count = CGImageSourceGetCount(source);
    
    UIImage *animatedImage;
    
    if (count <= 1) {
        animatedImage = [[UIImage alloc] initWithData:data];
    } else {
        NSMutableArray<SDWebImageFrame *> *frames = [NSMutableArray array];
        
        for (size_t i = 0; i < count; i++) {
            CGImageRef imageRef = CGImageSourceCreateImageAtIndex(source, i, NULL);
            if (!imageRef) {
                continue;
            }
            
            float duration = [self sd_frameDurationAtIndex:i source:source];
            UIImage *image = [[UIImage alloc] initWithCGImage:imageRef];
            CGImageRelease(imageRef);
            
            SDWebImageFrame *frame = [SDWebImageFrame frameWithImage:image duration:duration];
            [frames addObject:frame];
        }
        
        NSUInteger loopCount = 1;
        NSDictionary *imageProperties = (__bridge_transfer NSDictionary *)CGImageSourceCopyProperties(source, nil);
        NSDictionary *gifProperties = [imageProperties valueForKey:(__bridge NSString *)kCGImagePropertyGIFDictionary];
        if (gifProperties) {
            NSNumber *gifLoopCount = [gifProperties valueForKey:(__bridge NSString *)kCGImagePropertyGIFLoopCount];
            if (gifLoopCount != nil) {
                loopCount = gifLoopCount.unsignedIntegerValue;
            }
        }
        
        animatedImage = [SDWebImageCoderHelper animatedImageWithFrames:frames];
        animatedImage.sd_imageLoopCount = loopCount;
        animatedImage.sd_imageFormat = SDImageFormatGIF;
    }
    
    CFRelease(source);
    
    return animatedImage;
#endif
}

2、多个gif合并

基于SDWebImageGIFCoder 新建一个category,添加下面的方法
ps: 部分方法和头文件引用请直接复制SDWebImageGIFCoder.m !!!

- (UIImage *)decodedImageWithDatas:(NSArray<NSData *>*)datas {
    
    UIImage *animatedImage;
    switch (datas.count) {
        case 0:
            return nil;
        case 1:
        {
            animatedImage = [[UIImage alloc] initWithData:datas.firstObject];
        }
            break;
        default:
        {
            NSMutableArray<SDWebImageFrame *> *frames = [NSMutableArray array];
            
            for (NSUInteger i = 0; i < datas.count; ++i) {
                NSData *data = datas[i];
                
                CGImageSourceRef source = CGImageSourceCreateWithData((__bridge CFDataRef)data, NULL);
                if (!source) {
                    return nil;
                }
                size_t count = CGImageSourceGetCount(source);
                
                if (count <= 1) {
                    animatedImage = [[UIImage alloc] initWithData:data];
                } else {
                    for (size_t i = 0; i < count; i++) {
                        CGImageRef imageRef = CGImageSourceCreateImageAtIndex(source, i, NULL);
                        if (!imageRef) {
                            continue;
                        }
                        
                        float duration = [self sd_frameDurationAtIndex:i source:source];
                        UIImage *image = [[UIImage alloc] initWithCGImage:imageRef];
                        CGImageRelease(imageRef);
                        
                        SDWebImageFrame *frame = [SDWebImageFrame frameWithImage:image duration:duration];
                        [frames addObject:frame];
                    }
                }
                CFRelease(source);
            }
            NSUInteger loopCount = 1;
            animatedImage = [SDWebImageCoderHelper animatedImageWithFrames:frames];
            animatedImage.sd_imageLoopCount = loopCount;
            animatedImage.sd_imageFormat = SDImageFormatGIF;
        }
            break;
    }
    return animatedImage;
}

根据多个 gif 数据获取 image

NSMutableArray<NSData *> *datas = [NSMutableArray new];
for (NSUInteger i = 0; i < gifs.count; ++i) {
    NSString *path = [[NSBundle mainBundle] pathForResource:gifs[i] ofType:@"gif"];
    NSData *imgData = [NSData dataWithContentsOfFile:path];
    [datas addObject:imgData];
}
self.imageView.image = [[SDWebImageGIFCoder sharedCoder] decodedImageWithDatas:datas];

相关文章

  • iOS开发笔记 -- 一次播放多个Gif

    开发时遇到一个需求,就是要多个gif合并播放 1、单个gif播放 查看 ,发现只是用了简单的封装 继续查看 SD...

  • Swift (四) gif图片播放

    @[TOC](IOS gif图片播放 swift) 1. GIF在iOS平台上的几种加载方式 使用Dispatch...

  • iOS-播放gif动画文件(OC方法)

    iOS-.gif动画文件的播放 前言 播放gif动画的方法有多种: 将gif图片分解成多张图片使用UIImageV...

  • iOS 播放GIF

    iOS默认是不支持播放GIF图片的,但是系统也没有禁止播放它,该有的API还是有的,下面就 来一发吧! 一定要导入...

  • iOS - Gif播放

    ** 1.系统UIImageView 多张图片组成动画(帧动画)** ** 2.利用第三方库** 3. 为MBPr...

  • 使用UIImageView播放动图

    动图大家都会想到gif图片,但是在iOS端不能够播放gif格式图片怎么办呢。。。 其实苹果为开发者提供的控件足以让...

  • iOS的gif的图片处理

    iOS上没有直接播放gif控件(gif图片是几张png格式经过播放之后显示的不同的帧来进行实现的)sdwebima...

  • 关于iOS中Gif播放

    最近看了一下Gif播放,因为iOS是没有可以直接播放Gif资源的控件的,所以,这就需要我们想办法了。。。 准备 通...

  • iOS开发:让GIF动画只播放一次

    工作中我们拿到的是一个GIF文件,如果不作处理,直接使用SDWebImage就会无限次播放,那么我们只要他播放一次...

  • iOS 播放GIF图

    本文记录两种在iOS上播放GIF的方法 第一种:用UIWebView播放GIF图 如果想让webView的内容自适...

网友评论

      本文标题:iOS开发笔记 -- 一次播放多个Gif

      本文链接:https://www.haomeiwen.com/subject/dtroihtx.html