iOS中三種切圓角的幾種方法比較和圖片優化

  當我們在做APP的個人中心的時候,總會有用戶頭像的需求,用戶頭像最好是圓形的,我們有一下三種方式將一種圖片切成圓形:

第一種方法:通過設置layer的屬性 , 最簡單的一種,但是很影響性能,一般在正常的開發中使用很少
swift代碼如下:
        let imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 150, height: 150))
        imageView.image = UIImage(named: "meinv")
        imageView.center = view.center
        imageView.layer.cornerRadius = imageView.bounds.size.width / 2
        imageView.layer.masksToBounds = true
        view.addSubview(imageView)

OC代碼如下:
     UIImageView * imageview = [[UIImageView alloc] initWithFrame:CGRectMake(00, 00, 150, 150)];
     imageview.image = [UIImage imageNamed:@"meinv"];
     imageview.layer.cornerRadius = imageview.bounds.size.width / 2;
     imageview.layer.masksToBounds = YES;
     imageview.center = self.view.center;
     [self.view addSubview:imageview];
第二種方法:使用CAShapeLayer和UIBezierPath設置圓角
swift代碼如下:
        let imageview = UIImageView(frame: CGRect(x: 0, y: 0, width: 150, height: 150))
        imageview.center = view.center
        imageview.image = UIImage(named: "meinv")
 //畫一個部分圓角的矩形 rect: 需要畫的矩形的Frame corners: 哪些部位需要畫成圓角 cornerRadii: 圓角的Size
        let maskPath = UIBezierPath(roundedRect: imageview.bounds, byRoundingCorners: .allCorners, cornerRadii: imageview.bounds.size)
        let maskLayer = CAShapeLayer()
        maskLayer.frame = imageview.bounds
        maskLayer.path = maskPath.cgPath
        imageview.layer.mask = maskLayer
        view.addSubview(imageview)

OC代碼如下:
      UIImageView * imageview = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, 150, 150)];
      imageview.center = self.view.center;
      imageview.image = [UIImage imageNamed:@"meinv"];
      UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:imageview.bounds byRoundingCorners:UIRectCornerAllCorners cornerRadii:imageview.bounds.size];
      CAShapeLayer *maskLayer = [[CAShapeLayer alloc]init];
    //設置大小
      maskLayer.frame = imageview.bounds;
    //設置圖形樣子
      maskLayer.path = maskPath.CGPath;
      imageview.layer.mask = maskLayer;
      [self.view addSubview:imageview];
第三種方法:使用貝塞爾曲線UIBezierPath和Core Graphics框架畫出一個圓角
swift代碼如下:
        let imageview = UIImageView(frame: CGRect(x: 0, y: 0, width: 150, height: 150))
        imageview.center = view.center
        imageview.image = UIImage(named: "meinv")
    // 開始對imageView進行畫圖
        UIGraphicsBeginImageContextWithOptions(imageview.bounds.size, false, 0);
    // 實例化一個圓形的路徑
        let path = UIBezierPath(ovalIn: imageview.bounds)
    //  進行路勁裁切   后續的繪圖都會出現在圓形內  外部的都被干掉
        path.addClip()
        imageview.draw(imageview.bounds)
    //  取到結果
       imageview.image = UIGraphicsGetImageFromCurrentImageContext()
   // 關閉上下文
       UIGraphicsEndImageContext()
       view.addSubview(imageview)
OC代碼如下:
     UIImageView * imageview = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, 150, 150)];
     imageview.center = self.view.center;
     imageview.image = [UIImage imageNamed:@"meinv"];
    //開始對imageView進行畫圖
    UIGraphicsBeginImageContextWithOptions(imageview.bounds.size, NO, 0);
    //使用貝塞爾曲線畫出一個圓形圖
    [[UIBezierPath bezierPathWithOvalInRect:imageview.bounds] addClip];
    [imageview drawRect:imageview.bounds];
    imageview.image = UIGraphicsGetImageFromCurrentImageContext();
   //結束畫圖
    UIGraphicsEndImageContext();
    [self.view addSubview:imageview];

以上便是iOS中的三種方式對圖片進行切圓角的方法,如果還有其他的方法,歡迎補充。那么這三張切圓角的方法性能如何呢,我們可以用最簡單的Xcode模擬器DeBug的進行檢測
68348F99-CA09-47C7-9DAA-104A66B6F90A.png
最主要的是用Color Blended Layers 和 Color Misaligned Images進行檢測,這里copy下這些Color的作用

Color Blended Layers 大概的意思就是圖層顏色混合。
大概意思說就是綠色最好,紅色不好。。
Color Misaligned Images 黃色的圖層由于圖層顯示的是被縮放后的圖片。還有些系統Navigation Bar和Tool Bar的背景圖片使用的是拉伸(Streched)圖片,也會被表示為黃色,這是屬于正常情況,通常無需修改。這種問題一般對性能影響不大,而是可能會在邊緣處虛化。

我們看下三種切圓角的方法的Blended和Misaligned
方法一:
Simulator Screen Shot 2017年3月10日 上午10.40.18.png
Simulator Screen Shot 2017年3月10日 上午10.40.23.png

很顯然,用cornerRadius去切割圖像,無論Blended還是Misaligned都是極差的,大大的增加了內存的消耗

方法二
Simulator Screen Shot 2017年3月10日 上午10.43.08.png
Simulator Screen Shot 2017年3月10日 上午10.42.59.png

使用CAShapeLayer和UIBezierPath設置圓角的話知識有圖片拉伸的問題,算起來是比較好的一種方法

方法三
Simulator Screen Shot 2017年3月10日 上午10.48.38.png
Simulator Screen Shot 2017年3月10日 上午10.48.35.png

方法三圖片倒是不拉伸了,但是Blended又有問題了

那么有沒有一種方法是Blended和Misaligned都沒問題的呢?

只要把方法三的一些參數改變一下,就可以實現了,在方法三中,有個方法 UIGraphicsBeginImageContextWithOptions(imageview.bounds.size, false, 0); 其中第二個參數 true表示透明 false表示不透明,只要把參數改成true,那么無論是Blended還是Misaligned都可以實現我們所預期的樣子,但是這樣切圓角的時候圖片四周有黑黑的一層,這是我們介意使用 背景填充 setFill這個方法根據圖片背景色進行填充,這樣就大功告成了。
UIColor.white.setFill()
UIRectFill(imageview.bounds)
最后的樣子:

Simulator Screen Shot 2017年3月10日 上午11.05.07.png
Simulator Screen Shot 2017年3月10日 上午11.05.13.png
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容