3

我正在尝试将大量 UIImage 存储到一个文件中并读取它。我正在考虑的选项是:

  1. 将图像转换为 NSData 并将每个图像保存到相应的文件(“1.png”、“2.png”等),然后再读取它们。
  2. 将图像转换为 NSData 并保存到一个大文件中,并将每个图像的开始位置存储在文件中。然后稍后打开文件并使用 NSFileHandle 的 seekToFileOffset 读取它们。

我正在考虑选项 2 的原因是因为我正在尝试使用这些图像实现动画。我不确定一次打开一个图像是否足够快以制作高帧率动画。还有可能有更好的方法我还不知道。我将不胜感激任何建议。谢谢!

4

6 回答 6

2

iOS 5 在 UIImage 上有一个支持图像序列的方法。

+ (UIImage *)animatedImageNamed:(NSString *)name duration:(NSTimeInterval)duration

该方法的使用文档在这里:

http://developer.apple.com/library/ios/#documentation/UIKit/Reference/UIImage_Class/Reference/Reference.html

于 2013-05-29T19:58:33.927 回答
2

其他选择可能是

  1. 您可以缓存图像并同时将其文件路径存储在 plist 文件中,并在必要时访问它。

它只是另一个建议考虑一下!

于 2013-04-18T04:24:09.783 回答
0

你没有提到你想做动画的原因。那么在黑暗中拍摄,您是否考虑过使用 Cocos 2D 制作动画?这里有一个很棒的教程:

http://www.raywenderlich.com/32045/how-to-use-animations-and-sprite-sheets-in-cocos2d-2-x

于 2013-05-30T01:19:06.687 回答
0

无需过早地对其进行优化。

最简单且可能是最好的解决方案是为您上面提到的图像制定命名约定。我实际上会在帧号的左侧添加零,这样你也可以处理更高的帧数。

即IMG_0001.png、IMG_0002.png等

使用第一个图像创建一个 UIImageView 并创建一个 frameIndex 变量,您将使用它来跟踪当前动画帧并加载正确的图像。

然后安排一个 NSTimer 以您想要的速率运行(即 1/15 == 15FPS、1/30 == 30FPS 等),并在每次 NSTimer 调用选择器时将 UIImageView 上的当前图像替换为新图像。

这是一个简单的例子:

- (void)startAnimation
{
    self.currentFrame = 0;
    self.animationTimer = [NSTimer scheduledTimerWithTimeInterval:1/30.f
                                                           target:self
                                                         selector:@selector(_switchImage:)
                                                         userInfo:nil
                                                          repeats:YES];
}

然后在_switchImage方法上:

- (void)_switchImage:(NSTimer*)timer
{
    NSString *filename = [NSString stringWithFormat:@"IMG_%04i", self.currentFrame];
    NSString *fullPath = [[NSBundle mainBundle] pathForResource:filename ofType:@"png"];
    @autoreleasepool {
        UIImage *image = [UIImage imageWithContentsOfFile:fullPath];
        if (image) {
            self.animationImageView.image = image;
            self.currentFrame = self.currentFrame + 1;
            // If for any reason we reach the last animation frame, loop back to the beginning of the animation
            if (self.currentFrame > kLastAnimationFrame)
                self.currentFrame = 0;
        }
    }
}
于 2013-04-18T06:40:15.860 回答
0

有趣的。听起来你需要研究一些解决方案......我认为这完全取决于图像的数量、它们的大小、你希望它们出现的帧速率等

从最简单的解决方案开始,逐步解决,直到找到合适的解决方案。

加入另一种解决方案(不是最简单的)。多合一文件的一种变体。您可以使用[NSData dataWithContentsOfMappedFile:]它绕过文件的读取(通过缓冲区传递内容)并提供对字节的直接内存访问。

请注意,此方法在 iOS5 中已被弃用,dataWithContentsOfFile:建议作为替代方法,NSDataReadingMappedAlways它的大哥的选项似乎是使用什么

内存映射文件可以提供有趣的功能。一旦我使用http://www.memention.com/blog/2011/05/04/That-old-thing.html编写了一个文件qsort()排序mmap()

于 2013-05-29T20:12:20.797 回答
-1

另一种选择是: 1. 创建数据库文件并将所有图像加载到其中。2.在安装时将数据库文件从assets文件夹复制到documents文件夹(如果使用phonegap/jquery,如果不是,我认为还有其他方法可以做到)。3. 现在您可以在需要时使用图像,因为(只是猜测)数据库访问比文件访问快。

于 2013-04-18T06:19:19.983 回答