iOS上的圆形头像和性能问题

时间:2012-07-04 00:09:07

标签: ios performance uiimage drawrect

有没有办法在不执行以下任何操作的情况下绘制圆形UIImages?

  1. 混合(核心动画乐器中的红色)
  2. 离线渲染(核心动画乐器中的黄色)
  3. 的drawRect
  4. 我试过

    1. drawRect与剪切路径。这太慢了。 (见:http://developer.apple.com/library/ios/#qa/qa1708/_index.html
    2. 使用maskLayer的CALayer内容。这引入了屏幕外渲染。
    3. UIImageView并设置cornerRadius和masksToBounds。这与#2具有相同的效果。
    4. 我的最后一招是直接修改图像。有什么建议吗?

2 个答案:

答案 0 :(得分:3)

我使用blog.sallarp.com's rounded corners algorithm的变体。我修改了我的只是围绕某些角落,它是一个无缝集成的类别,但该链接为您提供了基本的想法。我认为这可能有资格作为“屏幕外渲染”,这是你拒绝的技术之一,但我并不完全确定。我从未见过任何可观察到的性能问题,但也许你有一些特殊的情况。

您可以覆盖图像视图顶部角落的图像视图,以获得圆角的外观吗?

或者,如果您担心因四舍五入而导致的性能损失,为什么不让您的应用保存带有圆角的图像副本,这样您只能在第一时间获得性能?它等同于你“直接修改图像”的概念,但是及时进行。

<强>更新

最重要的是,我不知道任何其他解决方案(缺少我的kludgy想法,下面的第2点)。但我做了一些实验(因为我正在处理类似的问题)并得出以下结论:

  1. 如果您在3GS或更高版本的设备上具有舍入性能,则问题可能不在于拐角处。我发现虽然它对3G上的UI产生了重大影响,但在3GS上几乎没有引起注意,而在以后的设备上它是不可思议的。如果您从圆角处看到性能问题,请确保它是圆角而不是其他东西。我发现,如果我在以前缓存的图像上进行了即时舍入,那么舍入的影响可以忽略不计。 (当我在缓存之前进行舍入时,UI就像丝绸一样光滑。)

  2. 掩蔽的另一种方法是创建一个圆角反转的图像(即它与角落中的背景相匹配,透明,您希望图像显示在哪里),然后放置此图像在tableviewcell的图像前面。我发现,为了这个工作,我不得不使用一个自定义单元格(例如创建我自己的主图像视图控件,我自己的标签,加上这个角落蒙版图像视图控件),但它绝对比刚准时更好调用拐角舍入算法。如果你试图在分组表中对角进行圆角处理,这可能效果不好,但是如果你只是想要圆角的外观而不实际将它们四舍五入,这可能是一个可爱的小黑客。

  3. 如果您正在使用分组的桌面视图而使角落变圆,并且您不希望图像溢出圆角,则可以简单地围绕第一行图像的左上角和下方最后一张图片的左下角。这将减少转角舍入逻辑的调用。它看起来也不错。

  4. 我知道您没有询问此问题,但有关图表视图中其他可能出现的性能问题包括:

    • 如果您在imageWithContentsOfFile中使用cellForRowAtIndexPath(不缓存)之类的内容,您肯定会看到性能问题。如果你无法利用imageNamed缓存(并且有些人抱怨它,无论如何),你可以自己缓存你的图像,或者是及时缓存你的图像,或者在二级线程上预先加载它们。如果你的桌面视图引用了之前加载的图像,你会看到巨大的性能提升,那么角落的圆角可能会或可能不会成为一个问题。

    • 其他性能问题来源包括使用尺寸不适合tableview的imageview的图像。大图像对性能产生了巨大影响。

  5. 底线,

    • 在此处自杀之前,请确保四舍五入是唯一的性能问题。如果您在当代硬件上看到问题,尤其如此,因为根据我的经验,影响可以忽略不计。另外,如果更广泛的解决方案会更好,那么在这方面失去太多睡眠将是一种耻辱。使用不是尺寸优化缩略图的图像,无法缓存图像等,都会对性能产生巨大影响。

    • 如果可能的话,提前围绕图像的角落,UI将是最好的,并且视图控制器代码将是美观和简单的。

    • 如果你不能提前做(因为你实时下载图像),你可以尝试角落遮蔽图像技巧,但这只适用于某些情况(尽管非分组tableview就是其中之一。)

    • 如果您在UI进行时必须进行圆角处理,请在单独的队列中进行圆角舍入,并且不要阻止UI。

答案 1 :(得分:1)

这就是我的工作,我对它的表现感到满意:

UIImageView *iv=[[UIImageView alloc] initWithImage:[UIImage imageNamed:@"769-male"]];
UIGraphicsBeginImageContextWithOptions(iv.bounds.size, NO, [UIScreen mainScreen].scale);
[[UIBezierPath bezierPathWithRoundedRect:v.bounds cornerRadius:s] addClip];
[image drawInRect:v.bounds];
v.image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();