欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

SDWebImage 加载显示 WebP 与性能问题

程序员文章站 2022-06-16 17:33:59
SDWebImage 加载显示 WebP 与性能问题 本文包含自定义下载操作 SDWebImageDownloaderOperation 与编码器 SDWebImageCoder。SDWebImage 的版本为 4.2.3。 静态图片 对于静态图片来说,WebP 比 PNG 体积小,可以省流量,但是 ......

SDWebImage 加载显示 WebP 与性能问题

本文包含自定义下载操作 SDWebImageDownloaderOperation 与编码器 SDWebImageCoder。SDWebImage 的版本为 4.2.3。

静态图片

对于静态图片来说,WebP 比 PNG 体积小,可以省流量,但是解码时间长。如果不需要 WebP 的原图数据,可以把 WebP 静态图片保存为 PNG 或 JPEG,加快解码速度。这一步可以通过自定义下载操作 SDWebImageDownloaderOperation 实现。

SDWebImageDownloaderOperation 的 URLSession:task:didCompleteWithError: 方法会把下载好的原图数据 imageData 通过 callCompletionBlocksWithImage:imageData:error:finished: 方法传给上层的回调 SDWebImageDownloaderCompletedBlock。

SDWebImage 加载显示 WebP 与性能问题

可以自定义 SDWebImageDownloaderOperation,修改 URLSession:task:didCompleteWithError: 方法,在上图箭头所指处修改 imageData,把静态 WebP 图片数据转为 PNG 或 JPEG 图片数据。修改上述方法只需要添加一行代码

imageData = [[SDWebImageCodersManager sharedInstance] encodedDataWithImage:image format:SDImageFormatUndefined];

原图数据有 Alpha 信息就转为 PNG,否则转为 JPEG。

自定义的类是 ImageDownloaderOperation,使用这个类需要一行代码

[[SDWebImageManager sharedManager].imageDownloader setOperationClass:[ImageDownloaderOperation class]];

动态图片

WebP 格式支持动态图片。SDWebImageWebPCoder 的 decodedImageWithData: 负责解码,返回 UIImage。如果是动态图片,每一帧图片都会解码,用所有图片帧和总动画时长通过 animatedImageWithImages:duration: 方法生成 UIImage。这样做的好处是,节省 CPU 资源,不用重复解码。对小图片来说,比较合适。如果图片太大,就会占内存多。另外,如果原图的每一帧动画时长不相等,那么实际播放的动画就与原图动画不符。可以用 YYImage 和 YYAnimatedImageView 来显示动态 WebP。这样可以用 CPU 资源换取内存空间(YYImage 也可以预先解码所有图片帧),也可以根据原图的每一帧动画时长来播放动画。直接使用 YYWebImage 框架是最方便的方法。然而,如果项目中需要统一图片的下载、缓存管理等操作,最好只用一套图片下载库。这里介绍用 SDWebImage 下载、缓存,用 YYImage 显示 WebP 的方法。

YYImage 会对 WebP 进行解码,因此不需要 SDWebImageWebPCoder 解码所有图片帧。自定义编码器 SDWebImageCoder,只对第一帧图片进行解码,减少解码时间。修改 decodedImageWithData: 方法,在解码每一帧图片的 while 循环中 (下图箭头所指处) 添加 break 即可,解码成功一帧图片就退出循环。

SDWebImage 加载显示 WebP 与性能问题

自定义编码器的类是 FirstFrameWebPCoder,使用这个编码器

[SDWebImageCodersManager sharedInstance].coders = @[[SDWebImageImageIOCoder sharedCoder],
                                                    [FirstFrameWebPCoder sharedCoder]];

加载显示图片 (cell.imageView 是 YYAnimatedImageView)

cell.imageView.image = placeholder;
[[SDWebImageManager sharedManager] loadImageWithURL:url options:0 progress:nil completed:^(UIImage * _Nullable image, NSData * _Nullable data, NSError * _Nullable error, SDImageCacheType cacheType, BOOL finished, NSURL * _Nullable imageURL) {
    if ([image isKindOfClass:[YYImage class]]) {
        cell.imageView.image = image;
    } else if (data) {
        YYImage *yyimage = [YYImage imageWithData:data];
        cell.imageView.image = yyimage;
        NSString *key = [[SDWebImageManager sharedManager] cacheKeyForURL:url];
        [[SDWebImageManager sharedManager].imageCache storeImage:yyimage forKey:key toDisk:NO completion:nil];
    }
}];

代码已上传 GitHub:https://github.com/Silence-GitHub/WebPDemo

转载请注明出处:http://www.cnblogs.com/silence-cnblogs/p/8319917.html