老生常談的圓角圖片優(yōu)化凭戴,結(jié)合SDWebImage的解決方案。

很早就想寫一篇講述圓角優(yōu)化的博客了炕矮。簇宽。結(jié)果發(fā)現(xiàn)這篇文章iOS 高效添加圓角效果實(shí)戰(zhàn)講解寫得很好:摘錄文章的總結(jié)部分勋篓,當(dāng)拓展閱讀了:

總結(jié)
如果能夠只用 cornerRadius 解決問(wèn)題,就不用優(yōu)化魏割。
如果必須設(shè)置 masksToBounds譬嚣,可以參考圓角視圖的數(shù)量,如果數(shù)量較少(一頁(yè)只有幾個(gè))也可以考慮不用優(yōu)化钞它。
UIImageView 的圓角通過(guò)直接截取圖片實(shí)現(xiàn)拜银,其它視圖的圓角可以通過(guò) Core Graphics 畫出圓角矩形實(shí)現(xiàn)。

過(guò)早的優(yōu)化是惡魔遭垛,這句話確實(shí)很有道理

Premature optimization is the root of all evil --Donald Knuth

當(dāng)時(shí)我做圓角優(yōu)化的場(chǎng)景尼桶,是一個(gè)collectionView很多頭像的展示。如果單純的用layer設(shè)置cornerRadius和masksToBounds锯仪,會(huì)產(chǎn)生離屏渲染泵督,小心別讓圓角成了你列表的幀數(shù)殺手,這篇文章已經(jīng)寫的很清楚了庶喜,就不贅述了小腊。

self.xxView.layer.cornerRadius = 5.0f;
self.xxView.layer.masksToBounds = YES;

Advanced Graphics and Animations for iOS Apps(session 419) 學(xué)習(xí)與延伸這篇文章也介紹了離屏渲染的一些知識(shí),有需要的同學(xué)可以去拓展閱讀一下久窟。

正文

其實(shí)寫到這里我已經(jīng)很方了秩冈。。因?yàn)楦杏X(jué)好多人都寫過(guò)了斥扛。入问。
這邊再留兩篇文章:
最早接觸到圓角優(yōu)化是里脊串寫的一次對(duì)MKMapView的性能優(yōu)化
近來(lái)還有葉孤城___reviewcode.cn里提出的解決方案。
你們可以先看我的文章稀颁,然后再去拓展閱讀芬失,反正上面那么多鏈接你們也要看一會(huì)[認(rèn)真臉]。

既然原理上面的文章都講過(guò)很多了匾灶,我真不好意思再講一遍了麸折,我就來(lái)說(shuō)說(shuō)我怎么做的吧。
首先給imageView一個(gè)catagory粘昨,核心方法如下:

- (void)lhy_loadImageUrlStr:(NSString *)urlStr placeHolderImageName:(NSString *)placeHolderStr radius:(CGFloat)radius;

當(dāng)然也有些簡(jiǎn)便的方法方便不同場(chǎng)景調(diào)用:

- (void)lhy_loadImageUrlStr:(NSString *)urlStr;
- (void)lhy_loadImageUrlStr:(NSString *)urlStr radius:(CGFloat)radius;

核心方法是這樣寫的:

- (void)lhy_loadImageUrlStr:(NSString *)urlStr placeHolderImageName:(NSString *)placeHolderStr radius:(CGFloat)radius {
    //something
    //這里有針對(duì)不同需求的處理,我就沒(méi)貼出來(lái)了
    //...

    NSURL *url;

    if (placeHolderStr == nil) {
        placeHolderStr = @"你通用的占位圖地址";
    }
   
    //這里傳CGFLOAT_MIN窜锯,就是默認(rèn)以圖片寬度的一半為圓角
    if (radius == CGFLOAT_MIN) {
        radius = self.frame.size.width/2.0;
    }

    url = [NSURL URLWithString:urlStr];

    if (radius != 0.0) {
        //頭像需要手動(dòng)緩存處理成圓角的圖片
        NSString *cacheurlStr = [urlStr stringByAppendingString:@"radiusCache"];
        UIImage *cacheImage = [[SDImageCache sharedImageCache] imageFromDiskCacheForKey:cacheurlStr];
        if (cacheImage) {
            self.image = cacheImage;
        }
        else {
            [self sd_setImageWithURL:url placeholderImage:[UIImage imageNamed:placeHolderStr] completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {
                if (!error) {
                    UIImage *radiusImage = [UIImage createRoundedRectImage:image size:self.frame.size radius:radius];
                    self.image = radiusImage;
                    [[SDImageCache sharedImageCache] storeImage:radiusImage forKey:cacheurlStr];
                    //清除原有非圓角圖片緩存
                    [[SDImageCache sharedImageCache] removeImageForKey:urlStr];
                }
            }];
        }
    }
    else {
        [self sd_setImageWithURL:url placeholderImage:[UIImage imageNamed:placeHolderStr] completed:nil];
    }
}

圓角的繪制方法是一個(gè)imageView的catagory

static void addRoundedRectToPath(CGContextRef context, CGRect rect, float ovalWidth,
                                 float ovalHeight)
{
    float fw, fh;
    
    if (ovalWidth == 0 || ovalHeight == 0)
    {
        CGContextAddRect(context, rect);
        return;
    }
    
    CGContextSaveGState(context);
    CGContextTranslateCTM(context, CGRectGetMinX(rect), CGRectGetMinY(rect));
    CGContextScaleCTM(context, ovalWidth, ovalHeight);
    fw = CGRectGetWidth(rect) / ovalWidth;
    fh = CGRectGetHeight(rect) / ovalHeight;
    
    //根據(jù)圓角路徑繪制
    CGContextMoveToPoint(context, fw, fh/2); 
    CGContextAddArcToPoint(context, fw, fh, fw/2, fh, 1); 
    CGContextAddArcToPoint(context, 0, fh, 0, fh/2, 1); 
    CGContextAddArcToPoint(context, 0, 0, fw/2, 0, 1); 
    CGContextAddArcToPoint(context, fw, 0, fw, fh/2, 1);
    
    CGContextClosePath(context);
    CGContextRestoreGState(context);
}

+ (id)createRoundedRectImage:(UIImage*)image size:(CGSize)size radius:(NSInteger)r
{
    int w = size.width;
    int h = size.height;
    
    UIImage *img = image;
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    CGContextRef context = CGBitmapContextCreate(NULL, w, h, 8, 4 * w, colorSpace, (CGBitmapInfo)kCGImageAlphaPremultipliedFirst);
    //CGContextRef context = UIGraphicsGetCurrentContext();
    CGRect rect = CGRectMake(0, 0, w, h);
    
    CGContextBeginPath(context);
    addRoundedRectToPath(context, rect, r, r);
    CGContextClosePath(context);
    CGContextClip(context);
    CGContextDrawImage(context, CGRectMake(0, 0, w, h), img.CGImage);
    CGImageRef imageMasked = CGBitmapContextCreateImage(context);
    img = [UIImage imageWithCGImage:imageMasked];
    
    CGContextRelease(context);
    CGColorSpaceRelease(colorSpace);
    CGImageRelease(imageMasked);
    
    return img;
}

這樣只要兩個(gè)catagory张肾,這個(gè)頭像圓角結(jié)合SDWebImage緩存的應(yīng)用場(chǎng)景,就可以即插即用啦锚扎。

簡(jiǎn)書已經(jīng)棄用吞瞪,歡迎移步我的小專欄:
https://xiaozhuanlan.com/dahuihuiiOS

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市驾孔,隨后出現(xiàn)的幾起案子芍秆,更是在濱河造成了極大的恐慌惯疙,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,482評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件妖啥,死亡現(xiàn)場(chǎng)離奇詭異霉颠,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)荆虱,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,377評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門蒿偎,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人怀读,你說(shuō)我怎么就攤上這事诉位。” “怎么了菜枷?”我有些...
    開(kāi)封第一講書人閱讀 152,762評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵苍糠,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我啤誊,道長(zhǎng)岳瞭,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書人閱讀 55,273評(píng)論 1 279
  • 正文 為了忘掉前任坷衍,我火速辦了婚禮寝优,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘枫耳。我一直安慰自己乏矾,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,289評(píng)論 5 373
  • 文/花漫 我一把揭開(kāi)白布迁杨。 她就那樣靜靜地躺著钻心,像睡著了一般。 火紅的嫁衣襯著肌膚如雪铅协。 梳的紋絲不亂的頭發(fā)上捷沸,一...
    開(kāi)封第一講書人閱讀 49,046評(píng)論 1 285
  • 那天,我揣著相機(jī)與錄音狐史,去河邊找鬼痒给。 笑死,一個(gè)胖子當(dāng)著我的面吹牛骏全,可吹牛的內(nèi)容都是我干的苍柏。 我是一名探鬼主播,決...
    沈念sama閱讀 38,351評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼姜贡,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼试吁!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起楼咳,我...
    開(kāi)封第一講書人閱讀 36,988評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤熄捍,失蹤者是張志新(化名)和其女友劉穎烛恤,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體余耽,經(jīng)...
    沈念sama閱讀 43,476評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡缚柏,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,948評(píng)論 2 324
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了宾添。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片船惨。...
    茶點(diǎn)故事閱讀 38,064評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖缕陕,靈堂內(nèi)的尸體忽然破棺而出粱锐,到底是詐尸還是另有隱情,我是刑警寧澤扛邑,帶...
    沈念sama閱讀 33,712評(píng)論 4 323
  • 正文 年R本政府宣布怜浅,位于F島的核電站,受9級(jí)特大地震影響蔬崩,放射性物質(zhì)發(fā)生泄漏恶座。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,261評(píng)論 3 307
  • 文/蒙蒙 一沥阳、第九天 我趴在偏房一處隱蔽的房頂上張望跨琳。 院中可真熱鬧,春花似錦桐罕、人聲如沸脉让。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 30,264評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)溅潜。三九已至,卻和暖如春薪伏,著一層夾襖步出監(jiān)牢的瞬間滚澜,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 31,486評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工嫁怀, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留设捐,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,511評(píng)論 2 354
  • 正文 我出身青樓塘淑,卻偏偏與公主長(zhǎng)得像萝招,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子朴爬,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,802評(píng)論 2 345

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

  • 在iOS中隨處都可以看到絢麗的動(dòng)畫效果,實(shí)現(xiàn)這些動(dòng)畫的過(guò)程并不復(fù)雜橡淆,今天將帶大家一窺iOS動(dòng)畫全貌召噩。在這里你可以看...
    F麥子閱讀 5,094評(píng)論 5 13
  • 在iOS中隨處都可以看到絢麗的動(dòng)畫效果母赵,實(shí)現(xiàn)這些動(dòng)畫的過(guò)程并不復(fù)雜,今天將帶大家一窺ios動(dòng)畫全貌具滴。在這里你可以看...
    每天刷兩次牙閱讀 8,465評(píng)論 6 30
  • 因?yàn)槲蚁M业娜松懈嗫赡堋?因?yàn)楫?dāng)初不想工作凹嘲,所以畢業(yè)后慌忙之下隨便進(jìn)了一家公司。這家公司呢工資一般构韵,環(huán)境放松...
    四一三閱讀 770評(píng)論 5 3
  • 看了病魔纏身好幾集周蹭,最大的感觸就是,當(dāng)開(kāi)始出現(xiàn)癥狀時(shí)疲恢,人們總是用習(xí)慣以往的經(jīng)驗(yàn)來(lái)判斷凶朗,覺(jué)得不過(guò)是一次普通感冒或...
    菩樹(shù)閱讀 122評(píng)論 0 0
  • 2015.12.24 今天可是平安夜啊 說(shuō)過(guò)我不愛(ài)過(guò)洋節(jié) 可能是心里有一種說(shuō)不出的愛(ài)國(guó)情愫 覺(jué)得我要為保護(hù)中國(guó)的傳...
    麻繩兮凍閱讀 390評(píng)論 1 0