SDWebImage学习之GIF加载.md 2.5 KB

SDWebImage GIF图加载

GIF是图片的一种压缩格式,其实就是将多张具有一定存活时间的静态图片压缩组合在了一起,在展示时将这些静态图片按照播放时长连贯播放就形成了动画

UIImageView控件并不能直接支持GIF 使用ImageIO.framework的API可以实现播放 获取gifData的imageSource

CGImageSourceRef source = CGImageSourceCreateWithData((__bridge CFDataRef)_gifData, NULL);

获取图片的帧数

size_t count = CGImageSourceGetCount(source);

获取image数组 然后通过imageView.animationImages = images即可实现

各个版本对比

SDWebImage4.0 以前版本

加载一个GIF图的url,显示的是静态的图片

SDWebImage4.x

采用FLAnimatedImageView

dispatch_main_async_safe(block) 保证 block 在主线程中执行,其中包含 setImageBlock。因此 setImageBlock 在主线程中执行,也就是说 FLAnimatedImage 在主线程中生成,这一步比较耗时,阻塞主线程,造成卡顿。 解决办法是,把FLAnimatedImage的创建放到子线程中。

给FLAnimatedImageView添加扩展方法

func setImage(with url: URL?, placeholderImage: UIImage?) {
    sd_internalSetImage(with: url, placeholderImage: placeholderImage, options: SDWebImageOptions(rawValue: 0), operationKey: nil, setImageBlock: { [weak self] (image, imageData) in
        guard let strongSelf = self else { return }

        let imageFormat = NSData.sd_imageFormat(forImageData: imageData)
        if imageFormat == .GIF {
            // Enter global queue
            DispatchQueue.global(qos: .userInteractive).async { [weak self] in
                // Create FLAnimatedImage in global queue
                let animatedImage = FLAnimatedImage(animatedGIFData: imageData)
                DispatchQueue.main.async { [weak self] in
                    guard let strongSelf = self else { return }
                    // Set image in main queue
                    strongSelf.animatedImage = animatedImage
                    strongSelf.image = nil
                }
            }
        } else {
            // Set image in main queue
            strongSelf.image = image
            strongSelf.animatedImage = nil
        }
        }, progress: nil, completed: nil)
}

同样调用 sd_internalSetImageWithURL: 方法,只是修改 setImageBlock 参数,在子线程中创建 FLAnimatedImage,然后在主线程中设置图片。

SDWebImage5.x