一、WebP是什么?
WebP格式,谷歌(google)开发的一种旨在加快图片加载速度的图片格式。图片压缩体积大约只有JPEG的2/3,并能节省大量的服务器带宽资源和数据空间。
是一种支持有损压缩和无损压缩的图片文件格式,派生自图像编码格式 VP8。根据 Google 的测试,无损压缩后的 WebP 比 PNG 文件少了 45% 的文件大小,即使这些 PNG 文件经过其他压缩工具压缩之后,WebP 还是可以减少 28% 的文件大小。
下图是腾讯的测试:
对比 PNG 原图、PNG 无损压缩、PNG 转 WebP(无损)、PNG 转 WebP(有损)的压缩效果。
二、WebP的优势
http://isux.tencent.com/introduction-of-webp.html
腾讯技术分享讲了下面这段话:
WebP 的优势体现在它具有更优的图像数据压缩算法,能带来更小的图片体积,而且拥有肉眼识别无差异的图像质量;同时具备了无损和有损的压缩模式、Alpha 透明以及动画的特性,在 JPEG 和 PNG 上的转化效果都非常优秀、稳定和统一。
至于WebP是如何压缩的,我没有做深入调研。但是从刚才的效果和数据比对,我们不难看出,在不影响图片展示效果的前提下,相比较PNG,压缩出来的WebP图片体积更小,有损压缩比占到原图的78%。对于节省移动APP数据流量的问题,WebP具有明显优势,值得我们使用。
三、如何应用到iOS工程
在iOS的开发中,获取网络图片我们基本上都会使用开源库SDWebImage,正好SDWebImage也支持webp格式图片的加载。可以将webp-->NSData-->UIImage最后变为可识别的图片格式直接给控件调用。
SDWebImage支持webp格式图片的加载,步骤如下:
方案一:
1、工程引入SDWebImage开源库。
2、下载打包WebP.framework,下载地址:https://github.com/webmproject/libwebp。
注意: 执行资源包里面iosbulid.sh脚本,就可以打出WebP.framework
3、让SDWebImage支持WebP,设置如下Build Settings -- Preprocessor Macros , add SD_WEBP=1
方案二:
最近SDWebImage的最新版本自己也做了支持WebP格式的功能,毕竟现在google推出的这个格式确实适合用在移动设备上,可以导入的时候直接通过cocoaPods:
pod 'SDWebImage/WebP'
调用与webp相关的代码很通俗易懂,不解释,如下:
注意:由于需要依赖google的库,所以需要VPN,VPN,VPN,重要的事情说三遍。
四、图片测试,如何做到图片格式转换?
在Mac下,可以使用homebrew安装webp工具:
brew install webp
安装完命令行工具后,就可以使用cwebp将JPG或PNG图片转换成WebP格式。
cwebp [-preset <...>] [options] in_file [-o out_file]
options参数列表中包含质量参数q,q为0~100之间的数字,比较典型的质量值大约为80。
也可以使用dwebp将WebP图片转换回PNG图片(默认)。
dwebp in_file [options] [-o out_file]
五、代码测试
使用SDImage库里面的sd_imageWithWebPData方法提供的Data,来渲染UIImageView。
UIView *webpView = [[UIView alloc] initWithFrame:self.view.bounds];
[self.view addSubview:webpView];
NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:@"https://o098vaj28.qnssl.com/2017060116240118734.webp"]];
UIImageView *wpimage = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
wpimage.center = webpView.center;
#ifdef SD_WEBP
[wpimage setImage:[UIImage sd_imageWithWebPData:data]];
#endif
[webpView addSubview:wpimage];
注意:webp文件引入到工程中,是不能直接通过NSBundle来取的。如下,失败!
NSBundle *mainBundle = [NSBundle mainBundle];
//本地的webp文件,竟然不能用取文件目录的方式mainBundle 取文件,,如下,失败
// NSString *imagePath = [mainBundle pathForResource:@"2017060116240118734" ofType:@"webp"];
// NSData *data = [NSData dataWithContentsOfFile:imagePath];
六、WebView使用WebP[扩展]
找了几篇大神写的文章,目前WebP应对WebView通用的有这两种:
1、和 JS 协作
2、NSURLProtocol
时间紧张,我只测试了第一种。参考地址:http://www.jianshu.com/p/ed7562a34af1
H5代码如下:
OC端支撑
- (void)webViewDidFinishLoad:(UIWebView *)webView {
//---------------------------------测试-----------------------------------
//获取`HTML`代码
NSString *lJs = @"document.documentElement.innerHTML";
NSString *str = [webView stringByEvaluatingJavaScriptFromString:lJs];
//执行约定好的方法,获取需要下载的 webp 图片
NSString *imgs = [webView stringByEvaluatingJavaScriptFromString:@"YongChe.getAllWebPImg();"];
NSArray *array = [NSJSONSerialization JSONObjectWithData:[imgs dataUsingEncoding:NSUTF8StringEncoding] options:0 error:nil];
//此处,做示范,只转换第一个,将图片下载下来,并且转为 PNG 后,再转成 Base64,传给 JS 脚本执行
NSString *imgUrl = array.firstObject;
__weak typeof (self) weakSelf = self;
SDWebImageManager *_manager = [SDWebImageManager new];
[_manager downloadImageWithURL:[NSURL URLWithString:imgUrl] options:SDWebImageProgressiveDownload progress:nil completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) {
NSString *pngPath = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents/Test.png"];
NSString *jpgPath = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents/Test.jpg"];
[UIImageJPEGRepresentation(image, 1.0) writeToFile:jpgPath atomically:YES];
// Write image to PNG
[UIImagePNGRepresentation(image) writeToFile:pngPath atomically:YES];
NSString *base = [NSString stringWithFormat:@"data:image/png;base64,%@",image];
NSString *js = [NSString stringWithFormat:@"YongChe.replaceWebPImg('%@','%@')",imageURL,pngPath];
[webView stringByEvaluatingJavaScriptFromString:js];
}];
}
水平有限,站在巨人的肩膀上,有问题可以下面指出讨论。
网友评论
可参考https://www.jianshu.com/p/1a96b54486fc