免费开源的iOS开发学习平台

UIImage与绘图:3-裁剪圆形图片

在实际的iOS开发中,经常会涉及到对图片进行一些裁剪,例如,常见的个人信息栏目,通常会把个人头像裁剪成为圆形。裁剪图片操作也可以通过绘图的方式实现。

使用绘图的方式实现裁剪

当使用绘图的方式对图片进行裁剪时,主要的思路就是裁剪出来一个圆形的图形上下文,相当于得到了一张圆形的画布,然后在这个圆形的画布上绘画,自然得到了一张圆形的图片。

下面的示例代码实现了对一个正方形的图片进行裁剪,最终得到一个圆形的图片。

  • 在Storyboard中,添加一个UIImageView控件,修改其背景颜色为绿色

  • 把该UIImageView与控制器建立连线,命名为clipImageView

  • 在控制器的.m文件中添加如下图片裁剪的方法

-(UIImage *) clipImage:(UIImage *) image {
    
    //开启上下文
    UIGraphicsBeginImageContextWithOptions(image.size, NO, 0.0);
    //获取路径
    UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(0, 0, image.size.width, image.size.height)];
    //裁剪圆形
    [path addClip];
    //把图片塞进上下文中
    [image drawInRect:CGRectMake(0, 0, image.size.width, image.size.height)];
    //保存新图片
    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
    //关闭上下文
    UIGraphicsEndImageContext();
    //返回图片
    return newImage;
}
  • 在viewDidLoad方法中,为self.clipImageView对象设置image属性。
- (void)viewDidLoad {
    [super viewDidLoad];
    
    UIImage *image = [UIImage imageNamed:@"99ios"];
    image = [self clipImage:image];
    self.clipImageView.image = image;
}

运行效果如下。我们可以看到,我们得到的仅仅是一个裁剪成圆形的图片,然后再把图片添加到UIImageView中。通过给clipImageView控件添加一个绿色的背景(backgroud),此时控件还是方形的,同时也可以清晰的看到这种方式实现的原理。

其他简便方法(常用)

在实际的开发过程中,还有一种更加常用并且简便的方法,能够实现对图片控件的裁剪,即修改UIView的layer属性。

UIView类中有一个CALayer类型的属性–layer,通过对layer的修改,也可以达到对图片的裁剪效果。

CALayer类中有两个常用的属性,cornerRadius和masksToBounds属性

@property CGFloat cornerRadius;//圆角半径
@property BOOL masksToBounds; //是否裁剪

一般情况下,我们设置UIImageView对象的这两个属性,可以达到使图片控件的边角显示成为圆角的效果。

实现代码:

- (void)viewDidLoad {
    [super viewDidLoad];
    
    self.clipImageView.image = [UIImage imageNamed:@"99ios"];
    self.clipImageView.layer.cornerRadius = 10;
    self.clipImageView.layer.masksToBounds = YES;
    
}

当圆角半径等于图片宽度的一半时,裁剪处理的就是一个圆形的图片,如下所示。与上面通过绘图裁剪的方式对比,我们可以发现,此时控件的形状可以认为是圆形的。

示例代码

- (void)viewDidLoad {
    [super viewDidLoad];
    
    self.clipImageView.image = [UIImage imageNamed:@"99ios"];
    self.clipImageView.layer.cornerRadius = self.clipImageView.bounds.size.width * 0.5;
    self.clipImageView.layer.masksToBounds = YES;
}

https://github.com/99ios/14.2.3