iOS图片设置圆角性能优化

问题

圆角虽好,但如果使用不当,它就是你的帧数杀手,特别当它出现在滚动列表的时候。下面来看圆角如何毁掉你的流畅度的。

实测

layer.cornerRadius

我创建了一个简单地UITableView视图,为每个cell添加了2个UIImageView实例,且为UIImageView实例进行如下设置

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

aImageView.layer.masksToBounds = YES;

运行截图如下:

你们猜,现在滚动的帧率是多少。

已经跌至45帧每秒,这个帧率已经让人感觉到不那么顺滑了,如果低于40帧每秒,普通用户就会察觉明显的不流畅了。当我把cell的UIImageView实例增加至四个

现在帧率已经低于30帧每秒了

这个帧率如果出现在首屏,足以引领你的app进入垃圾级别的体验了。 现在我把UIImageView实例的size调的小一些。

平均帧率提高了大概3帧每秒。

在这里视图和圆角的大小对帧率并没有什么卵影响,数量才是伤害的核心输出啊。

原理

上面拖慢帧率的原因其实都是Off-Screen Rendering(离屏渲染)的原因。离屏渲染是个好东西,但是频繁发生离屏渲染是非常耗时的。

Off-Screen Rendering

屏渲染,指的是GPU在当前屏幕缓冲区以外新开辟一个缓冲区进行渲染操作。由上面的一个结论视图和圆角的大小对帧率并没有什么卵影响,数量才是伤害的核心

输出啊。可以知道离屏渲染耗时是发生在离屏这个动作上面,而不是渲染。为什么离屏这么耗时?原因主要有创建缓冲区和上下文切换。创建新的缓冲区代价都不算

大,付出最大代价的是上下文切换。

上下文切换

下文切换,不管是在GPU渲染过程中,还是一直所熟悉的进程切换,上下文切换在哪里都是一个相当耗时的操作。首先我要保存当前屏幕渲染环境,然后切换到一

个新的绘制环境,申请绘制资源,初始化环境,然后开始一个绘制,绘制完毕后销毁这个绘制环境,如需要切换到On-Screen

Rendering或者再开始一个新的离屏渲染重复之前的操作。 下图描述了一次mask的渲染操作。

次mask发生了两次离屏渲染和一次主屏渲染。即使忽略昂贵的上下文切换,一次mask需要渲染三次才能在屏幕上显示,这已经是普通视图显示3陪耗时,若

再加上下文环境切换,一次mask就是普通渲染的30倍以上耗时操作。问我这个30倍以上这个数据怎么的出来的?当我在cell的UIImageView

的实例增加到150个,并去掉圆角的时候,帧数才跌至28帧每秒。虽然不是甚准确,但至少反映mask这个耗时是无mask操作的耗时的数十倍的。

第一种:设置CALayer的cornerRadius

 imageView.image = [UIImage imageNamed:@"img"];
 imageView.image.layer.cornerRadius = 5;
 imageView.image.layer.masksToBounds = YES;

这样设置会触发离屏渲染,比较消耗性能。比如当一个页面上有十几头像这样设置了圆角

会明显感觉到卡顿。
这种就是最常用的,也是最耗性能的。

注意:ios9.0之后对UIImageView的圆角设置做了优化,UIImageView这样设置圆角
不会触发离屏渲染,ios9.0之前还是会触发离屏渲染。而UIButton还是都会触发离屏渲染。

第二种

imageView.clipsToBounds = YES;
imageView.layer setCornerRadius:50];
imageView.layer.shouldRasterize = YES;

shouldRasterize=YES设置光栅化,可以使离屏渲染的结果缓存到内存中存为位图, 使用的时候直接使用缓存,节省了一直离屏渲染损耗的性能。

但是如果layer及sublayers常常改变的话,它就会一直不停的渲染及删除缓存重新 创建缓存,所以这种情况下建议不要使用光栅化,这样也是比较损耗性能的。

第三种 :通过Core Graphics重新绘制带圆角的视图

这种方式性能最好,但是UIButton上不知道怎么绘制,可以用UIimageView添加个 点击手势当做UIButton使用

@implementation UIImage (CircleImage)

- (UIImage *)drawCircleImage {
   UIGraphicsBeginImageContextWithOptions(self.bounds.size, NO, [UIScreen mainScreen].scale); 
   [[UIBezierPath bezierPathWithRoundedRect:self.bounds cornerRadius:50] addClip];
   [self drawInRect:self.bounds]; 

   UIImage *output = UIGraphicsGetImageFromCurrentImageContext();
   UIGraphicsEndImageContext();
   return output; } @end
//在需要圆角时调用如下
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    UIImage *img = [[UIImage imageNamed:@"image.png"] drawCircleImage];
    dispatch_async(dispatch_get_main_queue(), ^{
        imageView.image = img;
    });
});

四、通过混合图层

此方法就是在要添加圆角的视图上再叠加一个部分透明的视图,只对圆角部分进行遮挡。图层混合的透明度处理方式与mask正好相反。此方法虽然是最优解,没有离屏渲染,没有额外的CPU计算,但是应用范围有限。


总结

  1. 在可以使用混合图层遮挡的场景下,优先使用第四种方法。
  2. 即使是非iOS9以上系统,第一种方法在综合性能上依然强于后两者,iOS9以上由于没有了离屏渲染更是首选。
  3. 方法三由于需要大量计算和增加部分内存,需要实际情况各自取舍。
 
时间: 2024-08-24 19:34:03

iOS图片设置圆角性能优化的相关文章

iOS图片设置圆角

一般我们在iOS开发的过程中设置圆角都是如下这样设置的. imageView.clipsToBounds = YES; [imageView.layer setCornerRadius:50]; 这样设置会触发离屏渲染,比较消耗性能.比如当一个页面上有十几头像这样设置了圆角 会明显感觉到卡顿. 这种就是最常用的,也是最耗性能的. 注意:ios9.0之后对UIImageView的圆角设置做了优化,UIImageView这样设置圆角 不会触发离屏渲染,ios9.0之前还是会触发离屏渲染.而UIBut

Java 图片设置圆角(设置边框,旁白)

/** * 图片设置圆角 * @param srcImage * @param radius * @param border * @param padding * @return * @throws IOException */ public static BufferedImage setRadius(BufferedImage srcImage, int radius, int border, int padding) throws IOException{ int width = srcI

给图片设置圆角和圆形边框,添加点击事件

//1.创建图片 _userImage = [[UIImageView alloc]init]; //2.设置图片圆角 _userImage.layer.cornerRadius = 33; _userImage.layer.masksToBounds = YES; //3.设置圆形边框 CALayer *layer = [_userImage layer]; layer.borderColor = [[UIColor whiteColor] CGColor]; layer.borderWidt

iOS的一些常用性能优化,和内存优化的方法

也是借鉴别人的,感兴趣的可以仔细看看哈 1. 用ARC管理内存 ARC(Automatic ReferenceCounting, 自动引用计数)和iOS5一起发布,它避免了最常见的也就是经常是由于我们忘记释放内存所造成的内存泄露.它自动为你管理retain和release的 过程,所以你就不必去手动干预了.忘掉代码段结尾的release简直像记得吃饭一样简单.而ARC会自动在底层为你做这些工作.除了帮你避免内存泄 露,ARC还可以帮你提高性能,它能保证释放掉不再需要的对象的内存. 2. 在正确的

iOS 中18个性能优化/内存优化常用方法(很常用)

1. 用ARC管理内存 ARC(Automatic ReferenceCounting, 自动引用计数),它避免了最常见的由于我们忘记释放内存所造成的内存泄露.它自动为你管理retain和release的过程,所以你就不必去手动管理了.编写代码的时候很容易忘掉结尾的release.而ARC会自动在底层为你做这些工作.除了帮你避免内存泄露,ARC还可以帮你提高性能,它能保证释放掉不再需要的对象的内存. 2. 在正确的地方使用 reuseIdentifier 一个开发中常见的错误就是没有给UITab

图片帧播放性能优化及音频播放路径

/** *  图片帧播放 */ -(void)animationWithTomImageName:(NSString *)imageName andWithCount:(int)count { if ([self.tomImage isAnimating]) { return;//如果有动画在执行其他动画就不能执行 } NSMutableArray *imageArray = [NSMutableArray array]; for (int i = 0; i < count; i ++) { N

iOS UIView设置圆角

UIView设置圆角 1.比较简单的情况,UIView四个角都是圆角: UIView *aView = [[UIView alloc] init]; aView.frame = CGRectMake(0, 0, 300, 200); aView.backgroundColor = [UIColor redColor]; //设置圆角边框 aView.layer.cornerRadius = 8; aView.layer.masksToBounds = YES; //设置边框及边框颜色 aView

iOS 图片设置为圆角矩形,圆形等

有的时候需要将图片现实为圆形 比如头像等 以下面的图片为例 我们按照正常的方式添加后效果如下 UIImageView *userIconImageV=[[UIImageView alloc]initWithFrame:CGRectMake(30, 120, 188, 188)]; [self.view addSubview:userIconImageV]; userIconImageV.image=[UIImage imageNamed:@"icon_girl.jpg"]; 此时需要用

[转载]网站性能优化之CSS无图片技术 —— 网站性能优化

一.无图片技术定义在不使用CSS Image(通过CSS的引入的背景图片,不包括img标签内的图片)情况下生成类似图片效果的技术:换句话的意思就是在使用纯CSS生成类似图片效果的技术.二.为什么要“无图片”?首先我们通过yslow的statistics查看新浪微博最新版首页的文件,得到Stylesheet File(CSS文件)大小为206.8K, CSS Image大小为623.8K.明显发现CSS文件比CSS Image小很多.当然单纯拿这两个来比,还不能说明什么.下面我们通过计算来说下CS