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

2020-04-23  本文已影响0人  feb961880dc1

开发时遇到一个需求,就是要多个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];
上一篇 下一篇

猜你喜欢

热点阅读