我们知道,webp格式的图片是谷歌公司为了节省用户流量而出的一种图片压缩方式。虽然是有损压缩,但是图片的大小也被缩减到一个很小的级别。所以,很多公司为了节省用户流量,尤其是有很多图片的公司,开始大量使用webp的图片。but,对于安卓来讲,同一个公司的产品,兼容起来毫无压力;苦了我们广大的iOS的开发者们。
我们一般的开发者们,加载图片的方式用的还是SDWebImage。我们希望,有没有一种方式,不用改很多代码,还是使用SDWebImage加载,就可以成load出webp的图片呢。
环境: xcode8
1、看到曙光
我们下载最新的SDWebImage(https://github.com/rs/SDWebImage.git),我目前下载的是4.2.3 。打开之后发现,其中真的有一个叫做UIImage+WebP的文件,是不是可以直接使用呢?
我们导入SDWebImage到工程中。(ps:这里没有使用cocoa pods,为什么呢?因为后面还有别的三方需要导入,但是,没有fanqiang不能成功。为了保持一致,都是用直接导入项目中的方式导入三方库)。
2、希望破灭
导入成功之后,准备使用,写一段最最简单的代码
(ps:只是写个测试方法,代码没有整理,见谅)
//
// ViewController.m
// TestSDImport
//
// Created by weiman on 2018/1/9.
// Copyright © 2018年 weiman. All rights reserved.
//
#import "ViewController.h"
#import "SDWebImage/UIImage+WebP.h"
#import "SDWebImage/UIImageView+WebCache.h"
#define mScreenWidth [UIScreen mainScreen].bounds.size.width
#define mScreenHeight [UIScreen mainScreen].bounds.size.height
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
UIImageView * imageV = [[UIImageView alloc] initWithFrame:CGRectMake(10, 50, mScreenWidth-20, 200)];
[self.view addSubview:imageV];
imageV.backgroundColor = [UIColor yellowColor];
NSString * imageurl = @"http://images21.happyjuzi.com/test/ea/09/91f522741b7a0976b5f21a3b9f78.jpg!200.nw.webp";
//NSString * imageurl = @"[http://oss.img.2or3m.com/videoimg/php/20171112/5a080c360c6c3.jpg](http://oss.img.2or3m.com/videoimg/php/20171112/5a080c360c6c3.jpg)";
[imageV sd_setImageWithURL:[NSURL URLWithString:imageurl] completed:^(UIImage * _Nullable image, NSError * _Nullable error, SDImageCacheType cacheType, NSURL * _Nullable imageURL) {
if (error) {
NSLog(@"--------- %@",error);
}else{
NSLog(@"图片加载成功");
}
}];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end
发现,根本不能正常运行好伐???直接报错:
这个文件找不到。
全文搜索下,果真找不到。这是不是略坑?下载下来的代码不全?
再去文件夹中确认一下,果然没有这个文件,哭晕····
3、黑暗中摸索
怎么办?去git上再看文档,看这里:
这里有一个链接,点进去看看:
( https://github.com/Flipboard/FLAnimatedImage)
下载下来文件:
( https://github.com/Flipboard/FLAnimatedImage.git)
这里果然多了两个文件。现在把新文件添加进去。
再次运行,原来的那个地方不报错了。但是,又有了别的错误:
我这里是使用的xcode8,才会报这个错误,这个属性是xcode9才有的,所以使用xcode9 的童鞋可以略过。
代码上来看,应该是适配ios11的,暂时注释掉。
哈哈,发现,不错啊,跑起来了。有么有很开心?
but,webp的图片木有显示啊!
看下sd的api,发现UIImage+WebP.h中有一个方法,
+ (nullable UIImage *)sd_imageWithWebPData:(nullable NSData *)data;
我们是否可以使用它进行加载呢?
-(void)loadImageWebp{
UIImageView * imageV = [[UIImageView alloc] initWithFrame:CGRectMake(10, 50, mScreenWidth-20, 200)];
[self.view addSubview:imageV];
imageV.backgroundColor = [UIColor yellowColor];
NSString * imageurl = @"http://images21.happyjuzi.com/test/ea/09/91f522741b7a0976b5f21a3b9f78.jpg!200.nw.webp";
NSError * error;
NSData * data = [NSData dataWithContentsOfURL:[NSURL URLWithString:imageurl] options:NSDataReadingMappedIfSafe error:&error];
if (data) {
UIImage * image = [UIImage sd_imageWithWebPData:data];
imageV.image = image;
}else{
NSLog(@"惨啦,没有拿到数据");
}
}
写到 UIImage * image = [UIImage sd_imageWithWebPData:data]; 这一句的时候,发现,xcode根本不识别 sd_imageWithWebPData这个方法,它一直报错:
怎么回事?明明导进来了啊,
怎么就是不识别呢??再去源文件中自己查看:
发现了,原来是它在捣鬼啊!
我们切换到 bulid setting,找到如下位置:
添加 SD_WEBP的定义(注意:等于号左右两边没有空格):
再次强调,等于号左右两边没有空格!!!
如果你添加完这个配置之后,运行之后报了23个错误,并且UIImage变成了别的颜色,那么你可以回过来查看是否这里配置的时候多了空格。
再次运行。虽然还是会报错,但是报错的位置改变了。
报错文件:
这次变成了webp/decode,没有这个文件。文件搜索,发现,真的没有这个文件。多方所有答案,发现,这个文件是定义在一个叫做Webp.framework中的。
我们怎么得到这个文件呢?
如果你有fanqiang,那么一切好办。直接用cocoa pods导入即可:
pod 'SDWebImage/WebP'
再啰嗦下,因为这个文件需要用到谷歌的源文件,所以需要fanqiang才能够下载到。
那么我们没有fanqiang怎么办?
我们只是想得到Webp.framework这个文件,只要下载到它就可以了。我想起来,除了SDWebImage之外,还有一个加载图片的第三方 # YYWebImage
(https://github.com/ibireme/YYWeb)
它是可以加载webp图片的,它是怎么实现的呢?下载下来发现惊喜:
它里面也是集成了webp.framework的。我们可以把这个文件拷贝出来,放在我们的项目中:
再次运行,哈哈哈·····运行起来啦!而且,图片也是正常显示的。
现在我们可以使用多种方法加载webp图片,具体就根据我们的需要了。
最常用的:
NSString * imageurl = @"http://images21.happyjuzi.com/test/ea/09/91f522741b7a0976b5f21a3b9f78.jpg!200.nw.webp";
//NSString * imageurl = @"[http://oss.img.2or3m.com/videoimg/php/20171112/5a080c360c6c3.jpg](http://oss.img.2or3m.com/videoimg/php/20171112/5a080c360c6c3.jpg)";
[imageV sd_setImageWithURL:[NSURL URLWithString:imageurl] completed:^(UIImage * _Nullable image, NSError * _Nullable error, SDImageCacheType cacheType, NSURL * _Nullable imageURL) {
if (error) {
NSLog(@"--------- %@",error);
}else{
NSLog(@"图片加载成功");
}
}];
这种是可以的。
还有:
NSData * data = [NSData dataWithContentsOfURL:[NSURL URLWithString:imageurl]];
UIImage * image = [UIImage sd_imageWithWebPData:data];
也是可以的。
你要想知道还有哪些方法,可以自己查看sdwebimage的API,发现适合自己使用的方法。
另:YYWebImage也是支持webp的一个开源框架,据说还不错,没来得及研究呢。
总结:
遇到问题别着急,一点点屡清楚,一个个解决,一定会有解决办法的。
demo地址:
https://github.com/weiman152/TestSDWebImage.git
需要的可以拿去。