一句话设置图片圆角,高性能,避免离屏渲染,畅享丝滑

ZHCornerRadius

https://github.com/zhonghphuan/ZHCornerRadius

一句话设置图片圆角,高性能,避免离屏渲染,畅享丝滑_第1张图片
你看"我"还是看文章.jpeg

图片圆角的设置一直是永恒的话题,如果UI工程师不帮我们裁剪圆角,那么您可以用我这个"小小内裤(类库)",一句话设置图片圆角,高性能,避免离屏渲染,畅享丝滑.

How To Use

只需要一句话

imageView.cornerRadius = 25.0;

Note

太简单,无需CocoaPods,直接将分类导入即可.

License:

ZHCornerRadius is released under the MIT license. See LICENSE for details.

讲解部分

离屏渲染概念:当使用圆角,阴影,遮罩的时候,图层属性的混合体被指定为在未预合成之前不能直接在屏幕中绘制,所以就需要屏幕外渲染被唤起。屏幕外渲染并不意味着软件绘制,但是它意味着图层必须在被显示之前在一个屏幕外上下文中被渲染(不论Cpu还是Gpu)。所以当使用离屏渲染的时候会很容易造成性能消耗,因为在OPENGL里离屏渲染会单独在内存中创建一个屏幕外缓冲区并进行渲染,而屏幕外缓冲区跟当前屏幕缓冲区上下文切换是很耗性能的。离屏渲染可以是广义的理解为,在屏幕外的时候就要进行渲染,无论是Cpu还是Gpu,Gpu在处理浮点运算,处理矩阵运算的时候,一定会比Cpu快得,毕竟他天生就是拿来做图形处理的,所以在离屏渲染的数量比较少的时候,我们把运算交给Cpu,反而是略微增加了耗时与卡顿,离屏渲染真正的消耗,在于不同缓冲区的来回切换,一旦圆角的数量增多,计算量加大,这种切换会更加频繁,所以当数量庞大的时候,Gpu最终所有的操作就会更加耗时.

#pragma mark - 绘制圆角核心方法
- (UIImage*)imageAddCornerWithRadius:(CGFloat)radius andSize:(CGSize)size andImage:(UIImage *)image{
    CGRect rect = CGRectMake(0, 0, size.width, size.height);
    UIGraphicsBeginImageContextWithOptions(size, NO, [UIScreen mainScreen].scale);
    CGContextRef ctx = UIGraphicsGetCurrentContext();
    UIBezierPath * path = [UIBezierPath bezierPathWithRoundedRect:rect byRoundingCorners:UIRectCornerAllCorners cornerRadii:CGSizeMake(radius, radius)];
    CGContextAddPath(ctx,path.CGPath);
    CGContextClip(ctx);
    [image drawInRect:rect];
    CGContextDrawPath(ctx, kCGPathFillStroke);
    UIImage * newImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return newImage;
}
#pragma mark - 动态添加属性cornerRadius
- (CGFloat)cornerRadius {
    return [objc_getAssociatedObject(self, _cmd) floatValue];
}

- (void)setCornerRadius:(CGFloat)cornerRadius {
    objc_setAssociatedObject(self, @selector(cornerRadius), @(cornerRadius), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    if (self.image == nil) {
        self.rendering = NO;
        if (!self.addObserver) {
            [[self class] swizzleDealloc];
           // 给动态的属性赋值时kvo观察image的变化
            [self addObserver:self forKeyPath:@"image" options:NSKeyValueObservingOptionNew context:nil];
            self.addObserver = YES;
        }
    }else{
        self.rendering = NO;
        //调用绘制圆角方法接口
        [self addCorner:cornerRadius andImage:self.image];
    }
}

注意:设置圆角根据具体情况设置下光栅化技术避免离屏渲染照成性能问题,
如下代码:

label.layer.shouldRasterize = true 
label.layer.rasterizationScale = layer.contentsScale

CALayer的光栅化选项的开启与否需要我们仔细衡量使用场景。只能用在图像内容不变的前提下的 :

  • 用于避免静态内容的复杂特效的重绘.
  • 用于避免多个View嵌套的复杂View的重绘。
    而对于经常变动的内容,这个时候不要开启,否则会造成性能的浪费。

如有问题,请联系我:[email protected]

你可能感兴趣的:(一句话设置图片圆角,高性能,避免离屏渲染,畅享丝滑)