dav*_*Mac 23 performance objective-c masking calayer ios
我试图用来CAShapeLayer
掩盖CALayer
我的iOS
应用程序,因为它需要一小部分CPU time
掩盖图像与手动屏蔽一个bitmap context
;
当我有几十个或更多图像叠加在一起时,CAShapeLayer
蒙面UIImageView
很慢移动到我的触摸.
这是一些示例代码:
UIImage *image = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle]pathForResource:@"SomeImage.jpg" ofType:nil]];
CGMutablePathRef path = CGPathCreateMutable();
CGPathAddEllipseInRect(path, NULL, CGRectMake(0.f, 0.f, image.size.width * .25, image.size.height * .25));
for (int i = 0; i < 200; i++) {
SLTUIImageView *imageView = [[SLTUIImageView alloc]initWithImage:image];
imageView.frame = CGRectMake(arc4random_uniform(CGRectGetWidth(self.view.bounds)), arc4random_uniform(CGRectGetHeight(self.view.bounds)), image.size.width * .25, image.size.height * .25);
CAShapeLayer *shape = [CAShapeLayer layer];
shape.path = path;
imageView.layer.mask = shape;
[self.view addSubview:imageView];
[imageView release];
}
CGPathRelease(path);
Run Code Online (Sandbox Code Playgroud)
有了上面的代码,imageView
是非常滞后的.但是,如果我手动屏蔽它,它会立即作出反应bitmap context
:
UIImage *image = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle]pathForResource:@"3.0-Pad-Classic0.jpg" ofType:nil]];
CGMutablePathRef path = CGPathCreateMutable();
CGPathAddEllipseInRect(path, NULL, CGRectMake(0.f, 0.f, image.size.width * .25, image.size.height * .25));
for (int i = 0; i < 200; i++) {
UIGraphicsBeginImageContextWithOptions(CGSizeMake(image.size.width * .25, image.size.height * .25), NO, [[UIScreen mainScreen]scale]);
CGContextRef ctx = UIGraphicsGetCurrentContext();
CGContextAddPath(ctx, path);
CGContextClip(ctx);
[image drawInRect:CGRectMake(-(image.size.width * .25), -(image.size.height * .25), image.size.width, image.size.height)];
UIImage *finalImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
SLTUIImageView *imageView = [[SLTUIImageView alloc]initWithImage:finalImage];
imageView.frame = CGRectMake(arc4random_uniform(CGRectGetWidth(self.view.bounds)), arc4random_uniform(CGRectGetHeight(self.view.bounds)), finalImage.size.width, finalImage.size.height);
[self.view addSubview:imageView];
[imageView release];
}
CGPathRelease(path);
Run Code Online (Sandbox Code Playgroud)
顺便说一句,这里是代码SLTUIImageView
,它只是一个UIImageView
响应触摸的简单子类(对于任何想知道的人):
-(id)initWithImage:(UIImage *)image{
self = [super initWithImage:image];
if (self) {
self.userInteractionEnabled = YES;
}
return self;
}
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
[self.superview bringSubviewToFront:self];
}
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{
UITouch *touch = [touches anyObject];
self.center = [touch locationInView:self.superview];
}
Run Code Online (Sandbox Code Playgroud)
是否有可能以某种方式优化CAShapeLayer
屏蔽效果,UIImageView
从而提高性能?我试图找出瓶颈是使用Time Profiler
的Instruments
,但我不能告诉到底是什么原因造成的.
我已尝试设置shouldRasterize
为YES
on layer
和on,layer.mask
但似乎都没有任何效果.我不知道该怎么做.
编辑:
我做了更多的测试,并发现如果我只使用常规CALayer
来掩盖另一个CALayer (layer.mask = someOtherLayer)
我有相同的性能问题.似乎问题并不是特定于 - CAShapeLayer
它是特定于mask
财产的CALayer
.
编辑2:
因此,在了解了有关使用Core Animation tool
in的更多信息之后Instruments
,我了解到视图每次移动时都会在屏幕外呈现.设置shouldRaster
为YES
触摸开始时和触摸结束时将其关闭使视图保持绿色(从而保持缓存)instruments
,但性能仍然很糟糕.我相信这是因为即使视图被缓存,如果它不是不透明的,那么它仍然必须用每个帧重新渲染.
需要强调的一点是,如果只有少数几个视图被屏蔽(甚至大约十个),那么性能非常好.但是,当你增加它时100 or more
,性能会滞后.我想这是因为当一个人移过其他人时,他们都必须重新渲染.
我的结论是,我有两种选择之一.
首先,必须有一些永久屏蔽视图(渲染一次并称之为好).我知道这可以通过我在示例代码中显示的图形或位图上下文路由来完成,但是当图层屏蔽其视图时,它会立即发生.当我在如图所示的位图上下文中执行时,它非常慢(因为它几乎甚至无法比较它的速度有多慢).
其次,必须有一些faster
方法通过位图上下文路由来完成它.如果有专家屏蔽图像或视图,他们的帮助将非常感谢.
您已经取得了很大的进展,我相信已经快找到解决方案了。我要做的只是你已经尝试过的事情的延伸。既然您说这些图层中的许多“最终”位置相对于其他图层和蒙版保持不变,那么只需将所有这些“完成”图层渲染到单个位图上下文即可。这样,每次您向该单一上下文写入一个图层时,您就可以少一个图层来担心会减慢动画/渲染过程。
归档时间: |
|
查看次数: |
2255 次 |
最近记录: |