iOS开发笔记之六十五——两种截屏方案的对比

******阅读完此文,大概需要3分钟******

业务开发中常常需要截屏生成一张UIView的Image,我们前期就做了一个需要对UIView进行截屏的需求,iOS上截屏的方案有多种,因为我们需要控制图片的分辨率,防止图片过大,所以我们采取了两种方案对UIView进行截屏;

第一种:renderInContext方式,主要代码如下:

- (UIImage *)convertViewToImage:(UIView *)v
{
    @autoreleasepool
    {
        CGSize s = CGSizeMake(v.width, v.height);
        UIGraphicsBeginImageContextWithOptions(s, NO, 2);
        [v.layer renderInContext:UIGraphicsGetCurrentContext()];
        v.layer.contents = nil;
        UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
        return image;
    }
}
记住,当我们把UIView的layer渲染完以后,Layer的contents可以提前释放,这样有利于降低内存峰值。这种截屏方案的原理也有介绍:

/** Rendering properties and methods. **/


/* Renders the receiver and its sublayers into 'ctx'. This method

 * renders directly from the layer tree. Renders in the coordinate space

 * of the layer.

 *

 * WARNING: currently this method does not implement the full

 * CoreAnimation composition model, use with caution. */

renderInContext:方式实际上是通过遍历UIView的layer tree进行渲染,但是它不支持动画的渲染,它的的性能会和layer tree的复杂度直接关联。

第二种:UISnapshotting方式,代码如下:

- (UIImage *)convertViewToImage:(UIView *)v
{
    @autoreleasepool
    {
        CGSize s = CGSizeMake(v.width, v.height);
        UIGraphicsBeginImageContextWithOptions(s, NO, 2);
        [v drawViewHierarchyInRect:v.frame afterScreenUpdates:YES];
        UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
        return image;
    }
}
drawViewHierarchyInRect:afterScreenUpdates:的api是苹果基于UIView的扩展,与第一种方式不同,这种方式是直接获取当前屏幕的“快照”,

所以,此种方式的性能与UIView的frame大小直接关联。

以下是我做的几组性能测试数据:


在UIView内容不是很“长”的情况下,第二种方式有内存优势的;但是随着UIView的内容增加,第二种方式会有较大增加;


第二种因为需要等到UIView的update结束才会去capture,所以时间会慢些。

(以上数据会随着你的测试平台和机型不同,仅供参考。)




猜你喜欢

转载自blog.csdn.net/lizitao/article/details/74857890
今日推荐