你好,歡迎來到IOS教程網

 Ios教程網 >> IOS編程開發 >> IOS開發基礎 >> iOS 全面支持 webp格式圖片

iOS 全面支持 webp格式圖片

編輯:IOS開發基礎

iOS 全面支持 webp格式圖片 Custom URLProtocol

webp格式圖片

webp格式圖片是google推出的,相比jpg png有著巨大的優勢,同樣質量的圖片webp格式的圖片占用空間更小,在像電商這樣圖片比較多的App中,使用webp格式圖片會很有優勢。

webp在iOS設備上

當前的iOS不支持webp,不知道以後會不會支持,所以從網絡上拿到一個webp格式的圖片後,並不能直接顯示出來,需要把data數據轉化為jpg或者png來顯示。

支持webp的方案

使用SDWebImage中帶的WebP

在podfile中加入

pod 'SDWebImage/WebP'

可以在SDWebImage中加入UIImage的WebP類別,同時會引入libwebp。在使用SD加載圖片時,會判定圖片的格式,如果為webp,調用Google的libwebp庫進行解析。
調用過程如下:

sd_setImageWithURL -> 
URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error ->
sd_imageWithData->
sd_imageWithWebPData
處理成功後會返回一個UIImage。

在WebView中使用Webp格式圖片

如果有一些web頁中使用了webp格式的圖片,僅用上述方法是不行的,我推薦的做法是寫一個自定義的URLSession protocol, 繼承自NSURLProtocol, 然後注冊。自定義的協議文件為DMCustomURLSessionProtocol這個類,整個工程的地址如下:Demo地址.
關鍵代碼如下:

- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(nullable NSError *)error
{
   if (error == nil) 
   {
        if ([task.currentRequest.URL.absoluteString hasSuffix:@"webp"]) 
        {
            NSLog(@"webp will changed:%@",task.currentRequest.URL);
            UIImage *imgData = [UIImage sd_imageWithData:self.imageData];
            NSData *transData = UIImageJPEGRepresentation(imgData, 0.8f);
            self.beginAppendData = NO;
            self.imageData = nil;
            [self.client URLProtocol:self didLoadData:transData];
        }
        [self.client URLProtocolDidFinishLoading:self];
    } 
    else if ( [[error domain] isEqual:NSURLErrorDomain] && ([error code] == NSURLErrorCancelled) ) 
    {
        [self.client URLProtocol:self didFailWithError:error];
    }
    else
    {
        [[self client] URLProtocol:self didFailWithError:error];
    }
}

在一個task完成的時候,根據task中的url是否含有webp後綴,做處理,如果有webp後綴,用SD轉化圖片,轉化完成後, 需要把beginAppendData置為NO,imageData置為nil,self.client再load一次data。

- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data
{
    if ([dataTask.currentRequest.URL.absoluteString hasSuffix:@"webp"]) 
    {
        self.beginAppendData = YES;
        [self.imageData appendData:data];
    }
    if (!_beginAppendData) 
    {
        [self.client URLProtocol:self didLoadData:data];
    }
}

在didReceiveData裡面要做一些處理,這裡面是每次receive一塊新的data,當一個請求的地址裡面含有webp時,把beginAppendData置為yes,同時imgeData開始append data,而這時self.client不load data,每次有新data來,imageData就append上,止到這一個請求完成, 在完成的裡面 轉化webp後 load data。(請求一個圖片後,可能在did receive data中收到多次才能收全。)

處理重定向

自定義URL Protocol時,一定要實現重定向的代理方法,不然,在webview裡面會出問題。

- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task willPerformHTTPRedirection:(NSHTTPURLResponse *)response newRequest:(NSURLRequest *)newRequest completionHandler:(void (^)(NSURLRequest *))completionHandler
{
    NSMutableURLRequest *    redirectRequest;

    redirectRequest = [newRequest mutableCopy];
    [[self class] removePropertyForKey:URLProtocolHandledKey inRequest:redirectRequest];

    [[self client] URLProtocol:self wasRedirectedToRequest:redirectRequest redirectResponse:response];

    [self.session invalidateAndCancel];
    [[self client] URLProtocol:self didFailWithError:[NSError errorWithDomain:NSCocoaErrorDomain code:NSUserCancelledError userInfo:nil]];
}

最後在appdelegate didFinishLaunchingWithOptions中注冊上

[NSURLProtocol registerClass:[DMCustomURLSessionProtocol class]];

再發一下地址

  • 工程地址

  • webp格式圖片地址

  • 含有webp的網頁地址

  1. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved