在iOS项目中使用WebP格式图片

WebP是什么?

WebP(发音 weppy,来自:Google WebP),是一种支持有损压缩和无损压缩的图片文件格式,派生自图像编码格式 VP8。根据 Google 的测试,无损压缩后的 WebP 比 PNG 文件少了 45% 的文件大小,即使这些 PNG 文件经过其他压缩工具压缩之后,WebP 还是可以减少 28% 的文件大小。在 Google 的明星产品如 Youtube、Gmail、Google Play 中都可以看到 WebP 的身影,而 Chrome 网上商店甚至已完全使用了 WebP。国外公司如 Facebook、ebay 和国内公司如腾讯、淘宝、美团等也早已尝鲜。下面是QQ图片格式对比图

Snip20170803_18.png

iOS中如何使用WebP格式图片?

很幸运,SDWebImage支持WebP格式图片,可以讲WebP数据–>NSData–>UIImage

There are 3 subspecs available now: Core, MapKit and WebP (this means you can install only some of the SDWebImage modules. By default, you get just Core, so if you need WebP, you need to specify it).Podfile example:$pod ‘SDWebImage/WebP’
摘自SDWebImage

PS:下载WebP这个库,由于是从Google下载的,如果下载失败,请翻墙重试!!!
如果你是手动添加WebP这个库,Xcode 需要如下配置 targets->build settings ->preprocessor Macros 填写 SD_WEBP=1 如图


Snip20170802_19.png

到此app 中支持 WebP图片基本完成,但是重点来了,由于部分app使用到了UIWebview/WKWebview 这两个控件是不支持WebP图片的,目前有两种方式可以让其支持WebP格式图片。

实现方式一 NSURLProtocol

对于NSURLProtocol的作用及使用以后找个时间再讲了~~~~可以参考Apple 开发者文档NSURLProtocol, UIWebView 直接就可以支持,但是WKWebView是不支持的,如何让WKWebView也支持NSURLProtocol?不过WKWebView自定义NSURLProtocol会丢失boay数据。文章结尾会附上Demo下载地址。

WKWebView 拓展支持NSURLProtocol 具体代码如下

 FOUNDATION_STATIC_INLINE Class 
 ContextControllerClass() {
    static Class cls;
    if (!cls) {
        cls = [[[WKWebView new] valueForKey:@"browsingContextController"] class];
    }
    return cls;
}
FOUNDATION_STATIC_INLINE SEL RegisterSchemeSelector() {
    return NSSelectorFromString(@"registerSchemeForCustomProtocol:");
}
FOUNDATION_STATIC_INLINE SEL UnregisterSchemeSelector() {
    return NSSelectorFromString(@"unregisterSchemeForCustomProtocol:");
}
@implementation NSURLProtocol (WebKitExt)
+ (void)wk_registerScheme:(NSString *)scheme {
    Class cls = ContextControllerClass();
    SEL sel = RegisterSchemeSelector();
    if ([(id)cls respondsToSelector:sel]) {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
        [(id)cls performSelector:sel withObject:scheme];
#pragma clang diagnostic pop
    }
}
+ (void)wk_unregisterScheme:(NSString *)scheme {
    Class cls = ContextControllerClass();
    SEL sel = UnregisterSchemeSelector();
    if ([(id)cls respondsToSelector:sel]) {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
        [(id)cls performSelector:sel withObject:scheme];
#pragma clang diagnostic pop
    }
}

好了,现在UIWebView与WKWebView 都已经支持自定义NSURLProtocol了;
我们创建一个类CLURLProtocol 继承自NSURLProtocol
下面这几个方法必须实现

+(BOOL)canInitWithRequest:(NSURLRequest )request;
+(NSURLRequest )canonicalRequestForRequest:(NSURLRequest *)request;
-(void)stopLoading;
-(void)startLoading;

到此为止UIWebView/WKWebView 均已支持加载webp格式图片

优点:

适合所有网页,可以不用修改网页内部html内容。

缺点:

NSURLProtocol 拦截App 的所有请求, 使用时需要根据个人项目情况而定, WKWebView 在post请求时会丢失boay, 目前解决方式为在WKWebView的 开始加载的 代理方法判断是否为post,为post解除注册自定义的NSURLProtocol,为GET请求时注册自定义NSURLProtocol。

最后

本文Demo:【BAWKWebView-WebP
如有更多需求,请前往:【https://github.com/BAHome】

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容