我需要能够在静态图像上显示动画。
鉴于MPMoviePlayer无法控制任何有用的东西,我能想到的唯一方法就是使用多个静态图像,我们会逐一显示这些图像以创建“类似电影”的动画。 / p>
我知道我们可以使用UIImageView来执行此操作(通过设置UIImageView animationImages 属性,然后调用 startAnimation ),但是我们将在我们的动画 - 因此内存使用量将被最大化。
有没有人有很好的方法来做这种动画?使用Core Animation还是OpenGL?
我的猜测是我们需要创建一个图像缓冲区,当我们加载新图像时,我们会显示图像缓冲区中的图像吗?
答案 0 :(得分:6)
您可以使用Core Animation CALayer来托管您的动画,并将一系列CALayer交换进出该主图层以执行逐帧动画。您可以使用其contents属性将图像框架托管CALayer的内容设置为CGImageRef。可以根据需要创建包含图像的一系列CALayers并将其存储在NSMutableArray中,然后在完成时删除以最小化内存使用。
您可以通过在CATransaction中包装replaceSublayer:with:方法调用来设置帧之间的转换持续时间,如下所示:
[CATransaction begin];
[CATransaction setValue:[NSNumber numberWithFloat:0.25f] // 1/4th of a second per frame
forKey:kCATransactionAnimationDuration];
[mainLayer replaceSublayer:[imageLayers objectAtIndex:oldImageIndex] with:[imageLayers objectAtIndex:newImageIndex]];
[CATransaction commit];
如果你的画面显示时间足够短,你也可以在主图层的内容中交换进出CGImageRef。
答案 1 :(得分:1)
正如您所发现的那样,使用UIImageView.animationImages不起作用,因为它会耗尽您的所有系统内存并导致应用程序崩溃。您可以使用计时器并在每次计时器触发时设置UIImageView的image属性,每次计时器触发时都需要加载用作内容的UIImage对象。这与其他答案中描述的方法基本相同,只是它使用CALayer而不是UIImageView。每次定时器触发时加载图像并更改图像内容是一种好的方法,但它只能在iPhone上获得大约11 FPS的全屏图像。
如果您想使用实现UIImageView切换逻辑的工作示例,请下载此PNG Animation示例项目以获取xcode。我还提供AVAnimator库,它支持相同类型的功能的优化版本 Quicktime Animation和APNG格式以及压缩。
答案 2 :(得分:1)
您可以使用 CAKeyframeAnimation
为一系列图像制作动画/像电影一样播放图像。
//Get UIImage array
NSMutableArray<UIImage *> *frames = [[NSMutableArray alloc] init];
[frames addObject:[UIImage imageNamed:@"1"]];
[frames addObject:[UIImage imageNamed:@"2"]];
[frames addObject:[UIImage imageNamed:@"3"]];
[frames addObject:[UIImage imageNamed:@"4"]];
[frames addObject:[UIImage imageNamed:@"5"]];
//Declare an array for animationSequenceArray
NSMutableArray *animationSequenceArray = [[NSMutableArray alloc] init];
//Prepare animation
CAKeyframeAnimation *animationSequence = [CAKeyframeAnimation animationWithKeyPath: @"contents"];
animationSequence.calculationMode = kCAAnimationDiscrete;
animationSequence.autoreverses = YES;
animationSequence.duration = 5.00; // Total Playing duration
animationSequence.repeatCount = HUGE_VALF;
for (UIImage *image in frames) {
[animationSequenceArray addObject:(id)image.CGImage];
}
animationSequence.values = animationSequenceArray;
//Prepare CALayer
CALayer *layer = [CALayer layer];
layer.frame = self.view.frame;
layer.masksToBounds = YES;
[layer addAnimation:animationSequence forKey:@"contents"];
[self.view.layer addSublayer:layer]; // Add CALayer to your desired view
答案 3 :(得分:0)