美文网首页Coding is cool
[iOS]Native应对WebP使用的解决方案

[iOS]Native应对WebP使用的解决方案

作者: 春眠不觉晓光 | 来源:发表于2017-06-02 17:19 被阅读189次

一、WebP是什么?

WebP格式,谷歌(google)开发的一种旨在加快图片加载速度的图片格式。图片压缩体积大约只有JPEG的2/3,并能节省大量的服务器带宽资源和数据空间。

是一种支持有损压缩和无损压缩的图片文件格式,派生自图像编码格式 VP8。根据 Google 的测试,无损压缩后的 WebP 比 PNG 文件少了 45% 的文件大小,即使这些 PNG 文件经过其他压缩工具压缩之后,WebP 还是可以减少 28% 的文件大小。

下图是腾讯的测试:

对比 PNG 原图、PNG 无损压缩、PNG 转 WebP(无损)、PNG 转 WebP(有损)的压缩效果。



二、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];

}];

}




水平有限,站在巨人的肩膀上,有问题可以下面指出讨论。

相关文章

网友评论

本文标题:[iOS]Native应对WebP使用的解决方案

本文链接:https://www.haomeiwen.com/subject/aknyfxtx.html