UIImageView实现加载网络gif图片

Posted likun123

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了UIImageView实现加载网络gif图片相关的知识,希望对你有一定的参考价值。


#import
<UIKit/UIKit.h> NS_ASSUME_NONNULL_BEGIN @interface UIImageView (WZGif) /// 加载本地gif /// @param imageName gif名字 - (void)showGifImageLocalWithImageName:(NSString *)imageName; /// 加载网络gif /// @param url gifURL - (void)showGifImageWithURL:(NSURL *)url; @end NS_ASSUME_NONNULL_END
#import "UIImageView+WZGif.h"
#import <ImageIO/ImageIO.h>

#if __has_feature(objc_arc)
#define toCF (__bridge CFTypeRef)
#define ARCCompatibleAutorelease(object) object
#else
#define toCF (CFTypeRef)
#define ARCCompatibleAutorelease(object) [object autorelease]
#endif

@implementation UIImageView (WZGif)

- (void)animatedGIFImageSource:(CGImageSourceRef) source
                   andDuration:(NSTimeInterval) duration {
    
    
    if (!source) return;
    size_t count = CGImageSourceGetCount(source);
    NSMutableArray *images = [NSMutableArray arrayWithCapacity:count];
    for (size_t i = 0; i < count; ++i) {
        CGImageRef cgImage = CGImageSourceCreateImageAtIndex(source, i, NULL);
        if (!cgImage)
            return;
        [images addObject:[UIImage imageWithCGImage:cgImage]];
        CGImageRelease(cgImage);
    }
    [self setAnimationImages:images];
    [self setAnimationDuration:duration];
    [self startAnimating];
}

- (NSTimeInterval)durationForGifData:(NSData *)data {
    char graphicControlExtensionStartBytes[] = {0x21,0xF9,0x04};
    double duration=0;
    NSRange dataSearchLeftRange = NSMakeRange(0, data.length);
    while(YES){
        NSRange frameDescriptorRange = [data rangeOfData:[NSData dataWithBytes:graphicControlExtensionStartBytes
                                                                        length:3]
                                                 options:NSDataSearchBackwards
                                                   range:dataSearchLeftRange];
        if(frameDescriptorRange.location!=NSNotFound){
            NSData *durationData = [data subdataWithRange:NSMakeRange(frameDescriptorRange.location+4, 2)];
            unsigned char buffer[2];
            [durationData getBytes:buffer length:1];
            double delay = (buffer[0] | buffer[1] << 8);
            duration += delay;
            dataSearchLeftRange = NSMakeRange(0, frameDescriptorRange.location);
        }else{
            break;
        }
    }
    return duration/100;
}

- (void)showGifImageWithData:(NSData *)data {
    NSTimeInterval duration = [self durationForGifData:data];
    CGImageSourceRef source = CGImageSourceCreateWithData(toCF data, NULL);
    [self animatedGIFImageSource:source andDuration:duration];
    CFRelease(source);
}

- (void)loadImageWith:(NSString *)filePath{
    if (self && self != nil) {
        dispatch_async(dispatch_get_main_queue(), ^{
            NSData *data = [NSData dataWithContentsOfFile:filePath];
            NSString *imageType = [self imageTypeWithData:data];
            if ([imageType isEqualToString:@"gif"]) {
                [self showGifImageWithData:data];
            }else{
                if (self.isAnimating) {
                    [self stopAnimating];
                }
                [self setImage:[UIImage imageWithData:data]];
            }
            
        });
    }
}
/// 加载网络gif
/// @param url gifURL
- (void)showGifImageWithURL:(NSURL *)url {
    
    NSFileManager *fileManager = [NSFileManager defaultManager];
    NSString *cache = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES)  lastObject];
    NSString *filePath = [cache stringByAppendingPathComponent:url.lastPathComponent];
    BOOL flag = [[NSFileManager defaultManager] fileExistsAtPath:filePath];
    if (flag) {
        [self loadImageWith:filePath];
    }else{
        NSURLRequest *reque = [NSURLRequest requestWithURL:url];
        NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration ephemeralSessionConfiguration]];
        NSURLSessionDownloadTask *task = [session downloadTaskWithRequest:reque completionHandler:^(NSURL *location, NSURLResponse *response, NSError *error) {
            NSURL *toURL = [NSURL fileURLWithPath:filePath];
            [fileManager moveItemAtURL:location toURL:toURL error:nil];
            [self loadImageWith:filePath];
            
        }];
        [task resume];
    }
}
/// 加载本地gif
/// @param imageName gif名字
- (void)showGifImageLocalWithImageName:(NSString *)imageName{
    NSString *filePath = [[NSBundle mainBundle] pathForResource:imageName ofType:@"gif"];
    [self loadImageWith:filePath];
}

/// 获取数据类型
/// @param data data
- (NSString *)imageTypeWithData:(NSData *)data {
    
    uint8_t type;
    
    [data getBytes:&type length:1];
    
    switch (type) {
            
        case 0xFF:
            return @"jpeg";
            
        case 0x89:
            return @"png";
            
        case 0x47:
            return @"gif";
            
        case 0x49:
        case 0x4D:
            return @"tiff";
            
        case 0x52:
            if([data length] < 12) {
                return nil;
            }
            NSString *testString = [[NSString alloc] initWithData:[data subdataWithRange:NSMakeRange(0, 12)] encoding:NSASCIIStringEncoding];
            if([testString hasPrefix:@"RIFF"] && [testString hasSuffix:@"WEBP"]) {
                return@"webp";
            }
            
            return nil;
    }
    
    return nil;
}

 

以上是关于UIImageView实现加载网络gif图片的主要内容,如果未能解决你的问题,请参考以下文章

ios UIImageView异步加载网络图片

推荐iOS带有加载网络图片进度的UIImageView

iOS UIImageView 网络图片资源加载不出来,但在Chorme浏览器上可以打开

iOS获取网络图片大小

iOS图片加载框架-SDWebImage解读

SDWebImage使用,图片加载和缓存