前面有篇文章分析了不同的框架加载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

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


被折叠的 条评论
为什么被折叠?



