美文网首页
[iOS]UIImageView增加圆角及性能比较,有待考证

[iOS]UIImageView增加圆角及性能比较,有待考证

作者: 762683ff5d3d | 来源:发表于2019-01-08 17:18 被阅读0次
  1. SDWebImage处理图片时Core Graphics绘制圆角
  //UIImage绘制为圆角
  int w = imageSize.width;
  int h = imageSize.height;
  int radius = imageSize.width/2;

  UIImage *img = image;
  CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
  CGContextRef context = CGBitmapContextCreate(NULL, w, h, 8, 4 * w, colorSpace, kCGImageAlphaPremultipliedFirst);
  CGRect rect = CGRectMake(0, 0, w, h);

  CGContextBeginPath(context);
  addRoundedRectToPath(context, rect, radius, radius);
  CGContextClosePath(context);
  CGContextClip(context);
  CGContextDrawImage(context, CGRectMake(0, 0, w, h), img.CGImage);
  CGImageRef imageMasked = CGBitmapContextCreateImage(context);
  img = [UIImage imageWithCGImage:imageMasked];

  CGContextRelease(context);
  CGColorSpaceRelease(colorSpace);
  CGImageRelease(imageMasked);
  1. (https://github.com/syik/UIImageView-ZJRadius/blob/master/UIImageView%2BZJRadius.m)
- (void)ZJ_setImage:(UIImage *)image{
    
    if ([self.orginImage isEqual:image] || !image) {
        return;
    };
    self.orginImage = image;
    
    if (self.layer.cornerRadius > 0 && self.isClipsCorner) {
        [self ZJ_clipsImage:image];
    } else {
        [self ZJ_setImage:image];
    }
}


- (void)ZJ_clipsImage:(UIImage *)image{
    
    //创建一个的layer显示
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        
        /*
        UIImageView *imageView;
        for (UIView *subView in self.subviews) {
            if (subView.tag == 10241024) {
                imageView = (UIImageView *)subView;
                break;
            }
        }
        
        if (!imageView) {
            imageView = [[UIImageView alloc] initWithFrame:self.bounds];
            imageView.userInteractionEnabled = NO;
            imageView.opaque = YES;
            imageView.tag = 10241024; //标记
            
            dispatch_async(dispatch_get_main_queue(), ^{
                [self addSubview:imageView];
            });
        }
        */
        
        UIColor *orginColor = self.backgroundColor;
        self.backgroundColor = [UIColor clearColor];
        
        CGSize size = CGSizeMake(self.layer.cornerRadius * 2, self.layer.cornerRadius * 2);
        CGRect rect = CGRectMake(0, 0, size.width, size.height);
        
        UIGraphicsBeginImageContextWithOptions(size, NO, 0);
        
        UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:rect];
        [path addClip];
        
        [image drawInRect:rect];
        
        UIImage *drawImage = UIGraphicsGetImageFromCurrentImageContext();
        
        UIGraphicsEndImageContext();
        self.backgroundColor = orginColor;
    
        dispatch_async(dispatch_get_main_queue(), ^{
            [self ZJ_setImage:drawImage];
        });
    });
}

[iOS]UIImageView增加圆角

"如何给一个UIImageView增加圆角?有几种方法?各自区别?"

备注:本文参考自http://www.jianshu.com/p/d1954c9a4426

UIImageView *poImgView = [[UIImageView alloc]init];

方案A(基本方案):

poImgView.layer.cornerRadius = poImgView.frame.size.width/2.0;

poImgView.layer.masksToBounds = YES;
(或者 poImgView.clipsToBounds = YES;)

备注:clipsToBounds是对view的切割,masksToBounds是对layer的切割

性能消耗:
这个是离屏渲染(off-screen-rendering),对性能消耗比较大
fps大致在45帧左右(每个cell 做2个imageview)

正常fps是60帧,越小,用户体验越差

|

离屏渲染,指的是GPU在当前屏幕缓冲区以外新开辟一个缓冲区进行渲染操作。由上面的一个结论视图和圆角的大小对帧率并没有什么卵影响,数量才是伤害的核心输出啊。可以知道离屏渲染耗时是发生在离屏这个动作上面,而不是渲染。为什么离屏这么耗时?原因主要有创建缓冲区和上下文切换。创建新的缓冲区代价都不算大,付出最大代价的是上下文切换。

方案B:

CAShapeLayer *layer = [CAShapeLayer layer];  
UIBezierPath *aPath = [UIBezierPath bezierPathWithOvalInRect:aImageView.bounds];  
layer.path = aPath.CGPath;  
poImgView.layer.mask = layer;

性能消耗:
测试fps大致在20帧左右,比方案A的消耗更大

方案C:

- (UIImage *)imageWithCornerRadius:(CGFloat)radius {
CGRect rect = (CGRect){0.f, 0.f, self.size};

UIGraphicsBeginImageContextWithOptions(self.size, NO, UIScreen.mainScreen.scale);
CGContextAddPath(UIGraphicsGetCurrentContext(),
 [UIBezierPath bezierPathWithRoundedRect:rect cornerRadius:radius].CGPath);
CGContextClip(UIGraphicsGetCurrentContext());

[self drawInRect:rect];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();

UIGraphicsEndImageContext();

return image;
}

性能消耗:
这个是on-screen-rendering
相当于时时去做渲染,相比于A.B方案的离线渲染,此方法对性能消耗最低,推荐用此方案。

说明

方案A和方案B都是比较常见的方式,但是都不推荐,对此的优化方案是是用C,但是如果费用使用A或者B方案,补救措施是:

1.栅格化:将cell的所有内容生成一张独立的图像,在屏幕滚动时,只显示图像;这将隐式的创建一个位图,各种阴影遮罩等效果也会保存到位图中并缓存起来,从而减少渲染的频度(不是矢量图);这个命令会让视图渲染的内容被缓存下来,下一次绘制的时候直接显示缓存。

self.layer.shouldRasterize = YES;

2.指定分辨率,否则默认使用 *1 的图像,需要指定和屏幕相匹配的分辨率

self.layer.rasterizationScale = [UIScreen mainScreen].scale;

相关文章

网友评论

      本文标题:[iOS]UIImageView增加圆角及性能比较,有待考证

      本文链接:https://www.haomeiwen.com/subject/hjwzjftx.html