不使用 MPMoviePlayer 在 iPhone 上动画图像(如电影)的方法

Posted

技术标签:

【中文标题】不使用 MPMoviePlayer 在 iPhone 上动画图像(如电影)的方法【英文标题】:Method for animating images (like a movie) on iPhone without using MPMoviePlayer 【发布时间】:2009-01-14 06:18:13 【问题描述】:

我需要能够在静态图像上显示动画。

鉴于 MPMoviePlayer 无法让您控制任何有用的东西,我能想到的唯一方法是使用多个静态图像,我们会(一个接一个地)显示这些图像来创建“类似电影”的动画。

我知道我们可以使用 UIImageView 来执行此操作(通过设置 UIImageView animationImages 属性,然后调用 startAnimation),但是我们将在我们的动画 - 所以内存使用将被最大化。

有没有人有什么好的方法来制作这种动画?使用核心动画还是 OpenGL?

我的猜测是我们需要创建一个图像缓冲区,当我们加载新图像时,我们会显示图像缓冲区中的图像??

【问题讨论】:

【参考方案1】:

您可以使用核心动画 CALayer 来托管您的动画,并在主层内外交换一系列 CALayer 来执行逐帧动画。您可以使用其内容属性将图像帧托管 CALayer 的内容设置为 CGImageRef。可以根据需要创建一系列包含您的图像的 CALayer 并将其存储在 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。

【讨论】:

您能否详细说明您的答案或尝试回答这个***.com/questions/18955031/…【参考方案2】:

正如您所发现的,使用 UIImageView.animationImages 不起作用,因为它会耗尽您的所有系统内存并会使您的应用程序崩溃。您可以使用计时器并在每次计时器触发时设置 UIImageView 的图像属性,每次计时器触发时都需要加载用作内容的 UIImage 对象。这与另一个答案中描述的方法基本相同,只是它使用 CALayer 而不是 UIImageView。每次计时器触发时加载图像并更改图像内容是一种不错的方法,但它只能在 iPhone 上获得大约 11 FPS 的全屏图像。

如果您想使用实现 UIImageView 切换逻辑的工作示例,请下载此 PNG Animation xcode 示例项目。我还提供了AVAnimator 库,这是同类功能的优化版本,它支持 Quicktime 动画和 APNG 格式以及压缩。

【讨论】:

【参考方案3】:

您可以使用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

【讨论】:

【参考方案4】:

对于序列中的动画图像,

首先拍摄一组你需要播放的图像。

然后把这个数组交给动画就完成了。

井解释Animation in Iphone: Series of images

【讨论】:

以上是关于不使用 MPMoviePlayer 在 iPhone 上动画图像(如电影)的方法的主要内容,如果未能解决你的问题,请参考以下文章

MPMoviePlayer 声音在模拟器和 ipad 设备中工作,但在 iPhone 设备中不工作

iPhone开发mpmovieplayer崩溃

横向模式下的 iPhone MPMoviePlayer

我应该在 MPMoviePlayer 示例代码(适用于 iphone)中做出哪些区别才能使其在 Ipad 中工作?

删除/清除以前的缓冲区/流视频 mpmovieplayer iphone

iPhone:MPMoviePlayer 最初在几分之一秒内显示黑色背景