iOSQuartzCore框架

CATiledLayer方式显示大图

2018-12-19  本文已影响24人  gpylove

        显示大图时,传统加载方法会造成内存暴涨,造成主线程阻塞,甚至造成程序crash。可以使用CATiledLayer显示,CATiledLayer类似瓦片视图,他将需要绘制的内容分割成许多小块,然后异步绘制相应的小块,这样就节约了处理时间和内存。

1,它不需要你自己计算分块显示的区域,它自己直接提供,你只需要根据这个区域计算图片相应区域,然后画图就可以了。

2,它是在其他线程画图,不会因为阻塞主线程而导致卡顿。

3,它自己实现了只在屏幕区域显示图片,屏幕区域外不会显示,而且当移动图片时,它会自动绘制之前未绘制的区域,当你缩放时它也会自动重绘。

        CATiledLayer是为载入大图造成的性能问题提供的一个解决方案,具体如何划分小块和缩放时的加载策略,与CATiledLayer三个重要属性有关:

levelsOfDetail:levelsOfDetail指的是该图层缓存的缩小LOD数目,默认值为1,每进一级会对前一级分辨率的一半进行缓存,图层的levelsOfDetail最大值,对应至少一个像素点。

levelsOfDetailBias:levelsOfDetailBias指的是该图层缓存的放大LODB数目,它是layer的放大级别重绘设置,默认为0,即不会额外缓存放大层次,每进一级会对前一级两倍分辨率进行缓存。

tileSIze:(默认是256x256)tiledSize是layer划分视图区域最大尺寸,主要是影响layer的切片数量。

+ (Class)layerClass {

    return [CATiledLayer class];

}

-(id)initWithFrame:(CGRect)frame image:(UIImage*)img scale:(CGFloat)scale {

    if((self= [superinitWithFrame:frame])) {

        self.image= img;

        _imageRect=CGRectMake(0.0f,0.0f,

                                CGImageGetWidth(self.image.CGImage),

                                CGImageGetHeight(self.image.CGImage));

        _imageScale= scale;

        CATiledLayer*tiledLayer = (CATiledLayer*)[selflayer];

        intlev =ceil(log2(1/scale))+1;

        tiledLayer.levelsOfDetail=1;

        tiledLayer.levelsOfDetailBias= lev;

        //        tiledLayer.tileSize  此处tilesize使用默认的256x256即可

    }

    return self;

}

- (void)drawRect:(CGRect)rect {

    @autoreleasepool{

        CGRectimageCutRect =CGRectMake(rect.origin.x/_imageScale,

                                         rect.origin.y/_imageScale,

                                         rect.size.width/_imageScale,

                                         rect.size.height/_imageScale);

        CGImageRefimageRef =CGImageCreateWithImageInRect(self.image.CGImage, imageCutRect);

        UIImage*tileImage = [UIImageimageWithCGImage:imageRef];

        CGContextRef context = UIGraphicsGetCurrentContext();

        UIGraphicsPushContext(context);

        [tileImagedrawInRect:rect];

        CGImageRelease(imageRef);

        UIGraphicsPopContext();

    }

}

在GitHub上放了一个demo可以下载https://github.com/love1987/LargeImage

上一篇 下一篇

猜你喜欢

热点阅读