激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - IOS - iOS WebView中使用webp格式圖片的方法

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

2021-04-26 18:44月若無涯 IOS

由于最近項目需求,需要將項目中圖片的加載做到同時兼容WebP格式,所以下面這篇文章主要給大家介紹了關于在iOS WebView中使用webp格式圖片的相關資料,文中通過示例代碼介紹的非常詳細,需要的朋友可以參考下

webp格式圖片

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

引言

很早之前,我們的項目中就已經采用了webp格式,但是由于webView本身并不能解析webp格式,所以我們基于webView的文章詳情頁就無法使用到這項優化。 

那么有沒有什么辦法能實現呢?當然是有的。

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

本項目中,圖片緩存使用了SDWebImage,并且開啟了webp支持功能,那么我們對詳情頁webView的處理也會基于此來實現。 

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

  • HTML解析庫的setAttributeNamed不能增加屬性
  • webp服務器圖片下載后的默認緩存時gif不能正常存儲
  • 下載完的圖片不能實時通過js更改src為本地文件地址加載出來

最終的技術實現:

1.對下載回來的html內容進行處理,獲取所有圖片鏈接,并進行webp鏈接處理轉換 

對html內容的解析處理我使用的是Objective-C-HMTL-Parser,但是該庫已經多年不維護,這里有我fork后進行部分優化調整的版本:https://github.com/YueRuo/Objective-C-HMTL-Parser 

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
@try {
 HTMLParser *parser = [[HTMLParser alloc] initWithString:htmlContent error:&error];
 HTMLNode *bodyNode = [parser body];
 if (error) {
 return;
 }
 //得到所有的img標簽
 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)];//根據原圖片,得到webp服務器使用的圖片鏈接,需要有webp處理服務器
 //檢查本地圖片緩存
 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];
 }
 //存儲疑似webp圖片和原圖片,如果newSrc和webp相同則說明本地沒有緩存圖片
 [_webpImageUrlDic setObject:webpImage forKey:newSrc];
 if(localExsit){
  setAttributeNamed(inputNode->_node, "src", [newSrc cStringUsingEncoding:NSUTF8StringEncoding]);
 }else{
  setAttributeNamed(inputNode->_node, "src", "詳情頁占位圖@2x.png");
 }
 //給img標簽中增加一個叫osrc的屬性,便于后續處理
 setAttributeNamed(inputNode->_node, "osrc", [newSrc cStringUsingEncoding:NSUTF8StringEncoding]);
 }
 htmlContent = [NSMutableString stringWithString:parser.doc.rawContents];
}
@catch (NSException *exception) {
}
@finally {
 [webView loadHTMLString:htmlContent baseURL:baseUrl];
}

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

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

另外通過實驗,直接通過js無法實時更新下載到本地的圖片,只好通過圖片的base64encode數據加載方式實現。 

具體代碼如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
- (void)webViewDidFinishLoad:(UIWebView *)web {
 //處理webp格式加載
 [_webpImageUrlDic enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, id _Nonnull obj, BOOL * _Nonnull stop) {
 if([obj isEqualToString:key]){//說明這圖沒有緩存,還需要下載
  [[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的圖片如果直接存儲,會變成jpg從而失去動畫,因此要特殊處理
   [[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.回調webView頁面,用本地鏈接替換原有的圖片

加載已下載好的圖片,這里主要通過js來實現,即第2步中的replaceWebPImg方法,該js方法可通過提前置于html的模板中,或者webViewDidFinishLoad后采用js注入進去

?
1
2
3
4
5
6
7
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;
 }
}

好再次總結一下整個流程:

  • 對服務器返回的htmlContent數據進行相應處理,檢查圖片是否存在緩存,存在則使用本地地址為src,不存在則把圖片的src替換成占位圖。記錄下圖片地址,并增加屬性做好標記。
  • 圖片的地址進行webp轉換,通過客戶端進行下載
  • 下載后的圖片,通過js方法進行src更改,并且賦值的base64的圖片編碼數據,因為給本地地址無法實時展示出來

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

總結

以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對服務器之家的支持。

原文鏈接:https://blog.csdn.net/u010124617/article/details/51545611

延伸 · 閱讀

精彩推薦
  • IOSiOS開發之視圖切換

    iOS開發之視圖切換

    在iOS開發中視圖的切換是很頻繁的,獨立的視圖應用在實際開發過程中并不常見,除非你的應用足夠簡單。在iOS開發中常用的視圖切換有三種,今天我們將...

    執著丶執念5282021-01-16
  • IOSiOS開發技巧之狀態欄字體顏色的設置方法

    iOS開發技巧之狀態欄字體顏色的設置方法

    有時候我們需要根據不同的背景修改狀態欄字體的顏色,下面這篇文章主要給大家介紹了關于iOS開發技巧之狀態欄字體顏色的設置方法,文中通過示例代碼...

    夢想家-mxj8922021-05-10
  • IOSiOS中UILabel實現長按復制功能實例代碼

    iOS中UILabel實現長按復制功能實例代碼

    在iOS開發過程中,有時候會用到UILabel展示的內容,那么就設計到點擊UILabel復制它上面展示的內容的功能,也就是Label長按復制功能,下面這篇文章主要給大...

    devilx12792021-04-02
  • IOSiOS中MD5加密算法的介紹和使用

    iOS中MD5加密算法的介紹和使用

    MD5加密是最常用的加密方法之一,是從一段字符串中通過相應特征生成一段32位的數字字母混合碼。對輸入信息生成唯一的128位散列值(32個字符)。這篇文...

    LYSNote5432021-02-04
  • IOSiOS中滑動控制屏幕亮度和系統音量(附加AVAudioPlayer基本用法和Masonry簡單使用)

    iOS中滑動控制屏幕亮度和系統音量(附加AVAudioPlayer基本用法和

    這篇文章主要介紹了iOS中滑動控制屏幕亮度和系統音量(附加AVAudioPlayer基本用法和Masonry簡單使用)的相關資料,需要的朋友可以參考下...

    CodingFire13652021-02-26
  • IOSiOS實現控制屏幕常亮不變暗的方法示例

    iOS實現控制屏幕常亮不變暗的方法示例

    最近在工作中遇到了要將iOS屏幕保持常亮的需求,所以下面這篇文章主要給大家介紹了關于利用iOS如何實現控制屏幕常亮不變暗的方法,文中給出了詳細的...

    隨風13332021-04-02
  • IOS詳解iOS中多個網絡請求的同步問題總結

    詳解iOS中多個網絡請求的同步問題總結

    這篇文章主要介紹了詳解iOS中多個網絡請求的同步問題總結,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧...

    liang199111312021-03-15
  • IOSiOS自定義UICollectionViewFlowLayout實現圖片瀏覽效果

    iOS自定義UICollectionViewFlowLayout實現圖片瀏覽效果

    這篇文章主要介紹了iOS自定義UICollectionViewFlowLayout實現圖片瀏覽效果的相關資料,需要的朋友可以參考下...

    jiangamh8882021-01-11
主站蜘蛛池模板: 欧美a在线观看 | 免费一级毛片在线播放不收费 | 性看小视频 | 欧美日韩国产中文字幕 | 久久91亚洲精品久久91综合 | 黄在线观看在线播放720p | 欧美日韩中文字幕在线视频 | 免费日韩片 | 精品国产欧美一区二区 | 一级做a爱片性色毛片 | 免费a视频| 久久99国产精品视频 | 久久国产精品99国产 | 99在线热播精品免费 | 成人免费在线播放 | 久久久久久久高清 | 欧美色性 | 一区二区三区欧美精品 | 国产亚洲欧美一区久久久在 | 国产日韩中文字幕 | 美女亚洲综合 | 欧美国产第一页 | 五月天影院,久久综合, | 中文在线观看www | 亚洲人成在线播放网站 | 久久久久久久99 | 免费一级欧美大片视频 | 国产精品久久久乱弄 | 免费一级特黄欧美大片勹久久网 | 国产精品中文在线 | 日本精品中文字幕 | 伊人午夜| 午夜视频免费在线观看 | 激情小说区 | 国产美女白浆 | 精品人成 | 欧美成年视频 | 天堂成人一区二区三区 | 亚洲国产网址 | 国产色视频免费 | 亚洲精品无码不卡在线播放he |