iOS 图片的底层编辑framework还是很强大的,CoreGraphics。

实际中的应用案例:圆形的用户头像

一般头像是用UIImageView来显示

一种很古老的圆角方法为

UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
    imageView.image = [UIImage imageNamed:@"123"];
    imageView.layer.cornerRadius = imageView.frame.size.width/2.0;
    imageView.layer.masksToBounds = YES;

其实很多人指出来了,这种方法会降低系统性能,触发离屏渲染。

其实,可以直接对image进行操作,将image切出圆角,然后传给imageView。

这里就涉及到对图片的操作。

首先创建一个图片画布,UIGraphicsBeginImageContextWithOptions(CGSize size, BOOL opaque, CGFloat scale);
size为你最终需要的图片大小,第二个参数是表示是否透明。第三个参数比较特殊,缩放因子,这个需要注意,因为他的设置可能会影响到后面的图片质量。

其实还有一种默认的画布创建方法,UIGraphicsBeginImageContext(),等同于 UIGraphicsBeginImageContextWithOptions(size, NO, 1.0)。
如果在这个画布上对图片进行缩放操作,会导致缩小的图片变的更加模糊。问题就出在scale上。因为scale是1.0,而retina屏幕的像素肯定不是一倍像素,所以我们需要手动处理scale,用 UIGraphicsBeginImageContextWithOptions(size, NO, 0.0)这个方法去作图。0.0的意思就是自动调整缩放因子以适配显示屏,无论是Retina屏,还是普通屏,都可以清晰呈现。

创建好画布后,需要在画布上画出圆形的轨迹,用于剪切将要处理的图片。用Bezier曲线在画布上创建一个最大的内切圆轨迹。

UIBezierPath *cornerPath = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(0,0,size.width,size.height) byRoundingCorners:rectCornerType cornerRadii:cornerRadii];

或者

CGRect rect = CGRectMake(0, 0, size.width, size.height);
    UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:rect];

然后需要根据path来clip

[path addClip];

UIBezierPath中的addClip功能:

This method modifies the visible drawing area of the current graphics context. After calling it, subsequent drawing operations result in rendered content only if they occur within the fill area of the specified path.

简单的说,就是一个path调用addClip之后,它所在的context的可见区域就变成了它的“fill area”,接下来的绘制,如果在这个区域外都会被无视。

最后在画布上把待处理的image画上去

[self drawInRect:CGRectMake(0, 0,size.width, size.height)];

相当于把我们之前制作好的圆形path“模具”在image上切除圆形图片。

最后从画布上取出处理后的image

UIImage *image = UIGraphicsGetImageFromCurrentImageContext();

关闭画布

UIGraphicsEndImageContext();

当然,这样处理图片的前提是,他是正方形。

如果是非正方形,比如矩形之类的。我们裁取矩形内最大的正方形的内切圆。这话比较拗口,就是先取矩形内最大的正方形,然后取这个正方形中最大的内切圆。

这个时候就需要做些位置上的调整。

首先,因为我们需要的是圆形头像,所以画布还是正方形的。这个时候如果矩形的图片画在画布上,会有部分伸出画布的区域。伸出的部分我们不需要,不用管。

draw image的时候就需要注意了,在哪个位置画。例如图片的长度大于宽度的时候,为了保证切到图片的正中央,原来的图片draw的坐标为(0,0),这时候需要将图片往左移动(-n,0),n为画布的长度减去图片长度然后除以2。

打个比方,圆形的Bezier曲线path是一个圆形的铁框,然后要剪切的图片为一块豆腐,豆腐长度比铁框半径大,所以需要把豆腐往作移动,然后往下一按,再取出铁框里的圆形豆腐,就是我们需要的结果。→_→

ios 设置view圆角 ios icon圆角_缩放