设置圆角的4种方式--引申出离屏渲染

#pragma mark - 三、圆角问题4种

第一种:设置cornerRadius masksToBounds = yes,会引起离屏渲染
//    UIImageView * imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"imageName1.jpg"]];

//    [imageView setFrame: CGRectMake(100, 100, 50, 50)];

//    imageView.layer.cornerRadius = 5;

//    //裁剪掉超出的

//    imageView.layer.masksToBounds = YES;

//    [self.view addSubview:imageView];

//    

//    UIButton * button = [UIButton buttonWithType:UIButtonTypeCustom];

//    [button setImage:[UIImage imageNamed:@"imageName2.jpg"] forState:UIControlStateNormal];

//    [button setFrame:CGRectMake(100, 180, 50, 50)];

//    button.layer.cornerRadius = 10;

//    button.layer.masksToBounds = YES;

//    [self.view addSubview:button];

    

第二种:使用贝塞尔曲线UIBezierPath和Core Graphics框架在图片的绘图上下文中画出一个透明的圆,增加CPU负担,增加内存开销
//    UIImageView *imageViewTwo = [[UIImageView alloc]initWithFrame:CGRectMake(100, 100, 100, 100)];

//    imageViewTwo.image = [UIImage imageNamed:@"imageName1.jpg"];

//    //开始对imageView进行画图,在透明的这个imageView的画布上开始画

//    UIGraphicsBeginImageContextWithOptions(imageViewTwo.bounds.size, NO, [UIScreen mainScreen].scale);

////    UIGraphicsBeginImageContextWithOptions(<#CGSize size#>, <#BOOL opaque#>, <#CGFloat scale#>)

//    //opaque:不透明

//    //使用贝塞尔曲线画出一个圆形图,并且切掉其他的,就剩下了透明的想要的那个圆

//    [[UIBezierPath bezierPathWithRoundedRect:imageViewTwo.bounds cornerRadius:imageViewTwo.frame.size.width] addClip];

////    + (instancetype)bezierPathWithRoundedRect:(CGRect)rect cornerRadius:(CGFloat)cornerRadius; 

//    //rounds all corners with the same horizontal and vertical radius

//    [imageViewTwo drawRect:imageViewTwo.bounds];

//    

//    imageViewTwo.image = UIGraphicsGetImageFromCurrentImageContext();

//    //结束画图

//    UIGraphicsEndImageContext();

//    [self.view addSubview:imageViewTwo];

    

    

第三种:使用CAShapeLayer和UIBezierPath设置圆角,设置view.layer.mask,同样会触发离屏渲染。
//    UIImageView *imageView = [[UIImageView alloc]initWithFrame:CGRectMake(100, 100, 100, 100)];

//    imageView.image = [UIImage imageNamed:@"imageName1.jpg"];

//    

//    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];

    

  第四种:混合图层,两个图叠加在一起

用另外一个imageView盖在上面

另引申出:Off-Screen Rendering离屏渲染

是GPU在当前屏幕缓冲区以外新开辟一个缓冲区进行渲染操作。

offscreen-render有两种形式

CPU的offscreen-render

使用CPU来完成渲染操纵,通常在你使用:

  • drawRect (如果没有自定义绘制的任务就不要在子类中写一个空的drawRect方法,因为只要实现了该方法,就会为视图分配一个寄宿图,这个寄宿图的像素尺寸等于视图大小乘以 contentsScale的值,造成资源浪费)
  • 使用Core Graphics
    上面的两种情况使用的就是CPU离屏渲染,首先分配一块内存,然后进行渲染操作生成一份bitmap位图,整个渲染过程会在你的应用中同步的进行,接着再将位图打包发送到iOS里一个单独的进程--render server,理想情况下,render server将内容交给GPU直接显示到屏幕上。
GPU(Graphic Processing Unit)的offscreen-render

使用GPU在当前屏幕缓冲区以外开辟一个新的缓冲区进行绘制,通常发生的情况有:

    • 设置cornerRadius, masks, shadows,edge antialiasing等
    • 设置layer.shouldRasterize = YES

  shouldRasterize打开

  在触发离屏绘制的同时,会将光栅化后的内容缓存起来,如果对应的layer及其sublayers没有发生改变,在下一帧的时候可以直接复用。这将在很大程度上提升渲染性能。

原文地址:https://www.cnblogs.com/Jordandan/p/6183996.html