SDWebImage 加载显示 WebP 与性能问题
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。

可以自定义 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 即可,解码成功一帧图片就退出循环。

自定义编码器的类是 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
SDWebImage 加载显示 WebP 与性能问题的更多相关文章
- SDWebImage 加载显示 GIF 与性能问题
SDWebImage 加载显示 GIF 与性能问题 SDWebImage 4.0 之前,可以用 UIImageView 显示 GIF 图.如果 SDWebImage 4.0 还这么做,只会显示静态图. ...
- SDWebImage 加载网络图片失败,重新运行,就能加载成功。
现象: 使用SDWebImage 加载网络图片,偶尔会有一两张图片就是显示不出来.重新运行有时又可以了. 这个问题的原因是: 当SDWebImage 在加载图片的时候 我用的是- (void)sd_s ...
- 解决MWPhotoBrowser中的SDWebImage加载大图导致的内存警告问题
下面两种现象,用同一种方法解决 1.解决MWPhotoBrowser中的SDWebImage加载大图导致的内存警告问题 2.突然有一天首页访问图片很慢,至少隔20多秒所有图片才会出来.(解析:app使 ...
- 关于SDWebImage加载高清图片导致app崩溃的问题
链接是对于SDWebImage的使用方法 http://www.cnblogs.com/JimmyBright/p/4457258.html 使用SDWebImage加载高清图片的时候,往往会报内存溢 ...
- bootstrap模态框modal使用remote第二次加载显示相同内容解决办法
bootstrap模态框modal使用remote动态加载内容,第二次加载显示相同内容解决办法 bootstrap的modal中,使用remote可以动态加载页面到modal-body中,并弹窗显示 ...
- [ActionScript 3.0] AS3.0 动态加载显示内容
可以将下列任何外部显示资源加载到 ActionScript 3.0 应用程序中: 在 ActionScript 3.0 中创作的 SWF 文件 — 此文件可以是 Sprite.MovieClip 或扩 ...
- JS脚本加载与执行对性能的影响
高性能JavaScript-JS脚本加载与执行对性能的影响 在web产品优化准则中,很重要的一条是针对js脚本的加载和执行方式的优化.本篇文章简单描述一下其中的优化准则. 1. 脚本加载优化 1.1 ...
- 一个页面从输入url到页面加载显示完成,中间都经历了什么
第一种解释: 一般会经历以下几个过程: 1.首先,在浏览器地址栏中输入url 2.浏览器先查看浏览器缓存-系统缓存-路由器缓存,如果缓存中有,会直接在屏幕中显示页面内容.若没有,则跳到第三步操作. 3 ...
- 用SDWebImage加载FLAnimatedImage
用SDWebImage加载FLAnimatedImage 效果 源码 https://github.com/YouXianMing/Animations // // GifPictureControl ...
随机推荐
- CentOS 7 学习(三)配置Tomcat集群
所谓集群,就是把多台服务器集合起来,对外提供一个接口访问,对用户来说完全透明,常用的办法就是前端放一个服务器,将用户请求分发到不同的服务器,大致有以下几种方案 1)采取DNS轮询:将用户的连接解析到不 ...
- 《写给大家看的设计书(第3版)》【PDF】下载
<写给大家看的设计书(第3版)>[PDF]下载链接: https://u253469.ctfile.com/fs/253469-231196355 内容简介 <写给大家看的设计书&g ...
- Oracle安装步骤
1.在Oracle官网下载安装包: 2.非常重要:两个压缩包都要解压(不是分卷压缩的,不然安装过程中会报找不到文件的错误,被坑过!): 3.关闭所有安全相关软件(关闭杀毒软件.防火墙.windows ...
- 数据分析与展示——Matplotlib库入门
Matplotlib库入门 Matplotlib库介绍 Matliotlib库是Python优秀的数据可视化第三方库. Matliotlib库的效果见:http://matplotlib.org/ga ...
- Python学习日记:day4
列表 li=['alex',[1,2,3] ,'wusir','egon','女神','taibai']#列表 l1 = li[0] print(l1)#alex l2 = li[1] print ( ...
- verilog抓外部低频输入信号的上升沿和下降沿
版权申明:本文为博主窗户(Colin Cai)原创,欢迎转帖.如要转贴,必须注明原文网址 http://www.cnblogs.com/Colin-Cai/p/7220107.html 作者:窗户 Q ...
- nova创建虚拟机源码分析系列之八 compute创建虚机
/conductor/api.py _build_instance() /conductor/rpcapi.py _build_instance() 1 构造一些数据类型2 修改一些api版本信息 ...
- Linux(CentOS7.1)修改默认yum源为国内的阿里云yum源
官方的yum源在国内访问效果不佳. 需要改为国内比较好的阿里云或者网易的yum源 修改方式: 下载wget yum install wget -y echo 备份当前的yum源 mv /etc/yum ...
- sourcetree跳过注册的方法
当前只有Win的版本,Mac自行百度(笑) 很多人用git命令行不熟练,那么可以尝试使用sourcetree进行操作. 然鹅~~sourcetree又一个比较严肃的问题就是,很多人不会跳过注册或者操作 ...
- Linux 下Beanstalk安装
1.安装 # wget https://github.com/kr/beanstalkd/archive/v1.10.tar.gz # tar xzvf v1.10 # cd beanstalkd-1 ...