美文网首页
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

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