iOS CATiledLayer大图加载

  • 内存暴增
    以加载一张7033 × 10110的图片为例,解压缩生成的bitmap可高达7033101104/1024/1024 = 271M。
    如果直接用UIKit-setImage方法对ImageView.image赋值,app占用内存会由60多MB激增到323MB。3

  • CATiledLayer
    CATiledLayer是继承于CALayer的方片图层,可以利用其对图片进行分片绘制。


@interface LargeImageView(){
    UIImage *originImage;
    CGFloat imageScale;
}

@end
@implementation LargeImageView

- (void)setImage:(UIImage *)image {
	originImage = image;
    [self setBackgroundColor:[UIColor whiteColor]];
    imageScale = self.frame.size.width/image.size.width;
    int lev = ceil(log2(1/imageScale))+1;
    CATiledLayer *tiledLayer = (CATiledLayer *)[self layer];
    tiledLayer.levelsOfDetail = 1;
    tiledLayer.levelsOfDetailBias = lev;
}

+ (Class)layerClass {
    return [CATiledLayer class];
}

- (void)drawRect:(CGRect)rect {
    @autoreleasepool{
        CGRect imageCutRect = CGRectMake(rect.origin.x / imageScale,
                                         rect.origin.y / imageScale,
                                         rect.size.width / imageScale,
                                         rect.size.height / imageScale);
        CGImageRef imageRef = CGImageCreateWithImageInRect(originImage.CGImage, imageCutRect);
        UIImage *tileImage = [UIImage imageWithCGImage:imageRef];
        CGContextRef context = UIGraphicsGetCurrentContext();
        UIGraphicsPushContext(context);
        [tileImage drawInRect:rect];
        CGImageRelease(imageRef);
        UIGraphicsPopContext();
    }
}
@end

加载效果:
在这里插入图片描述
CATiledLayer背后采用了多线程对图片进行绘制,cpu使用率会明显提升,逐个区域绘图也降低了内存峰值。

在这里插入图片描述

CATiledLayer主要属性:

tileSize:在绘制视图层时,将View分割成最大不超过tileSize指定的尺寸,然后调用drawRect方法逐个区域绘制。默认是{256 , 256}

以一张尺寸7033 × 10110的图片为例。

设置tilesize为{7033 , 10110},其实相当于整张图片加载,跟不使用TiledLayer差不多,内存峰值可达235MB。
在这里插入图片描述
设置tilesize为{500 , 500},内存峰值明显下降了不少,即72.4MB。
在这里插入图片描述
设置tilesize为{200 , 200},内存峰值会下降到66.7MB
在这里插入图片描述
CATiledLayer可以进行逐个区域绘制,明显减少内存的占用,缓解了内存压力。

levelsOfDetail:缩小图片时的层级数量,即图片可以缩小到最大缩小级别,每一级是上一级的 1/2。
levelsOfDetailBias:放大图片时的层级数量,即图片可以缩小到最大放大级别,每一级是上一级的 2倍。

CATiledLayer可以配合UIScrollView来进行图片的缩放。
levelsOfDetailBias 不指定的话,设置levelsOfDetail=n,则CATiledLayer 将会在 UIScrollView 的 zoomScale 为以下数字时进行重绘:2^-1 -> 2^-2 -> … -> 2^-n。也就是 1/2, 1/4, 1/8, 1/16, … , 1/2^n。
所以,在levelsOfDetailBias 不指定的话,zoomScale大于0.5就不再重绘图片,图片也会变得越来越模糊。

因此就需要对levelsOfDetailBias进行设置,当设置levelsOfDetailBias=m,levelsOfDetail=n,则CATiledLayer 将会在 UIScrollView 的 zoomScale 为以下数字时进行重绘: 2^m * 2^-1 -> 2^m * 2^-2 -> … -> 2^m * 2^-n
即: 2^(m – 1) -> 2^(m – 2) -> 2^(m – 3) ->… -> 2^(m – n)
可简单理解成:
levelsOfDetail表示一共有多少个drawLayer的位置
levelsOfDetailBias表示比1大的位置里有多少个drawLayer的位置(包括1)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值