SDWebImageDecoder引發(fā)的思考

關于SDWebImage中的SDWebImageDecoder這個類,看完以后有下面幾個思考

0.為什么圖片要解碼

1.這么解碼的好處

2.這么解碼有壞處嗎

圖片的格式(png, jpg, gif ,webp,bitMap等等)

jpeg :

(1)有損壓縮格式, 將像素信息用jpeg保存成文件再讀取出來,其中某些像素值會有少許變化每瞒。

(2)沒有透明信息

(3)jpeg比較適合用來存儲相機拍攝出來的圖片

png :

(1) png是一種無損壓縮格式

(2) png可以有透明效果

(3)png比較適合矢量圖,幾何圖.

(矢量格式的一大優(yōu)點就是縮放.矢量格式的圖像其實是一組繪圖命令.這些指令通常是獨立于尺寸的.如果你想要擴大一個圓形,只需在繪制之前擴大他的半徑就可以了)

bitMap(位圖):

(1)bmp格式沒有壓縮像素格式

(2)存儲在文件中時先有文件頭月趟、再圖像頭济榨、后面就都是像素數據了搅吁,上下顛倒存儲

最早接觸到bitMap是在imageView的layer.shouldRasterize,你是否也用過這個屬性

CALayer的shouldRasterize和離屏渲染(offscreen rendering):

開啟shouldRasterize后,CALayer會被光柵化為bitmap,layer的陰影等效果也會被保存到bitmap中.

更新已光柵化的layer,會造成大量的offscreen渲染.

offscreen rendring: 指的是在圖像在繪制到當前屏幕前,需要先進行一次渲染,之后才繪制到當前屏幕。

離屏渲染有兩種:

1 .GPU的離屏渲染(shouldRasterize,mask等layer相關的 )

2 ,CPU的離屏渲染(使用drawRect,和CoreGraphic(線程安全,SDWebImage的解壓圖片))

?離屏渲染消耗性能:(看了好多文章都是這么寫的):

原因是顯卡需要另外alloc一塊內存來進行渲染,渲染完畢后在繪制到當前屏幕,而且對于顯卡來說,onscreen到offscreen的上下文環(huán)境切換是非常昂貴的(涉及到OpenGL的pipelines和barrier等).

開啟柵格化,相當于把部分GPU的工作轉到CPU來做了,由CPU生成bitMap,供GPU下次使用.

總結: 開起柵格化的圖片的內容不應該經常變化,否則造成大量的離屏渲染.它使用的范圍應該是當前l(fā)ayer的顯示比較復雜,但卻不怎么變化.

就可以開啟柵格化,在內存中保留一份,以方便使用.

Advanced Graphics and Animations for iOS Apps

這篇文章比較詳細,也介紹了Instruments對性能的測試,對上面有興趣的可以深看一下.

圖片的在內存中的大小

圖片在內存中占用的大小 跟圖片自身的大小沒有關系

內存中占用的大小 = 圖片的寬度 * 圖片的高度*每個像素占用的字節(jié)數

在SDWebImage中衡量大圖的標準:

圖片的像素總數 > 60M內存所存儲的像素數 ? 壓縮 : 不壓縮.

蘋果官方的加載大圖demo

這個里面的大圖處理邏輯個SDWebImage 是完全一樣的,介紹更詳細,效果看起來也更好,建議看蘋果官方的.

基本原理:也就是原圖按照定好的大小(像素).來對原圖進行切塊,然后再一塊塊的繪制到destContext.

(這里網上Google了好多文章,對這個介紹很少,還是不怎么明白

static const CGFloat ?kDestSeemOverlap =2.0f;// the numbers of pixels to overlap(重疊) the seems where tiles(切片) meet.

為什么要定義這個,這個為什么會有重合的像素,以及它在后面的代碼里面的操作.還望有大神明白指導一下,不勝感激).

這些都是經過壓縮編碼后的圖片格式,是不能直接使用的,其基本原理

圖片為什么要解碼

png,jpeg格式的數據是不能直接使用的,需要將其轉化為位圖.

當我們使用imageView顯示圖片的時候:

1.讀取圖片

2.解壓圖片為位圖(消耗CPU)

3.如果位圖數據不是字節(jié)對齊的煤蚌,CoreAnimation會copy一份位圖數據并進行字節(jié)對齊

4 CoreAnimation渲染解壓縮過的位圖

這一切在IOS中都是默認發(fā)生在主線程成的并且是在UIImageView執(zhí)行setImage方法的時候完成的(在UIImage imageNamed的時候不會發(fā)生,具體參考下文).

當你使用[UIImage ImageNamed: @"xxx.jpg"]的時候,內存不會有明顯變化,只有當調用

UIImageView的setImage的時候,這時候內存才會增加.并且這時候你將imageView移除,內存也不會有減少. 這也是為什么

+ (nullableUIImage*)imageNamed:(NSString*)name;

不適合加載大的 不常用的圖片.因為它會默認在程序里保存這張圖片數據(不會隨ImageView的移除而移除).只有經常使用圖片適合這種方式加載.

+ (nullableUIImage*)imageWithContentsOfFile:(NSString*)path;

這個方法跟上面的略有不同,他不會在內存中保留一份數據.只要imageView移除,內存中的數據就會直接移除.這也就是這個方法為什么適合加載大的圖片,但卻不常用的圖片.


這樣解碼的好處:

把圖片解碼這個默認在主線程執(zhí)行,耗損CPU的行為,放在了后臺線程.

只需要在使用的時候,直接setImage,不會有太大的CPU消耗

這只是對圖片優(yōu)化的其中一種方式.在圖片從下載到顯示的過程中有很多個步驟可以優(yōu)化:

有興趣的可以參考這篇文章:

IOS異步圖片加載與常用的優(yōu)化

Instruments的測試

由于數據比較多,直接做成了gif動畫. 細細觀察吧

PS:

下面的前兩幅圖是執(zhí)行下面這段代碼:(圖1,圖2,內存和CPU的消耗):?

(1) 解壓是代碼執(zhí)行SDWebImage的:

NSString*path = [[NSBundlemainBundle]pathForResource:@"xxx.jpg"ofType:nil];

UIImage *image = [UIImage imageWithContentsOfFile:path];

_decodeImage = [UIImage decodedImageWithImage :image];(SDWebImage的decodedImageWithImage)方法

(2) 點擊灰色區(qū)域:

_showImageView.image = _decodeImage;

(3)點擊移除

[_showImageView removeFromSuperView];

_decodeImage = nil;

下面的后兩幅圖是執(zhí)行下面這段代碼:(圖3,圖4,內存和CPU的消耗):

(1) 點擊 使用UIImage imageName加載的按鈕 是代碼執(zhí)行的:

_image = [UIImage imageNamed:@"xxx.jpg"];

(2) 點擊灰色區(qū)域:

_showImageView.image = _image;

(3)點擊移除

[_showImageView removeFromSuperView];

_image = nil;

使用SDWebImage的decodedImageWithImage方法解碼的時候,內存的占用情況


1

使用SDWebImage的decodedImageWithImage方法解碼的時候,CPU的占用情況


2

使用[UIImage imageNamed:@"xxx.jpg"]的內存占用情況


3 這里可以清楚地看到,移除ImageView和指針后,圖片沒有被銷毀,還存在內存中

使用[UIImage imageNamed:@"xxx.jpg"]的CPU占用情況


4

這樣解碼的弊端:

這樣解碼就是以空間換時間的方法,提前解壓好,用的時候直接從內存讀取.

如果下載的圖片比較大,然后直接解碼的話 這個是內存所不能承受,需要對圖片進行壓縮.

不過SDWebImage里面也提供了對大圖的壓縮API.

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末豪嚎,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子厢塘,更是在濱河造成了極大的恐慌茶没,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,470評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件俗冻,死亡現場離奇詭異礁叔,居然都是意外死亡,警方通過查閱死者的電腦和手機迄薄,發(fā)現死者居然都...
    沈念sama閱讀 92,393評論 3 392
  • 文/潘曉璐 我一進店門琅关,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事涣易』” “怎么了?”我有些...
    開封第一講書人閱讀 162,577評論 0 353
  • 文/不壞的土叔 我叫張陵新症,是天一觀的道長步氏。 經常有香客問我,道長徒爹,這世上最難降的妖魔是什么荚醒? 我笑而不...
    開封第一講書人閱讀 58,176評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮隆嗅,結果婚禮上界阁,老公的妹妹穿的比我還像新娘。我一直安慰自己胖喳,他們只是感情好泡躯,可當我...
    茶點故事閱讀 67,189評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著丽焊,像睡著了一般较剃。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上技健,一...
    開封第一講書人閱讀 51,155評論 1 299
  • 那天写穴,我揣著相機與錄音,去河邊找鬼凫乖。 笑死确垫,一個胖子當著我的面吹牛,可吹牛的內容都是我干的帽芽。 我是一名探鬼主播删掀,決...
    沈念sama閱讀 40,041評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼导街!你這毒婦竟也來了披泪?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 38,903評論 0 274
  • 序言:老撾萬榮一對情侶失蹤搬瑰,失蹤者是張志新(化名)和其女友劉穎款票,沒想到半個月后,有當地人在樹林里發(fā)現了一具尸體泽论,經...
    沈念sama閱讀 45,319評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡艾少,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,539評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現自己被綠了翼悴。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片缚够。...
    茶點故事閱讀 39,703評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出谍椅,到底是詐尸還是另有隱情误堡,我是刑警寧澤,帶...
    沈念sama閱讀 35,417評論 5 343
  • 正文 年R本政府宣布雏吭,位于F島的核電站锁施,受9級特大地震影響,放射性物質發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,013評論 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧柒啤,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,664評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽栅螟。三九已至荆秦,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間力图,已是汗流浹背步绸。 一陣腳步聲響...
    開封第一講書人閱讀 32,818評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留吃媒,地道東北人瓤介。 一個月前我還...
    沈念sama閱讀 47,711評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像赘那,于是被迫代替她去往敵國和親刑桑。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,601評論 2 353

推薦閱讀更多精彩內容

  • 誰吃掉我們的CPU: 方法CA::Render::create_image_from_provider 圖片預解碼...
    神采飛揚_2015閱讀 3,230評論 2 6
  • 導語:這是SDWebImage源碼理解的第一篇募舟,本篇先介紹圖片解碼相關的背景知識祠斧,然后介紹SDWebImage中解...
    南華coder閱讀 7,468評論 12 48
  • 繪制像素到屏幕上 answer-huang22 Mar 2014 分享文章 一個像素是如何繪制到屏幕上去的?有很多...
    阿貍旅途T恤閱讀 1,636評論 0 7
  • 卷首語 歡迎來到 objc.io 的第三期拱礁! 這一期都是關于視圖層的琢锋。當然視圖層有很多方面,我們需要把它們縮小到幾...
    評評分分閱讀 1,765評論 0 18
  • 在聊這一話題之前呢灶,我們先看看屏幕是如何顯示圖像的吴超。 屏幕顯示圖像的原理 在最簡單的情況下,幀緩沖區(qū)只有一個鸯乃,這時幀...
    muice閱讀 3,106評論 4 19