SDWebImage(一) GIF播放

工作的时候,需要播放某几帧有延时的GIF,才发现工程中接入的SDWebImage(V3.8)不支持这个功能。


某一些帧有明显延时 (网络图片,侵删)

为了解决这个问题,查了一些资料,看了SDWebImage源码,所以做个记录:在4.0之前,SDWebImage自带GIF播放效果,不需要特殊处理;从4.0开始,SDWebImage集成FLAnimatedImageView来播放GIF。

V4.0之前

SDWebImage源码里面,对于获取到的图片信息(二进制数据),如果判定为GIF,就换成GIF图:

+ (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);
            if (!image) {
                continue;
            }
            //获取每一帧的展示时长,并相加,得到整个GIF的时长
            duration += [self sd_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;
}

如上所示,整个GIF的duration是每一帧的展示时长相加之和,从而导致最终每一帧展示的时长是一样的。对于普通的GIF,可以满足需求,但是对于那些某一帧需要特别停顿较长时间的GIF,就满足不了需求。

不过,这个版本中,SDWebImage外露的下载GIF和普通图片(png、JPG等)的接口是一致的。所以,使用者不用区分需要下载的是GIF还是普通图片,使用统一的接口下载即可。

V4.0及以上

从4.0开始,SDWebImage集成了FLAnimatedImageView,并且新建了一个FLAnimatedImageView的分类,专门用于播放GIF:


FLAnimatedImageView的分类

如果想要下载的是GIF,那么对应的UIImageView必须FLAnimatedImageView的对象,并且使用FLAnimatedImageView+WebCache提供的接口:

    FLAnimatedImageView *imageView = [[FLAnimatedImageView alloc] init];
    imageView.frame = CGRectMake(100, 300, 38, 38);
    [imageView sd_setImageWithURL:[NSURL URLWithString:@"https://www.xxx.com/xxx.gif"] placeholderImage:nil options:SDWebImageRefreshCached];
    [self.view addSubview:imageView];

而且,FLAnimatedImageView里面,使用了CADisplayLink作为计时器来播放GIF,从而可以达到每一帧时长都不同的效果。

分析

个人觉得,4.0之所以集成FLAnimatedImageView,主要就是为了可以播放每一帧的展示时长会不同的GIF。

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 14,702评论 4 61
  • 写在第一次小组学习会后,这是正式的学习感悟,我是认真的! 六月的下旬, 一个突发奇想, 然后,我就遇上了一群可爱的...
    弱水雾w阅读 3,047评论 0 3
  • @洋葱阅读100天航海W1-自我管理之《见识》 一、为什么读这本书 《见识》作者:吴军 豆瓣评分8.3。推荐系数:...
    吴小音阅读 2,481评论 0 0
  • 剑魔分享: 以色列,一个看似动乱,但比任何人都珍惜和捍卫和平的国家; 以色列,一个沙漠覆盖三分之二,但创造了沙漠农...
    剑魔纵横阅读 4,884评论 0 0
  • 和大家分享下英国诗人威廉・布莱克的《天真的预示》诗节选。配小女子插画一幅,以共勉之。 一颗沙里看出一个世界, ...
    美目盼兮雪阅读 6,411评论 49 65

友情链接更多精彩内容