日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術文章
文章詳情頁

iOS 下的圖片處理與性能優化詳解

瀏覽:107日期:2022-09-16 16:33:43
圖片在計算機世界中怎樣被存儲和表示?

圖片和其他所有資源一樣,在內存中本質上都是0和1的二進制數據,計算機需要將這些原始內容渲染成人眼能觀察的圖片,反過來,也需要將圖片以合適的形式保存在存儲器或者在網絡上傳送。

這種將圖片以某種規則進行二進制編碼的方式,就是圖片的格式。

常見的圖片格式

圖片的格式有很多種,除了我們熟知的 JPG、PNG、GIF,還有Webp,BMP,TIFF,CDR 等等幾十種,用于不同的場景或平臺。

這些格式可以分為兩大類:有損壓縮和無損壓縮。

有損壓縮:相較于顏色,人眼對光線亮度信息更為敏感,基于此,通過合并圖片中的顏色信息,保留亮度信息,可以在盡量不影響圖片觀感的前提下減少存儲體積。顧名思義,這樣壓縮后的圖片將會永久損失一些細節。最典型的有損壓縮格式是 jpg。

無損壓縮:和有損壓縮不同,無損壓縮不會損失圖片細節。它降低圖片體積的方式是通過索引,對圖片中不同的顏色特征建立索引表,減少了重復的顏色數據,從而達到壓縮的效果。常見的無損壓縮格式是 png,gif。

除了上述提到的格式,有必要再簡單介紹下 webp 和 bitmap這兩種格式:

Webp:jpg 作為主流的網絡圖片標準可以向上追溯到九十年代初期,已經十分古老了。所以谷歌公司推出了Webp標準意圖替代陳舊的jpg,以加快網絡圖片的加載速度,提高圖片壓縮質量。

webp 同時支持有損和無損兩種壓縮方式,壓縮率也很高,無損壓縮后的 webp 比 png 少了45%的體積,相同質量的 webp 和 jpg,前者也能節省一半的流量。同時 webp 還支持動圖,可謂圖片壓縮格式的集大成者。

webp 的缺點是瀏覽器和移動端支持還不是很完善,我們需要引入谷歌的 libwebp 框架,編解碼也會消耗相對更多的資源。

bitmap:bitmap 又叫位圖文件,它是一種*非壓縮*的圖片格式,所以體積非常大。所謂的非壓縮,就是圖片每個像素的原始信息在存儲器中依次排列,一張典型的1920*1080像素的 bitmap 圖片,每個像素由 RGBA 四個字節表示顏色,那么它的體積就是 1920 * 1080 * 4 = 1012.5kb。

由于 bitmap 簡單順序存儲圖片的像素信息,它可以不經過解碼就直接被渲染到 UI 上。實際上,其它格式的圖片一般都需要先被首先解碼為 bitmap,然后才能渲染到界面上。

如何判斷圖片的格式?

在一些場景中,我們需要手動去判斷圖片數據的格式,以進行不同的處理。一般來說,只要拿到原始的二進制數據,根據不同壓縮格式的編碼特征,就可以進行簡單的分類了。以下是一些圖片框架的常用實現,可以復制使用:

+ (XRImageFormat)imageFormatForImageData:(nullable NSData *)data { if (!data) {return XRImageFormatUndefined; }uint8_t c; [data getBytes:&c length:1]; switch (c) {case 0xFF: return XRImageFormatJPEG;case 0x89: return XRImageFormatPNG;case 0x47: return XRImageFormatGIF;case 0x49:case 0x4D: return XRImageFormatTIFF;case 0x52: if (data.length < 12) {return XRImageFormatUndefined; }NSString *testString = [[NSString alloc] initWithData:[data subdataWithRange:NSMakeRange(0, 12)] encoding:NSASCIIStringEncoding]; if ([testString hasPrefix:@'RIFF'] && [testString hasSuffix:@'WEBP']) {return XRImageFormatWebP; } } return XRImageFormatUndefined;}UIImageView 的性能瓶頸

如上文所說,大部分格式的圖片,都需要被首先解碼為bitmap,然后才能渲染到UI上。

UIImageView 顯示圖片,也有類似的過程。實際上,一張圖片從在文件系統中,到被顯示到 UIImageView,會經歷以下幾個步驟:

分配內存緩沖區和其它資源。 從磁盤拷貝數據到內核緩沖區 從內核緩沖區復制數據到用戶空間 生成UIImageView,把圖像數據賦值給UIImageView 將壓縮的圖片數據,解碼為位圖數據(bitmap),如果數據沒有字節對齊,Core Animation會再拷貝一份數據,進行字節對齊。 CATransaction捕獲到UIImageView layer樹的變化,主線程Runloop提交CATransaction,開始進行圖像渲染 GPU處理位圖數據,進行渲染。

由于 UIKit 的封裝性,這些細節不會直接對開發者展示。實際上,當我們調用[UIImage imageNamed:@'xxx']后,UIImage 中存儲的是未解碼的圖片,而調用 [UIImageView setImage:image]后,會在主線程進行圖片的解碼工作并且將圖片顯示到 UI 上,這時候,UIImage 中存儲的是解碼后的 bitmap 數據。

而圖片的解壓縮是一個非常消耗 CPU 資源的工作,如果我們有大量的圖片需要展示到列表中,將會大大拖慢系統的響應速度,降低運行幀率。這就是 UIImageView 的一個性能瓶頸。

解決性能瓶頸:強制解碼

如果 UIImage 中存儲的是已經解碼后的數據,速度就會快很多,所以優化的思路就是:在子線程中對圖片原始數據進行強制解碼,再將解碼后的圖片拋回主線程繼續使用,從而提高主線程的響應速度。

我們需要使用的工具是 Core Graphics 框架的 CGBitmapContextCreate 方法和相關的繪制函數。總體的步驟是:

A. 創建一個指定大小和格式的 bitmap context。

B. 將未解碼圖片寫入到這個 context 中,這個過程包含了*強制解碼*。

C. 從這個 context 中創建新的 UIImage 對象,返回。

下面是 SDWebImage 實現的核心代碼,編號對應的解析在下文中:

// 1.CGImageRef imageRef = image.CGImage;// 2.CGColorSpaceRef colorspaceRef = [UIImage colorSpaceForImageRef:imageRef];size_t width = CGImageGetWidth(imageRef);size_t height = CGImageGetHeight(imageRef);// 3.size_t bytesPerRow = 4 * width;// 4.CGContextRef context = CGBitmapContextCreate(NULL, width, height, kBitsPerComponent, bytesPerRow, colorspaceRef, kCGBitmapByteOrderDefault|kCGImageAlphaNoneSkipLast);if (context == NULL) { return image;}// 5.CGContextDrawImage(context, CGRectMake(0, 0, width, height), imageRef);// 6.CGImageRef newImageRef = CGBitmapContextCreateImage(context);// 7.UIImage *newImage = [UIImage imageWithCGImage:newImageRefscale:image.scale orientation:image.imageOrientation];CGContextRelease(context);CGImageRelease(newImageRef);return newImage;

對上述代碼的解析:

1、從 UIImage 對象中獲取 CGImageRef 的引用。這兩個結構是蘋果在不同層級上對圖片的表示方式,UIImage 屬于 UIKit,是 UI 層級圖片的抽象,用于圖片的展示;CGImageRef 是 QuartzCore 中的一個結構體指針,用C語言編寫,用來創建像素位圖,可以通過操作存儲的像素位來編輯圖片。這兩種結構可以方便的互轉:

// CGImageRef 轉換成 UIImageCGImageRef imageRef = CGBitmapContextCreateImage(context);UIImage *image = [UIImage imageWithCGImage:imageRef]; // UIImage 轉換成 CGImageRefUIImage *image=[UIImage imageNamed:@'xxx'];CGImageRef imageRef=loadImage.CGImage;

2、調用 UIImage 的 +colorSpaceForImageRef: 方法來獲取原始圖片的顏色空間參數。

什么叫顏色空間呢,就是對相同顏色數值的解釋方式,比如說一個像素的數據是(FF0000FF),在 RGBA 顏色空間中,會被解釋為紅色,而在 BGRA 顏色空間中,則會被解釋為藍色。所以我們需要提取出這個參數,保證解碼前后的圖片顏色空間一致。

3、計算圖片解碼后每行需要的比特數,由兩個參數相乘得到:每行的像素數 width,和存儲一個像素需要的比特數4。

這里的4,其實是由每張圖片的像素格式和像素組合來決定的,下表是蘋果平臺支持的像素組合方式。

我們解碼后的圖片,默認采用 kCGImageAlphaNoneSkipLast RGB 的像素組合,沒有 alpha 通道,每個像素32位4個字節,前三個字節代表紅綠藍三個通道,最后一個字節廢棄不被解釋。

4、最關鍵的函數:調用 CGBitmapContextCreate() 方法,生成一個空白的圖片繪制上下文,我們傳入了上述的一些參數,指定了圖片的大小、顏色空間、像素排列等等屬性。

5、調用 CGContextDrawImage() 方法,將未解碼的 imageRef 指針內容,寫入到我們創建的上下文中,這個步驟,完成了隱式的解碼工作。

6、從 context 上下文中創建一個新的 imageRef,這是解碼后的圖片了。

7、從 imageRef 生成供UI層使用的 UIImage 對象,同時指定圖片的 scale 和orientation 兩個參數。

scale 指的是圖片被渲染時需要被壓縮的倍數,為什么會存在這個參數呢,因為蘋果為了節省安裝包體積,允許開發者為同一張圖片上傳不同分辨率的版本,也就是我們熟悉的@2x,@3x后綴圖片。不同屏幕素質的設備,會獲取到對應的資源。為了繪制圖片時統一,這些圖片會被set自己的scale屬性,比如@2x圖片,scale 值就是2,雖然和1x圖片的繪制寬高一樣,但是實際的長是width * scale。

orientation 很好理解,就是圖片的旋轉屬性,告訴設備,以哪個方向作為圖片的默認方向來渲染。

通過以上的步驟,我們成功在子線程中對圖片進行了強制轉碼,回調給主線程使用,從而大大提高了圖片的渲染效率。這也是現在主流 App 和大量三方庫的最佳實踐。

總結

總結一下本文內容:

圖片在計算機世界中被按照不同的封裝格式進行壓縮,以便存儲和傳輸。 手機會在主線程中將壓縮的圖片解壓為可以進行渲染的位圖格式,這個過程會消耗大量資源,影響App性能。 我們使用 Core Graphics 的繪制方法,強制在子線程中先對 UIImage 進行轉碼工作,減少主線程的負擔,從而提升App的響應速度。

和 UIImageView 類似,UIKit 隱藏了很多技術細節,降低開發者的學習門檻,但另一方面,卻也限制了我們對一些底層技術的探究。文中提到的強制解碼方法,其實也是CGBitmapContextCreate 方法的一個『副作用』,屬于比較hack方式,這也是iOS平臺的一個局限:蘋果過于封閉了。

用戶對軟件性能(幀率、響應速度、閃退率等等)其實非常敏感,作為開發者,必須不斷探究性能瓶頸背后的原理,并且嘗試解決,移動端開發的性能優化永無止境。

以上就是iOS 下的圖片處理與性能優化詳解的詳細內容,更多關于ios 圖片處理與性能優化的資料請關注好吧啦網其它相關文章!

標簽: IOS
相關文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
国产美女精品视频免费播放软件| 欧美日韩99| 激情综合自拍| 午夜国产欧美理论在线播放| 在线综合亚洲| 日本午夜精品视频在线观看| 久久97久久97精品免视看秋霞| 激情亚洲影院在线观看| 狠狠久久婷婷| 欧美亚洲自偷自偷| 久久男人av资源站| 国产亚洲亚洲| 国产美女亚洲精品7777| 日韩理论片av| а√在线中文在线新版| 麻豆91精品视频| 国产一区二区三区四区二区| 国产成人精品一区二区三区在线| 国产福利电影在线播放| 99tv成人| 石原莉奈一区二区三区在线观看| 亚洲三级国产| 欧美一区影院| 精品视频黄色| 成人精品亚洲| 午夜在线一区二区| 日韩高清欧美激情| 精品国产中文字幕第一页| 免费污视频在线一区| 日韩视频一区| 亚洲天堂免费| 国产精品久久久久av蜜臀| 亚洲最新av| 久久激五月天综合精品| 激情综合网五月| 久久99性xxx老妇胖精品| 日韩不卡免费高清视频| 亚洲精品系列| 在线一区视频观看| 国产欧美啪啪| 中文亚洲免费| 久久电影tv| 97久久中文字幕| 婷婷色综合网| 精品少妇av| 免费一级片91| 亚洲精品一级二级| 国产精品久久久久久久久久齐齐| 伊人久久婷婷| 成人在线视频免费看| 深夜日韩欧美| 亚洲天堂黄色| 国产91在线播放精品| 日韩高清成人在线| 欧美精品一卡| 日韩一区电影| 国产日韩欧美三级| 免费人成精品欧美精品| 国产99久久久国产精品成人免费| 欧美黑人做爰爽爽爽| 亚洲欧美网站| 久久精品导航| 91中文字幕精品永久在线| 亚洲欧美一区在线| www.com.cn成人| 久久亚洲国产精品尤物| 欧美在线看片| 亚洲精品乱码久久久久久蜜桃麻豆 | 狠狠久久伊人中文字幕| 日韩美女精品| 视频在线观看一区| 欧美在线网站| 高清不卡亚洲| 91综合视频| 成人午夜网址| 国际精品欧美精品| 国产精品对白| 国产毛片精品| 国产探花一区| 久久激五月天综合精品| 欧美偷窥清纯综合图区| 日本成人中文字幕| 亚洲人成精品久久久| 99国产精品| 女同性一区二区三区人了人一| 色天使综合视频| 欧美天堂视频| 捆绑调教日本一区二区三区| 国产成人黄色| 色婷婷色综合| а√天堂8资源中文在线| 国产精品久久久久蜜臀| 成人高清一区| 成人一区而且| 亚洲国产福利| 精品亚洲美女网站| 国产一区视频在线观看免费| 美女网站一区| 日韩视频在线一区二区三区| 国产一区导航| 亚洲欧美久久久| 视频在线观看国产精品| 视频一区二区中文字幕| 首页国产欧美久久| 亚洲深深色噜噜狠狠爱网站| 亚州欧美在线| 91九色综合| 麻豆精品视频在线| 国产在线一区不卡| 蜜桃精品在线| 不卡一区综合视频| 每日更新成人在线视频| 综合激情五月婷婷| 日韩精品亚洲专区在线观看| 国产欧美亚洲精品a| 国产精品欧美在线观看| 鲁大师精品99久久久| 成人在线免费观看网站| 成人看片网站| 性欧美长视频| 欧美一区影院| 欧美激情另类| 欧美91福利在线观看| 香蕉久久夜色精品国产| 欧美日韩中出| 国模大尺度视频一区二区| 久久精品卡一| 蜜臀va亚洲va欧美va天堂| 日韩不卡免费视频| 久久精品国产久精国产爱| 日韩国产一区二区三区| 亚洲精品888| 日韩欧美四区| 久久久久亚洲精品中文字幕| 999国产精品永久免费视频app| aa国产精品| 国产日韩视频| 99视频精品视频高清免费| 99香蕉国产精品偷在线观看 | 亚洲综合色婷婷在线观看| 国产精品丝袜在线播放| 日韩成人a**站| 妖精视频成人观看www| 91午夜精品| 日韩成人亚洲| 亚洲+小说+欧美+激情+另类| 久草免费在线视频| 中文无码日韩欧| 精品视频自拍| 一区免费在线| 国产精品2023| 欧美日韩三区| 国产精品对白| 红桃视频亚洲| 精品国产不卡| 国产偷自视频区视频一区二区| 午夜久久99| 国产亚洲一区二区手机在线观看| 99国产精品| 欧美天堂一区二区| 欧美aa在线观看| 日韩在线一区二区| 国产剧情一区| 亚洲一级少妇| 伊人精品久久| 丁香婷婷久久| av不卡在线看| 国产精品网址| 免费视频亚洲| 欧美久久精品| 91精品啪在线观看国产18| 香蕉成人久久| 久久这里只有精品一区二区| 欧美丝袜一区| 欧美日韩精品一区二区三区视频 | 精品久久久网| 黄色成人91| 久久99视频| 中文在线一区| 卡一精品卡二卡三网站乱码| 黄色av日韩| 麻豆免费精品视频| 婷婷综合亚洲| 日韩高清欧美激情| 99久精品视频在线观看视频| 日韩区欧美区| 久久在线电影| 国产人成精品一区二区三| 99tv成人| 欧美1区2区3| 国产精品日韩久久久| 久久亚洲人体| 亚洲91网站| 99久久久国产精品美女| 国产精品最新| 亚洲综合欧美| 午夜久久福利| 日韩av福利| 精品国产亚洲日本| 欧美日韩18|