iOS圖片設(shè)置圓角性能優(yōu)化

對(duì)圖片進(jìn)行圓角處理會(huì)相比于直角固翰,它更加柔和優(yōu)美,是一種很常見的視圖效果浊猾,在APP中常用于對(duì)用戶頭像的美化,但是設(shè)置不當(dāng)就會(huì)讓你的APP性能下降,導(dǎo)致掉幀,影響用戶體驗(yàn)
首先介紹一下常用的切圓角的幾種常見方式

第一種方法:通過(guò)設(shè)置layer的屬性

UIImageView *imageView = [[UIImageView alloc]initWithFrame:CGRectMake(100, 100, 100, 100)]; //只需要設(shè)置layer層的兩個(gè)屬性  
//設(shè)置圓角    
 imageView.layer.cornerRadius = imageView.frame.size.width / 2; 
//將多余的部分切掉
 imageView.layer.masksToBounds = YES;
 [self.view addSubview:imageView];

但是這種方式切圓角的很大一個(gè)弊端就是影響性能,對(duì)于圖片較少的情況下還不是很明顯,不會(huì)太影響幀數(shù),但是圖片多的時(shí)候就會(huì)嚴(yán)重影響幀數(shù)(視圖和圓角的大小對(duì)幀率并沒(méi)有什么卵影響沼头,數(shù)量才是傷害的核心輸出),大概圓角的數(shù)量在30-40左右的時(shí)候,界面就會(huì)卡出翔的節(jié)奏,所以開發(fā)中一般不會(huì)用這個(gè)方法.
一開始我以為導(dǎo)致幀數(shù)下降的原因是imageView.layer.cornerRadius 這個(gè)方法造成的,后來(lái)才發(fā)現(xiàn)罪魁禍?zhǔn)资莍mageView.layer.masksToBounds ,這玩意會(huì)導(dǎo)致離屏渲染,
離屏渲染我并沒(méi)有深入的去了解,在網(wǎng)上找資料大體的了解下

渲染機(jī)制是GPU在當(dāng)前屏幕緩沖區(qū)外新開辟一個(gè)渲染緩沖區(qū)進(jìn)行工作羹令,也就是離屏渲染傻谁,這會(huì)給我們帶來(lái)額外的性能損耗孝治,如果這樣的圓角操作達(dá)到一定數(shù)量,會(huì)觸發(fā)緩沖區(qū)的頻繁合并和上下文的的頻繁切換审磁,性能的代價(jià)會(huì)宏觀地表現(xiàn)在用戶體驗(yàn)上----掉幀

但是ios9之后蘋果對(duì)離屏渲染做了優(yōu)化
1.iOS 9.0 之前UIimageView跟UIButton設(shè)置圓角都會(huì)觸發(fā)離屏渲染
2.iOS 9.0 之后UIButton設(shè)置圓角會(huì)觸發(fā)離屏渲染谈飒,而UIImageView里png圖片設(shè)置圓角不會(huì)觸發(fā)離屏渲染了,如果設(shè)置其他陰影效果之類的還是會(huì)觸發(fā)離屏渲染的态蒂。
這可能是蘋果也意識(shí)到離屏渲染會(huì)產(chǎn)生性能問(wèn)題杭措,所以能不產(chǎn)生離屏渲染的地方蘋果也就不用離屏渲染了。
對(duì)第一種方法的總結(jié)
1.如果圖片數(shù)量很少,能夠只用 cornerRadius 解決問(wèn)題钾恢,就不用優(yōu)化手素。
2.如果必須設(shè)置 masksToBounds,而且只是設(shè)置UIImageView的圓角,那么久不用考慮離屏渲染,如果設(shè)置其他的空間,那么就要在空間設(shè)置圓角過(guò)多的情況下舍棄這一種方法

第二種方法:使用貝塞爾曲線UIBezierPath和Core Graphics框架畫出一個(gè)圓角

UIImageView *imageView = [[UIImageView alloc]initWithFrame:CGRectMake(100, 100, 100, 100)]; 
imageView.image = [UIImage imageNamed:@"1"]; 
//開始對(duì)imageView進(jìn)行畫圖 UIGraphicsBeginImageContextWithOptions(imageView.bounds.size, NO, 1.0); 
//使用貝塞爾曲線畫出一個(gè)圓形圖 
[[UIBezierPath bezierPathWithRoundedRect:imageView.bounds cornerRadius:imageView.frame.size.width] addClip];
 [imageView drawRect:imageView.bounds];
 imageView.image = UIGraphicsGetImageFromCurrentImageContext(); 
//結(jié)束畫圖 
UIGraphicsEndImageContext(); [self.view addSubview:imageView];

第三種方法:使用CAShapeLayer和UIBezierPath設(shè)置圓角

#import "ViewController.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad { [super viewDidLoad]; 
UIImageView *imageView = [[UIImageView alloc]initWithFrame:CGRectMake(100, 100, 100, 100)]; imageView.image = [UIImage imageNamed:@"1"]; 
UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:imageView.bounds byRoundingCorners:UIRectCornerAllCorners cornerRadii:imageView.bounds.size];
 CAShapeLayer *maskLayer = [[CAShapeLayer alloc]init]; 
//設(shè)置大小 
maskLayer.frame = imageView.bounds; 
//設(shè)置圖形樣子 
maskLayer.path = maskPath.CGPath;
 imageView.layer.mask = maskLayer; 
[self.view addSubview:imageView];}

1.首先是CAShapeLayer
1.1CAShapeLayer繼承于CALayer,可以使用CALayer的所有屬性值瘩蚪;
1.2CAShapeLayer需要貝塞爾曲線配合使用才有意義(也就是說(shuō)才有效果)
1.3使用CAShapeLayer(屬于CoreAnimation)與貝塞爾曲線可以實(shí)現(xiàn)不在view的drawRect(繼承于CoreGraphics走的是CPU,消耗的性能較大)方法中畫出一些想要的圖形
1.4CAShapeLayer動(dòng)畫渲染直接提交到手機(jī)的GPU當(dāng)中泉懦,相較于view的drawRect方法使用CPU渲染而言,其效率極高疹瘦,能大大優(yōu)化內(nèi)存使用情況
總的來(lái)說(shuō)就是用CAShapeLayer的內(nèi)存消耗少,渲染速度快,建議使用第三種

框架ZYCornerRadius

另外在給大家介紹一個(gè)第三方框架,雖然star不多,但是感覺挺使用,個(gè)人使用的不是太多,因?yàn)槠綍r(shí)工作中大量的圖片切圓角并沒(méi)有遇到,
地址:https://github.com/liuzhiyi1992/ZYCornerRadius
我簡(jiǎn)單的了解了下,作者用了兩種途徑去實(shí)現(xiàn),一個(gè)是uiimageView的分類,另外一個(gè)是子類實(shí)現(xiàn),而且用到了runtime運(yùn)行時(shí)的知識(shí),(給分類中增加私有屬性),總體會(huì)大大降低了設(shè)置圓角是產(chǎn)生的內(nèi)存占用高和幀數(shù)低的問(wèn)題,而且還支持多種帶邊框的圓角,這里就不在多贅述了,大家有需要的可以去github去克隆下來(lái)研究研究

最后總結(jié)

1.對(duì)于圓角少的情況下,而且是ios9以上,設(shè)置圖片可以不用考慮離屏渲染,數(shù)量少的陰影和其他控件的圓角設(shè)置也影響不大
2.數(shù)量多的情況,而且ios9以下的情況切忌使用cornerRadius,maskToBounds來(lái)設(shè)置,掉幀太嚴(yán)重,盡量使用貝塞爾曲線和Core Graphics框架或者CAShapeLayer來(lái)去實(shí)現(xiàn),或者用第三方框架

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末崩哩,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子言沐,更是在濱河造成了極大的恐慌琢锋,老刑警劉巖辕漂,帶你破解...
    沈念sama閱讀 222,627評(píng)論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異吴超,居然都是意外死亡钉嘹,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,180評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門鲸阻,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)跋涣,“玉大人,你說(shuō)我怎么就攤上這事鸟悴〕氯瑁” “怎么了?”我有些...
    開封第一講書人閱讀 169,346評(píng)論 0 362
  • 文/不壞的土叔 我叫張陵细诸,是天一觀的道長(zhǎng)沛贪。 經(jīng)常有香客問(wèn)我,道長(zhǎng)震贵,這世上最難降的妖魔是什么利赋? 我笑而不...
    開封第一講書人閱讀 60,097評(píng)論 1 300
  • 正文 為了忘掉前任,我火速辦了婚禮猩系,結(jié)果婚禮上媚送,老公的妹妹穿的比我還像新娘。我一直安慰自己寇甸,他們只是感情好塘偎,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,100評(píng)論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著拿霉,像睡著了一般吟秩。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上绽淘,一...
    開封第一講書人閱讀 52,696評(píng)論 1 312
  • 那天涵防,我揣著相機(jī)與錄音,去河邊找鬼收恢。 笑死武学,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的伦意。 我是一名探鬼主播火窒,決...
    沈念sama閱讀 41,165評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼驮肉!你這毒婦竟也來(lái)了熏矿?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 40,108評(píng)論 0 277
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎票编,沒(méi)想到半個(gè)月后褪储,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,646評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡慧域,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,709評(píng)論 3 342
  • 正文 我和宋清朗相戀三年鲤竹,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片昔榴。...
    茶點(diǎn)故事閱讀 40,861評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡辛藻,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出互订,到底是詐尸還是另有隱情吱肌,我是刑警寧澤,帶...
    沈念sama閱讀 36,527評(píng)論 5 351
  • 正文 年R本政府宣布仰禽,位于F島的核電站氮墨,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏吐葵。R本人自食惡果不足惜规揪,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,196評(píng)論 3 336
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望折联。 院中可真熱鬧粒褒,春花似錦识颊、人聲如沸诚镰。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,698評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)清笨。三九已至,卻和暖如春刃跛,著一層夾襖步出監(jiān)牢的瞬間抠艾,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,804評(píng)論 1 274
  • 我被黑心中介騙來(lái)泰國(guó)打工桨昙, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留检号,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 49,287評(píng)論 3 379
  • 正文 我出身青樓蛙酪,卻偏偏與公主長(zhǎng)得像齐苛,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子桂塞,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,860評(píng)論 2 361

推薦閱讀更多精彩內(nèi)容