SDWebImage加载gif动态图原理

文章详细解析了SDWebImage库如何高效加载GIF图片,涉及CGImageSource、SDImageGIFCoder及解码流程,展示了其CPU低占用和常见框架的特点。

前面有篇文章分析了不同的框架加载gif的性能https://blog.csdn.net/u014600626/article/details/113767876。SD的性能是不错的,CPU占用很低, 而且这个框架很常见, 就想研究下SDWebImage是怎么加载gif图片的。

先看调用的地方, 就是很简单的使用 [imageView sd_setImageWithURL:url](之前的版本可能不支持直接传gif的地址,但是在5.x.x之后肯定是可以了,本文基于5.10.4分析);  或者使用工程中/沙盒里 获取到的二进制数据即可

#pragma mark SD加载image
- (void)testGifImage5 {

    UIImageView *imageView = [[UIImageView alloc] initWithFrame:self.view.frame];

    // 网络图
    NSURL *url = [NSURL URLWithString:@"http://res.hongrenshuo.com.cn/66532a15-c726-4edf-bb4f-0b8897753f31.gif?t=1606124887942"];
    [imageView sd_setImageWithURL:url];


    // 本地图
//    NSString * path = [[NSBundle mainBundle] pathForResource:@"直播间测试gif" ofType:@"gif"];
//    NSData * data = [NSData dataWithContentsOfFile:path];
//    UIImage *image = [UIImage sd_imageWithGIFData:data];
//    imageView.image = image;
    [self.view addSubview:imageView];
    NSLog(@"SD加载image");

}

现在开始。

1,首先我们看下SDWebImage是怎么加载gif的。

对外暴露的方法只有一个,传入gif的二进制数据, 返回生成的UIImage对象,

由于传入的二进制数据, 这个gif可以是在工程中的, 也可以是网络上的图片下载到沙盒,然后读取出来传入给此方法.

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

2.此方法调用到了SDImageGIFCoder, 但是SDImageGIFCoder中没有实现此方法, 只好到父类中寻找, SDImageGIFCoder的父类是SDImageIOAnimatedCoder, 看下父类中的实现.

看下面方法之前先看下这个东西, 有助于下面的理解: 

CGImageSourceRef source = CGImageSourceCreateWithData((__bridge CFDataRef)data, NULL); // 解码二进制数据,获取到图片的原始信息

CGImageSourceRef定义如下,typedef struct CGImageSource *CGImageSourceRef;

可以看到它是一个CGImageSource 指针。
CGImageSource又是什么呢?
CGImageSource是对图像数据读取任务的抽象,通过它可以获得图像对象、缩略图、图像的属性(包括Exif信息)。

  • 解码图片原始数据,判断静态图还是gif,走进不同的处理方法中
  • 动态图添加到数组中, 然后统一返回一个UIImage
// 解码二进制数据,生成UIImage对象
- (UIImage *)decodedImageWithData:(NSData *)data options:(nullable SDImageCoderOptions *)options {
    if (!data) {
        return nil;
    }
    CGFloat scale = 1;
    NSNumber *scaleFactor = options[SDImageC
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值