SDWebImage 源码分析 --加载gif图片
2015-02-13 17:18
357 查看
n年关了,马上放假,终于把手头上的事情告一段落,连续发布了3个app,我也是醉了。终于有了点时间。想研究下SDWebImage是怎么加载gif图片的。一直很好奇。现在开始。1,首先我们看下SDWebImage是怎么加载gif的。
typedef struct CGImageSource *CGImageSourceRef;可以看到它是一个CGImageSource 指针。CGImageSource又是什么呢?CGImageSource是对图像数据读取任务的抽象,通过它可以获得图像对象、缩略图、图像的属性(包括Exif信息)。那么这行代码可以这样理解:通过nadata取到图像的以系列信息。goon,size_t count = CGImageSourceGetCount(source);这行代码是读取CGImageSourceRef有几个图片对象。next,下面就不难理解了,CGImageSourceCreateImageAtIndex 从source里面读取各个图片放入数组里面。读取显示图片的 时间。duration += [self frameDurationAtIndex:i source:source];4,计算图片显示时间
animatedImage = [UIImage animatedImageWithImages:images duration:duration];播放数组里里面的图片。over!!!!
faceButton.image = [UIImage sd_animatedGIFNamed:[NSString stringWithFormat:@"CHATA_%d",i - 46]];
sd_animatedGIFNamed是SDWebImage提供的加载gif图片的一种方法。我们点进去这个方法去看以下。 2,sd_animatedGIFNamed 这个方法的实现如下。生成一个UIImage对象。
+ (UIImage *)sd_animatedGIFNamed:(NSString *)name {
//取到屏幕分辨率
CGFloat scale = [UIScreen mainScreen].scale;//是否是高清屏
if (scale > 1.0f) {
//如果是高清屏 取@2x图片
//读取图片
NSString *retinaPath = [[NSBundle mainBundle] pathForResource:[name stringByAppendingString:@"@2x"] ofType:@"gif"];//图片转换为data
NSData *data = [NSData dataWithContentsOfFile:retinaPath];//如果图片存在
if (data) {
//调用sd_animatedGIFWithData 生成image实例
//
return [UIImage sd_animatedGIFWithData:data];
}//如果@2x图片不存在 读取普通图片
NSString *path = [[NSBundle mainBundle] pathForResource:name ofType:@"gif"];//图片转换为data
data = [NSData dataWithContentsOfFile:path];//如果图片存在
if (data) {
//调用sd_animatedGIFWithData 生成image实例
return [UIImage sd_animatedGIFWithData:data];
}//如果图片不存在
return [UIImage imageNamed:name];
}
else {
//如果不是高清屏 读取普通图片
NSString *path = [[NSBundle mainBundle] pathForResource:name ofType:@"gif"];
//图片转换为data
NSData *data = [NSData dataWithContentsOfFile:path];//如果图片存在
if (data) {
//调用sd_animatedGIFWithData 生成image实例
return [UIImage sd_animatedGIFWithData:data];
}
//如果图片不存在
return [UIImage imageNamed:name];
}
}
注释已经很详细了,这个类方法里面主要是确定当前设备的分辨率,以便加载不同分辨率的图片。 然后通过
dataWithContentsOfFile
方法把图片转换为NSData,判断NSData是否存在。
如果存在调用sd_animatedGIFWithData 后续处理。3,sd_animatedGIFWithData 方法。
+ (UIImage *)sd_animatedGIFWithData:(NSData *)data {
if (!data) {
return nil;
}CGImageSourceRef source = CGImageSourceCreateWithData((__bridge CFDataRef)data, NULL);size_t count = CGImageSourceGetCount(source);UIImage *animatedImage;if (count <= 1) {
animatedImage = [[UIImage alloc] initWithData:data];
}
else {
NSMutableArray *images = [NSMutableArray array];NSTimeInterval duration = 0.0f;for (size_t i = 0; i < count; i++) {
CGImageRef image = CGImageSourceCreateImageAtIndex(source, i, NULL);duration += [self frameDurationAtIndex:i source:source];[images addObject:[UIImage imageWithCGImage:image scale:[UIScreen mainScreen].scale orientation:UIImageOrientationUp]];CGImageRelease(image);
}if (!duration) {
duration = (1.0f / 10.0f) * count;
}animatedImage = [UIImage animatedImageWithImages:images duration:duration];
}CFRelease(source);return animatedImage;
}
先看这行代码
CGImageSourceRef source = CGImageSourceCreateWithData((__bridge CFDataRef)data, NULL);
CGImageSourceRef定义如下,
typedef struct CGImageSource *CGImageSourceRef;可以看到它是一个CGImageSource 指针。CGImageSource又是什么呢?CGImageSource是对图像数据读取任务的抽象,通过它可以获得图像对象、缩略图、图像的属性(包括Exif信息)。那么这行代码可以这样理解:通过nadata取到图像的以系列信息。goon,size_t count = CGImageSourceGetCount(source);这行代码是读取CGImageSourceRef有几个图片对象。next,下面就不难理解了,CGImageSourceCreateImageAtIndex 从source里面读取各个图片放入数组里面。读取显示图片的 时间。duration += [self frameDurationAtIndex:i source:source];4,计算图片显示时间
+ (float)frameDurationAtIndex:(NSUInteger)index source:(CGImageSourceRef)source {
float frameDuration = 0.1f;
CFDictionaryRef cfFrameProperties = CGImageSourceCopyPropertiesAtIndex(source, index, nil);
NSDictionary *frameProperties = (__bridge NSDictionary *)cfFrameProperties;
NSDictionary *gifProperties = frameProperties[(NSString *)kCGImagePropertyGIFDictionary];NSNumber *delayTimeUnclampedProp = gifProperties[(NSString *)kCGImagePropertyGIFUnclampedDelayTime];
if (delayTimeUnclampedProp) {
frameDuration = [delayTimeUnclampedProp floatValue];
}
else {NSNumber *delayTimeProp = gifProperties[(NSString *)kCGImagePropertyGIFDelayTime];
if (delayTimeProp) {
frameDuration = [delayTimeProp floatValue];
}
}if (frameDuration < 0.011f) {
frameDuration = 0.100f;
}CFRelease(cfFrameProperties);
return frameDuration;
}
详细分析 待续!!! 5,
animatedImage = [UIImage animatedImageWithImages:images duration:duration];播放数组里里面的图片。over!!!!
相关文章推荐
- 加载gif图片的方法:(需要SDWebImage方法)
- 使用SDWebImageView加载gif图片
- ios-使用SDWebImage加载Gif图片的问题
- 加载gif图片的方法:(需要SDWebImage方法)
- iOS 使用SDWebImage加载gif链接图片时内存过大问题
- 加载gif图片的方法:(需要SDWebImage方法)
- SDWebImage使用——一个可管理远程图片加载的类库
- iOS 图片加载框架SDWebImage详解
- SDWebImage一个可管理远程图片加载的类库
- SDWebimage加载图片
- SDWebImage使用——一个可管理远程图片加载的类库
- 基于SDWebImage的网络图片加载处理 & 获取网络中得UIimage
- SDWebImage加载图片问题
- 解决SDWebImage加载多个图片内存崩溃的问题
- iOS第三方框架: 使用SDWebImage 加载不出图片
- SDWebImage异步加载图片及缓存的管理与清理
- SDWebImage使用——一个可管理远程图片加载的类库
- iOS网络编程(三) 异步加载及缓存图片---->SDWebImage
- SDWebImage-图片自动缓存、异步加载实用库
- SDWebImage使用,图片加载和缓存