iOS 支持webp格式图片
2018-11-07 本文已影响0人
CoderLGL
在iOS项目中使用WebP
SDWebImage
中支持WebP
格式的,可以完成UIImage -> Webp
和WebP -> UIImage
的转换。直接通过CocoaPods
的Podfile
文件中加入pod 'SDWebImage/WebP'
即可。
可能会遇到libwebp v0.6.0 超时问题:iOS使用cocoapods 安装 libwebp0.6.0 遇到Error installing libwebp
SDWebImage/WebP
提供了UIImage+WebP
的Category
里面有个将WebP NSData
的数据转换为UIImage
的方法:
+ (UIImage *)sd_imageWithWebPData:(NSData *)data;
1. 在Native中使用WebP格式图片
NSString *path = [[NSBundle mainBundle] pathForResource:@"logo" ofType:@"webp"];
NSData *data = [[NSData alloc] initWithContentsOfFile:path];
UIImage *img = [UIImage sd_imageWithWebPData:data];
self.imageView.image = img;
2. 在UIWebView中使用WebP格式图片
具体实现是通过NSURLProtocol拦截WebView的网络请求,筛选出请求Webp图片的网络请求,下载完Webp图片后使用谷歌的WebP解析库解析图片,转换成Jpg格式图片,传给网页。
.h
#import <Foundation/Foundation.h>
@interface TTWebPURLProtocol : NSURLProtocol
@end
.m
#import "TTWebPURLProtocol.h"
#import "UIImage+MultiFormat.h"
static NSString *const TTWebPProtocolHandledKey = @"TTWebPProtocolHandledKey";
@interface TTWebPURLProtocol ()<NSURLSessionTaskDelegate, NSURLSessionDataDelegate>
@property (nonatomic, strong) NSURLSession *session;
@property (nonatomic, strong) NSURLSessionDataTask *sessionTask;
@property (nonatomic, strong) NSMutableData *imgData;
@end
@implementation TTWebPURLProtocol
+ (BOOL)canInitWithRequest:(NSURLRequest *)request
{
if ([NSURLProtocol propertyForKey:TTWebPProtocolHandledKey inRequest:request]) {
return NO;
}
NSURL *url = [request URL];
NSString *userAgent = [request allHTTPHeaderFields][@"User-Agent"];
if (![[userAgent lowercaseString] containsString:@"applewebkit"]) {
return NO;
}
NSString* const requestFiletype = [[url pathExtension] lowercaseString];
NSLog(@"---------------%@",url);
return [@"webp" isEqualToString:requestFiletype];
}
+ (NSURLRequest *)canonicalRequestForRequest:(NSURLRequest *)request
{
return request;
}
- (void)startLoading
{
NSMutableURLRequest *mutableReqeust = [[self request] mutableCopy];
[NSURLProtocol setProperty:@YES forKey:TTWebPProtocolHandledKey inRequest:mutableReqeust];
self.sessionTask = [self.session dataTaskWithRequest:self.request];
[self.sessionTask resume];
}
- (void)stopLoading
{
[self.sessionTask cancel];
self.sessionTask = nil;
}
#pragma mark -- NSURLSessionTaskDelegate
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask
didReceiveResponse:(NSURLResponse *)response
completionHandler:(void (^)(NSURLSessionResponseDisposition disposition))completionHandler
{
self.imgData = [[NSMutableData alloc] init];
[self.client URLProtocol:self didReceiveResponse:response cacheStoragePolicy:NSURLCacheStorageNotAllowed];
if (completionHandler) {
completionHandler(NSURLSessionResponseAllow);
}
}
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask
didReceiveData:(NSData *)data
{
[self.imgData appendData:data];
}
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task
didCompleteWithError:(nullable NSError *)error
{
if (error) {
[self.client URLProtocol:self didFailWithError:error];
return;
}
UIImage *webpImg = [UIImage sd_imageWithData:self.imgData];
NSData *imgData = UIImageJPEGRepresentation(webpImg, 1);
[self.client URLProtocol:self didLoadData:imgData];
[self.client URLProtocolDidFinishLoading:self];
}
#pragma mark -- Setter && Getter
- (NSURLSession *)session
{
if (!_session) {
NSURLSessionConfiguration *sessonConfig = [NSURLSessionConfiguration defaultSessionConfiguration];
_session = [NSURLSession sessionWithConfiguration:sessonConfig delegate:self delegateQueue:nil];
}
return _session;
}
最后:
使用TTWebPURLProtocol
前需要注册,推荐在APPDelegate
中的- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(nullable NSDictionary *)launchOptions;
的方法中加入如下代码:
[NSURLProtocol registerClass:[TTWebPURLProtocol class]];
提示: 图片链接必须是以
.webp
结尾.