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 ...
随机推荐
- [原创]mysql的zip包如何在windows下安装
今天在尝试zipkin的链路数据写入mysql,本机恰好没有按照mysql.找到一个很久前谁发的mysql-5.6.19-winx64.zip,版本不新?别挑剔啦,只是本机测试,能用就好哈哈.. 解压 ...
- 【CSS3】布局
浮动布局: <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <tit ...
- ES6之Class
ES6中的Class和JS的比起来无疑是让对象原型的写法更加清晰,更像面向对象编程的语法而已,注意一个问题ES6里面的Class的内部定义的所有方法都是不可枚举的,而且在ES6中Class不存在变量提 ...
- jQuery架构(源码)分析
( function( global, factory ) { "use strict"; if ( typeof module === "object" &a ...
- iOS OC应用异常捕获,崩溃退出前返回信息给后台
第三方的了,有友盟,腾讯的bugly 查了一下网上类似的代码很多,在借鉴前辈的代码后,组合了一下: 1.捕获异常信息 2.获得当前日期,版本,系统 3.获得出bug的视图控制器转为字符串 4.将前3条 ...
- iOS 常用到的宏#define
//AppDelegate #define APPDELEGATE [(AppDelegate*)[UIApplication sharedApplication] delegate] //----- ...
- ArcGIS 网络分析[2.1] 最短路径
最短路径求解 [如果看到此博客还没有网络数据集的,请参考第一章的内容,点击我,看目录] 最短路径,是什么最短?时间最短?距离最短?什么距离?路程距离? 考虑到拥堵问题,限速问题,换乘问题,在现实的最短 ...
- jsDOM编程-乌龟抓小鸡游戏
<html> <head> <title>js乌龟抓小鸡游戏 </title> <meta http-equiv="conten ...
- Python 错误 UnicodeEncodeError: 'ascii' codec can't encode character 的解决方案
一.使用workbook.get_sheet_by_name(name) 获取excel一个工作表时,发生字符集解析的错误. 网上搜集解决方案为添加以下三句: import sys reload(sy ...
- python自动安装mysql5.7
python自动安装mysql5.7 python版本:python2.6 centos版本:centos6.9 mysql版本:mysql5.7.19 安装目录路径和数据目录路径都是固定,当然也可以 ...