iOS开发知识小集

SDWebImage (5.1.0)UIImage+GIF.h(

2019-08-26  本文已影响0人  charlotte2018

这个头文件就有一个方法,通过传入gif的data数据转化出一个image对象

+ (nullable UIImage *)sd_imageWithGIFData:(nullable NSData *)data {
    if (!data) {
        return nil;
    }
    return [[SDImageGIFCoder sharedCoder] decodedImageWithData:data options:0];
}

解析工作主要在SDImageGIFCoder类中,所以主要看这个类,这个类继承自NSObject对象,然后实现了SDImageCoder.h里的协议, SDImageCoder.h里头都是协议

#import <Foundation/Foundation.h>
#import "SDImageCoder.h"

@interface SDImageGIFCoder : NSObject <SDProgressiveImageCoder, SDAnimatedImageCoder>

@property (nonatomic, class, readonly, nonnull) SDImageGIFCoder *sharedCoder;

@end

这个- (nullable UIImage *)decodedImageWithData:(nullable NSData *)data options:(nullable SDImageCoderOptions *)options;方法是在@protocol SDImageCoder协议里的,然而@protocol SDAnimatedImageCoder <SDImageCoder, SDAnimatedImageProvider>所以也具备这个能力

iOS使用imageIO框架去实现data转化为Image,先了解GIF的几个概念:


- (UIImage *)decodedImageWithData:(NSData *)data options:(nullable SDImageCoderOptions *)options {
    if (!data) {
        return nil;
    }
    CGFloat scale = 1;
    NSNumber *scaleFactor = options[SDImageCoderDecodeScaleFactor];
    if (scaleFactor != nil) {
        scale = MAX([scaleFactor doubleValue], 1);
    }
    
#if SD_MAC
    SDAnimatedImageRep *imageRep = [[SDAnimatedImageRep alloc] initWithData:data];
    NSSize size = NSMakeSize(imageRep.pixelsWide / scale, imageRep.pixelsHigh / scale);
    imageRep.size = size;
    NSImage *animatedImage = [[NSImage alloc] initWithSize:size];
    [animatedImage addRepresentation:imageRep];
    return animatedImage;
#else
    
    CGImageSourceRef source = CGImageSourceCreateWithData((__bridge CFDataRef)data, NULL);
    if (!source) {
        return nil;
    }
    //gif有多少帧
    size_t count = CGImageSourceGetCount(source);
    UIImage *animatedImage;
    
    BOOL decodeFirstFrame = [options[SDImageCoderDecodeFirstFrameOnly] boolValue];
    if (decodeFirstFrame || count <= 1) {
        animatedImage = [[UIImage alloc] initWithData:data scale:scale];
    } else {
        NSMutableArray<SDImageFrame *> *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 scale:scale orientation:UIImageOrientationUp];
            CGImageRelease(imageRef);
            
            //SDImageFrame中保存了每一帧的图片和播放的时间
            SDImageFrame *frame = [SDImageFrame frameWithImage:image duration:duration];
            [frames addObject:frame];
        }
        
        //有些gif播放到一定次数就停止了,如果是0就是一直循环播放
        NSUInteger loopCount = [self sd_imageLoopCountWithSource:source];
        
        //将帧数组传入SDImageCoderHelper生成animatedImage,通过遍历得到image数组和总的时间最后把
        //animatedImage解析出来
        //animatedImage = [UIImage animatedImageWithImages:animatedImages duration:totalDuration / 1000.f];
        animatedImage = [SDImageCoderHelper animatedImageWithFrames:frames];
        animatedImage.sd_imageLoopCount = loopCount;
    }
    animatedImage.sd_imageFormat = SDImageFormatGIF;
    CFRelease(source);
    
    return animatedImage;
#endif
}

上一篇下一篇

猜你喜欢

热点阅读