我正在尝试动画一些图像。这些图像在非视网膜iPad上运行良好,但它们的视网膜对应物很慢,并且动画不会以指定的速率循环。我正在使用的代码如下所示,每隔1/25秒调用一次。此方法的效果似乎优于UIViewAnimations
。
if (counter < 285) {
NSString *file = [[NSBundle mainBundle] pathForResource:[NSString stringWithFormat:@"Animation HD1.2 png sequence/file_HD1.2_%d", counter] ofType:@"png"];
@autoreleasepool {
UIImage *someImage = [UIImage imageWithContentsOfFile:file];
falling.image = someImage;
}
counter ++;
} else {
NSLog(@"Timer invalidated");
[timer invalidate];
timer = nil;
counter = 1;
}
}
我意识到有很多图像,但是帧数较少的动画的性能相同。就像我说的那样,非视网膜动画效果很好。上面的每张图片大约是90KB。我做错了什么或者这仅仅是iPad的限制?说实话,我觉得很难相信当它可以处理复杂的3D游戏时它无法处理这样的东西,所以我想我做错了。任何帮助将不胜感激。
编辑1:
从下面的答案中,我编辑了我的代码,但无济于事。执行以下代码会导致设备崩溃。
viewDidLoad
中的
NSString *fileName;
myArray = [[NSMutableArray alloc] init];
for(int i = 1; i < 285; i++) {
fileName = [NSString stringWithFormat:@"Animation HD1.2 png sequence/HD1.2_%d.png", i];
[myArray addObject:[UIImage imageNamed:fileName]];
NSLog(@"Loaded image: %d", i);
}
falling.userInteractionEnabled = NO;
falling.animationImages = humptyArray;
falling.animationDuration = 11.3;
falling.animationRepeatCount = 1;
falling.contentMode = UIViewContentModeCenter;
动画方法
-(void) triggerAnimation {
[falling startAnimating];
}
答案 0 :(得分:11)
首先,视网膜iPad上的动画表现非常不稳定。也就是说,您可以采取一些措施来确保您的动画获得最佳效果(无特定顺序)。
预加载图像 - 正如其他人提到的那样,在绘制图像之前必须等待读取图像时,动画速度会受到影响。如果你使用UIImageView的动画属性,这个预加载将自动处理。
使用正确的图像类型 - 尽管文件大小有优势,但使用JPEG而不是PNG会大幅降低动画速度。 PNG压缩程度较低,系统更容易解压缩。此外,Apple还显着优化了用于阅读和绘制PNG图像的iOS系统。
减少混合 - 如果可能,请尝试从动画图像中删除任何透明度。确保图像中没有Alpha通道,即使它看起来完全不透明。您可以通过在“预览”中打开图像并打开检查器来进行验证。通过减少或删除这些透明像素,可以消除系统在显示图像时必须执行的额外渲染过程。这可以产生显着的差异。
使用GPU支持的动画 - 建议您不要使用当前使用计时器为图像设置动画的方法,以获得最佳性能。通过不使用UIViewAnimation或CAAnimation,您强制CPU执行大部分动画工作。 Core Animation和UIViewAnimation的许多动画技术都经过OpenGL优化和支持,OpenGL使用GPU处理图像和动画。图形处理就是GPU的制作过程,利用它可以最大限度地提高动画效果。
避免像素不对齐 - 在显示动画图像时,请确保动画图像的大小合适。如果在动画或使用不正确的帧时拉伸图像,系统必须执行更多工作来处理每个帧。此外,当系统尝试将图像定位在小数像素上时,对任何帧或点值使用整数将避免抗锯齿。
警惕阴影和圆角 - CALayer有很多简单的方法可以创建阴影和圆角,但如果要在动画中移动这些图层,系统通常会重绘动画每帧中的图层。使用shadowOffset属性指定阴影时就是这种情况(使用UILabel的阴影属性不会渲染每一帧)。此外,边框和使用maskToBounds和clipToBounds将更加注重性能,而不仅仅是使用图像编辑器来裁剪实际资产。
答案 1 :(得分:0)
这里有几点需要注意:
如果“下降”是UIImageView,请确保它的内容模式说“中心”而不是某种缩放(当然,确保你的图像适合它)。
除此之外,正如@FogleBird所说,测试您的设备是否有足够的内存来预加载所有图像,如果没有,请尝试通过使用图像文件创建NSData对象来至少预加载数据。
您对@autorelease池的使用不是很有用,您最终会创建一个自动释放对象来执行单个操作 - 删除对已保留对象的引用 - 没有内存增益,但性能损失。
如果有的话,你应该包装文件名格式化程序代码,并且考虑到这个方法是由NSTimer调用的,它已经包装在自动释放池中。
答案 2 :(得分:0)
只想指出 - 当您使用图像名称创建NSString时 - 什么是“动画HD1.2 png序列/ HD1.2_%d.png”?
看起来你正试图在那里设置路径,只尝试图像名称 - 例如。 “HD1.2_%d.png”。