美文网首页
iOS 自定义高性能加载gif

iOS 自定义高性能加载gif

作者: Neal_f | 来源:发表于2019-04-09 12:17 被阅读0次

    一·实现的各种方式

    1.将GIF图片分解成多张PNG图片,使用UIImageView播放(内存消耗过大)
    2.使用YYImage中的YYAnimatedImageView播放,推荐,内存优化的挺好,是个高性能的框架。

    这里就不详细说明YYAnimatedImageView的实现方式了。其核心思想就是 解压gif成图片数组,利用CADisplaylink进行按帧动画显示

    二·自己实现播放gif,学习内部细节

    1.属性
    /// 用于展示帧动画
    @property (nonatomic, strong) CADisplayLink *displayLink;
    /// 图片数组
    @property (nonatomic, strong) NSArray *imageArray;
    /// 当前帧
    @property (nonatomic, assign) NSInteger currentIndex;
    /// 是否正在显示
    @property (nonatomic, assign, getter=isAnimation) BOOL animation;
    /// 总的时间
    @property (nonatomic, assign) NSTimeInterval timeDuration;
    /// 是否重复
    @property (nonatomic, assign, getter=isRepeat) BOOL repeat;
    
    2.解压gif
    /// 获取资源
    - (void)loadGif:(NSString *)gif isRepeat:(BOOL)repeat {
    
        self.repeat = repeat;
        
        //1.加载Gif图片,转换成Data类型
        NSString *path = [NSBundle.mainBundle pathForResource:gif ofType:@"gif"];
        NSData *data = [NSData dataWithContentsOfFile:path];
        
        //2.将data数据转换成CGImageSource对象
        CGImageSourceRef imageSource = CGImageSourceCreateWithData(CFBridgingRetain(data), nil);
        size_t imageCount = CGImageSourceGetCount(imageSource);
        //3.遍历所有图片
        NSMutableArray *images = [NSMutableArray array];
        NSTimeInterval totalDuration = 0;
        for (int i = 0; i<imageCount; i++) {
            //取出每一张图片
            CGImageRef cgImage = CGImageSourceCreateImageAtIndex(imageSource, i, nil);
            UIImage *image = [UIImage imageWithCGImage:cgImage];
            [images addObject:image];
            
            //持续时间
            NSDictionary *properties = (__bridge_transfer  NSDictionary*)CGImageSourceCopyPropertiesAtIndex(imageSource, i, nil);
            NSDictionary *gifDict = [properties objectForKey:(__bridge NSString *)kCGImagePropertyGIFDictionary];
            NSNumber *frameDuration =
            [gifDict objectForKey:(__bridge NSString *)kCGImagePropertyGIFDelayTime];
            totalDuration += frameDuration.doubleValue;
        }
        
        self.imageArray = [images copy];
        self.timeDuration = totalDuration;
        self.currentIndex = 0;
    }
    
    3.利用CADisplaylink实现播放
    - (void)display {
        
        if ([self.imageArray isEqual:nil] || self.imageArray.count == 0) {
            [self stopAnimating];
            return;
        }
        if (self.currentIndex > self.imageArray.count) {
            if (self.repeat) {
                self.currentIndex = 0;
                [self startAnimating];
                return;
            } else {
                [self stopAnimating];
                return;
            }
        }
    }
    
    - (CADisplayLink *)displayLink {
        if (!_displayLink) {
            _displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(display)];
            // 当把 CADisplayLink 对象添加到 Runloop 中后,selector就能被周期性调用
            [self.displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];
        }
        return _displayLink;
    }
    

    相关文章

      网友评论

          本文标题:iOS 自定义高性能加载gif

          本文链接:https://www.haomeiwen.com/subject/mpfjcftx.html