- (void)downloadImages:(int)index {
//下载图片
NSBlockOperation *download = [NSBlockOperation blockOperationWithBlock:^{
NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:urlString]];
if (!data) return;
UIImage *image = getImageWithData(data);
//取到的data有可能不是图片
if (image) {
self.images[index] = image;
//如果下载的图片为当前要显示的图片,直接到主线程给imageView赋值,否则要等到下一轮才会显示
NSLog(@"images_index= %ld",index);
if (_currIndex == index) [_currImageView performSelectorOnMainThread:@selector(setImage:) withObject:image waitUntilDone:NO];
if (_autoCache) [data writeToFile:path atomically:YES];
}
}];
[self.queue addOperation:download];
}
#pragma mark 下载图片,如果是gif则计算动画时长
UIImage *getImageWithData(NSData *data) {
CGImageSourceRef imageSource = CGImageSourceCreateWithData((__bridge CFDataRef)data, NULL);
size_t count = CGImageSourceGetCount(imageSource);
if (count <= 1) { //非gif
CFRelease(imageSource);
return [[UIImage alloc] initWithData:data];
} else { //gif图片
NSMutableArray *images = [NSMutableArray array];
NSTimeInterval duration = 0;
for (size_t i = 0; i < count; i++) {
CGImageRef image = CGImageSourceCreateImageAtIndex(imageSource, i, NULL);
if (!image) continue;
duration += durationWithSourceAtIndex(imageSource, i);
[images addObject:[UIImage imageWithCGImage:image]];
CGImageRelease(image);
}
if (!duration) duration = 0.1 * count;
CFRelease(imageSource);
return [UIImage animatedImageWithImages:images duration:duration];
}
}
#pragma mark 获取每一帧图片的时长
float durationWithSourceAtIndex(CGImageSourceRef source, NSUInteger index) {
float duration = 0.1f;
CFDictionaryRef propertiesRef = CGImageSourceCopyPropertiesAtIndex(source, index, nil);
NSDictionary *properties = (__bridge NSDictionary *)propertiesRef;
NSDictionary *gifProperties = properties[(NSString *)kCGImagePropertyGIFDictionary];
NSNumber *delayTime = gifProperties[(NSString *)kCGImagePropertyGIFUnclampedDelayTime];
if (delayTime) duration = delayTime.floatValue;
else {
delayTime = gifProperties[(NSString *)kCGImagePropertyGIFDelayTime];
if (delayTime) duration = delayTime.floatValue;
}
CFRelease(propertiesRef);
return duration;
}