欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

iOS WebView中使用webp格式圖片的方法

 更新時(shí)間:2018年05月14日 11:53:42   作者:月若無(wú)涯  
由于最近項(xiàng)目需求,需要將項(xiàng)目中圖片的加載做到同時(shí)兼容WebP格式,所以下面這篇文章主要給大家介紹了關(guān)于在iOS WebView中使用webp格式圖片的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下

webp格式圖片

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

引言

很早之前,我們的項(xiàng)目中就已經(jīng)采用了webp格式,但是由于webView本身并不能解析webp格式,所以我們基于webView的文章詳情頁(yè)就無(wú)法使用到這項(xiàng)優(yōu)化。 

那么有沒有什么辦法能實(shí)現(xiàn)呢?當(dāng)然是有的。

在開始技術(shù)講解之前需要先說(shuō)明,本文的技術(shù)方案,是基于本項(xiàng)目的情況:文章的正文大部分通過接口直接獲取到,通過在客戶端本地進(jìn)行html正文組裝,最后通過webView的loadHTMLString方法進(jìn)行加載顯示。普通的圖片可以通過轉(zhuǎn)換鏈接得到webp服務(wù)器獲取到相應(yīng)的webp版的圖片。

本項(xiàng)目中,圖片緩存使用了SDWebImage,并且開啟了webp支持功能,那么我們對(duì)詳情頁(yè)webView的處理也會(huì)基于此來(lái)實(shí)現(xiàn)。 

通過思考,方案其實(shí)還是比較明確的,就是替換html中圖片鏈接,通過客戶端下載webp圖片,然后在通過js刷新出頁(yè)面上的下完的圖片,但實(shí)際開發(fā)中也遇到了一些坑,比如:

  • HTML解析庫(kù)的setAttributeNamed不能增加屬性
  • webp服務(wù)器圖片下載后的默認(rèn)緩存時(shí)gif不能正常存儲(chǔ)
  • 下載完的圖片不能實(shí)時(shí)通過js更改src為本地文件地址加載出來(lái)

最終的技術(shù)實(shí)現(xiàn):

1.對(duì)下載回來(lái)的html內(nèi)容進(jìn)行處理,獲取所有圖片鏈接,并進(jìn)行webp鏈接處理轉(zhuǎn)換 

對(duì)html內(nèi)容的解析處理我使用的是Objective-C-HMTL-Parser,但是該庫(kù)已經(jīng)多年不維護(hù),這里有我fork后進(jìn)行部分優(yōu)化調(diào)整的版本:https://github.com/YueRuo/Objective-C-HMTL-Parser (本地下載

處理html圖片核心處理邏輯代碼:

@try {
 HTMLParser *parser = [[HTMLParser alloc] initWithString:htmlContent error:&error];
 HTMLNode *bodyNode = [parser body];
 if (error) {
 return;
 }
 //得到所有的img標(biāo)簽
 NSArray *inputNodes = [bodyNode findChildTags:@"img"];

 for (HTMLNode *inputNode in inputNodes) {
 NSString *imageSrc = [inputNode getAttributeNamed:@"src"];
 if (!imageSrc) {
  continue;
 }
 NSString *newSrc = [[GlobalVariable shareInstance] resizeWebpImageWithUrl:imageSrc size:CGSizeMake((SCREEN_WIDTH - 20) * 2, 0)];//根據(jù)原圖片,得到webp服務(wù)器使用的圖片鏈接,需要有webp處理服務(wù)器
 //檢查本地圖片緩存
 NSString *key = [[SDWebImageManager sharedManager] cacheKeyForURL:[NSURL URLWithString:newSrc]];
 NSString *localPath = [[SDImageCache sharedImageCache] defaultCachePathForKey:key];
 NSString *webpImage = newSrc;
 BOOL localExsit = [[NSFileManager defaultManager] fileExistsAtPath:localPath];
 if (localExsit) {
  newSrc = [NSString stringWithFormat:@"file://%@", localPath];
 }
 //存儲(chǔ)疑似webp圖片和原圖片,如果newSrc和webp相同則說(shuō)明本地沒有緩存圖片
 [_webpImageUrlDic setObject:webpImage forKey:newSrc];
 if(localExsit){
  setAttributeNamed(inputNode->_node, "src", [newSrc cStringUsingEncoding:NSUTF8StringEncoding]);
 }else{
  setAttributeNamed(inputNode->_node, "src", "詳情頁(yè)占位圖@2x.png");
 }
 //給img標(biāo)簽中增加一個(gè)叫osrc的屬性,便于后續(xù)處理
 setAttributeNamed(inputNode->_node, "osrc", [newSrc cStringUsingEncoding:NSUTF8StringEncoding]);
 }
 htmlContent = [NSMutableString stringWithString:parser.doc.rawContents];
}
@catch (NSException *exception) {
}
@finally {
 [webView loadHTMLString:htmlContent baseURL:baseUrl];
}

2.用原生方法下載webp圖片,緩存到本地 

下載之后會(huì)存儲(chǔ)為jpg或png格式,這樣就可以被webView進(jìn)行本地加載,但是需要注意gif的存儲(chǔ)特殊處理。 

另外通過實(shí)驗(yàn),直接通過js無(wú)法實(shí)時(shí)更新下載到本地的圖片,只好通過圖片的base64encode數(shù)據(jù)加載方式實(shí)現(xiàn)。 

具體代碼如下:

- (void)webViewDidFinishLoad:(UIWebView *)web {
 //處理webp格式加載
 [_webpImageUrlDic enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, id _Nonnull obj, BOOL * _Nonnull stop) {
 if([obj isEqualToString:key]){//說(shuō)明這圖沒有緩存,還需要下載
  [[SDWebImageDownloader sharedDownloader] downloadImageWithURL:[NSURL URLWithString:obj] options:0 progress:nil completed:^(UIImage *image, NSData *data, NSError *error, BOOL finished) {
  if (image&&finished) {
   NSString *js;
   NSRange range = [[obj lowercaseString] rangeOfString:@".gif"];//檢查是否是gif
   BOOL isGif = (range.location != NSNotFound);
   if (!isGif) {
   [[SDImageCache sharedImageCache] storeImage:image forKey:obj];
   NSString *base64 = [UIImageJPEGRepresentation(image,1) base64EncodedStringWithOptions:0];
   js = [NSString stringWithFormat:@"replaceWebPImg('%@','data:image/jpeg;base64,%@')",key,base64];
   }else{//gif的圖片如果直接存儲(chǔ),會(huì)變成jpg從而失去動(dòng)畫,因此要特殊處理
   [[SDImageCache sharedImageCache] storeImage:image recalculateFromImage:false imageData:data forKey:key toDisk:true];
   NSString *base64 = [data base64EncodedStringWithOptions:0];
   js = [NSString stringWithFormat:@"replaceWebPImg('%@','data:image/gif;base64,%@')",key,base64];
   }
   [NSThread excuteInMainThread:^{
   [webView stringByEvaluatingJavaScriptFromString:js];
   } async:false];
  }
  }];
 } else {//緩存中存在,那么直接加載吧
  NSString *js;
  NSRange range = [[obj lowercaseString] rangeOfString:@".gif"];//檢查是否是gif
  NSData* data = [NSData dataWithContentsOfFile:[key stringByReplacingOccurrencesOfString:@"file://" withString:@""]];
  NSString *base64 = [data base64EncodedStringWithOptions:0];
  BOOL isGif = (range.location != NSNotFound);
  if (!isGif) {
  js = [NSString stringWithFormat:@"replaceWebPImg('%@','data:image/jpeg;base64,%@')",obj,base64];
  }else{
  js = [NSString stringWithFormat:@"replaceWebPImg('%@','data:image/gif;base64,%@')",obj,base64];
  }
  [NSThread excuteInMainThread:^{
  [webView stringByEvaluatingJavaScriptFromString:js];
  } async:false];
 }
 }];
} 

3.回調(diào)webView頁(yè)面,用本地鏈接替換原有的圖片 

加載已下載好的圖片,這里主要通過js來(lái)實(shí)現(xiàn),即第2步中的replaceWebPImg方法,該js方法可通過提前置于html的模板中,或者webViewDidFinishLoad后采用js注入進(jìn)去

replaceWebPImg = function(src, localPath) {
 var imgs = document.querySelectorAll('img[osrc="'+src+'"]'),len = imgs.length;;
 for (var i = 0; i < len; i++) {
 var img = imgs[i];
 img.src = localPath;
 }
}

好再次總結(jié)一下整個(gè)流程:

  • 對(duì)服務(wù)器返回的htmlContent數(shù)據(jù)進(jìn)行相應(yīng)處理,檢查圖片是否存在緩存,存在則使用本地地址為src,不存在則把圖片的src替換成占位圖。記錄下圖片地址,并增加屬性做好標(biāo)記。
  • 圖片的地址進(jìn)行webp轉(zhuǎn)換,通過客戶端進(jìn)行下載
  • 下載后的圖片,通過js方法進(jìn)行src更改,并且賦值的base64的圖片編碼數(shù)據(jù),因?yàn)榻o本地地址無(wú)法實(shí)時(shí)展示出來(lái)

這篇寫的比較簡(jiǎn)單,更詳細(xì)的步驟請(qǐng)查閱上面的代碼,里面我加上還算詳細(xì)的注釋,希望對(duì)想要在webView中使用webp圖片的大家有所幫助。

總結(jié)

以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,如果有疑問大家可以留言交流,謝謝大家對(duì)腳本之家的支持。

相關(guān)文章

  • iOS中指紋識(shí)別常見問題匯總

    iOS中指紋識(shí)別常見問題匯總

    最近在公司做了一個(gè)app要使用指紋支付的功能,在實(shí)現(xiàn)過程中遇到各種坑,今天小編抽抗給大家總結(jié)把遇到問題匯總特此分享到腳本之家平臺(tái),需要的朋友參考下
    2016-12-12
  • IOS開發(fā)第三方語(yǔ)音-微信語(yǔ)音

    IOS開發(fā)第三方語(yǔ)音-微信語(yǔ)音

    微信語(yǔ)音開放平臺(tái)致力于為開發(fā)者提供免費(fèi)的語(yǔ)音技術(shù),目前已經(jīng)開放的語(yǔ)音技術(shù)包括在線語(yǔ)音識(shí)別、在線語(yǔ)音合成等,下面通過本篇文章給大家介紹IOS開發(fā)第三方語(yǔ)言-微信語(yǔ)言,需要的朋友可以一起來(lái)學(xué)習(xí)下
    2015-08-08
  • 詳解iOS - ASIHTTPRequest 網(wǎng)絡(luò)請(qǐng)求

    詳解iOS - ASIHTTPRequest 網(wǎng)絡(luò)請(qǐng)求

    本篇文章主要介紹了iOS - ASIHTTPRequest 網(wǎng)絡(luò)請(qǐng)求 ,詳細(xì)的介紹了 ASIHTTPRequest的使用,具有一定的參考價(jià)值,有興趣的可以了解一下。
    2016-12-12
  • iOS中Xcode 8 日志輸出亂碼問題的解決方法

    iOS中Xcode 8 日志輸出亂碼問題的解決方法

    這篇文章主要介紹了iOS中Xcode 8日志輸出亂碼問題及解決方法,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下
    2016-09-09
  • ios使用OC寫算法之遞歸實(shí)現(xiàn)八皇后

    ios使用OC寫算法之遞歸實(shí)現(xiàn)八皇后

    本篇文章主要介紹了ios使用OC寫算法之遞歸實(shí)現(xiàn)八皇后,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來(lái)看看吧
    2017-08-08
  • iOS使用WKWebView加載HTML5不顯示屏幕寬度的問題解決

    iOS使用WKWebView加載HTML5不顯示屏幕寬度的問題解決

    這篇文章主要介紹了iOS使用WKWebView加載HTML5不顯示屏幕寬度的問題解決,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來(lái)看看吧
    2018-12-12
  • iOS實(shí)現(xiàn)抽屜效果

    iOS實(shí)現(xiàn)抽屜效果

    這篇文章主要為大家詳細(xì)介紹了iOS實(shí)現(xiàn)抽屜效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-02-02
  • iOS 修改alertViewController彈框的字體顏色及字體的方法

    iOS 修改alertViewController彈框的字體顏色及字體的方法

    下面小編就為大家分享一篇iOS 修改alertViewController彈框的字體顏色及字體的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來(lái)看看吧
    2018-01-01
  • iOS的UI開發(fā)中UITabBarControlle的基本使用教程

    iOS的UI開發(fā)中UITabBarControlle的基本使用教程

    這篇文章主要介紹了iOS的UI開發(fā)中UITabBarControlle的基本使用教程,代碼基于傳統(tǒng)的Objective-C,需要的朋友可以參考下
    2015-12-12
  • Swift Self詳解及簡(jiǎn)單實(shí)例代碼

    Swift Self詳解及簡(jiǎn)單實(shí)例代碼

    這篇文章主要介紹了Swift Self詳解及簡(jiǎn)單實(shí)例代碼的相關(guān)資料,這里對(duì)self 進(jìn)行了詳細(xì)介紹并附實(shí)例代碼,需要的朋友可以參考下
    2016-12-12

最新評(píng)論