3

我有一个动画 GIF 成功加载到一个NSDataNSBitmapImageRep对象中。NSBitmapImageRep 参考

我已经想出了如何使用以下方法返回数据,例如该 gif 中的帧数:

NSNumber *frames = [bitmapRep valueForProperty:@"NSImageFrameCount"];

但是,对于如何实际访问该框架作为它自己的对象,我有点困惑。

我认为这两种方法中的一种会有所帮助,但我实际上不确定他们将如何为我获得单独的框架。

+ representationOfImageRepsInArray:usingType:properties:
– representationUsingType:properties:

任何帮助表示赞赏。谢谢

4

3 回答 3

7

我已经想出了如何使用以下方法返回数据,例如该 gif 中的帧数:

NSNumber *frames = [bitmapRep valueForProperty:@"NSImageFrameCount"];

但是,对于如何实际访问该框架作为它自己的对象,我有点困惑。

要访问特殊框架indexOfFrame( 0 <= indexOfFrame < [frames intValue]),您只需设置NSImageCurrentFrame即可。无需使用 CG 功能或复制帧。您可以留在面向对象的 Cocoa 世界中。一个小例子显示了所有 GIF 帧的持续时间:

NSNumber *frames = [bitmapRep valueForProperty:@"NSImageFrameCount"];
if( frames!=nil ){   // bitmapRep is a Gif imageRep
   for( NSUInteger i=0; i<[frames intValue]; i++ ){
      [bitmapRep setProperty:NSImageCurrentFrame
                   withValue:[NSNumber numberWithUnsignedInt:i] ];
       NSLog(@"%2d duration=%@",
                 i, [bitmapRep valueForProperty:NSImageCurrentFrameDuration] );
   }
}

另一个例子:将 GIF 图像的所有帧作为 PNG 文件写入文件系统:

NSNumber *frames = [bitmapRep valueForProperty:@"NSImageFrameCount"];
if( frames!=nil ){   // bitmapRep is a Gif imageRep
   for( NSUInteger i=0; i<[frames intValue]; i++ ){
      [bitmapRep setProperty:NSImageCurrentFrame
                   withValue:[NSNumber numberWithUnsignedInt:i] ];
       NSData *repData = [bitmapRep representationUsingType:NSPNGFileType
                                                 properties:nil];
       [repData writeToFile:
            [NSString stringWithFormat:@"/tmp/gif_%02d.png", i ] atomically:YES];
    }
}
于 2013-06-19T15:28:52.790 回答
2

我已经想出了如何使用以下方法返回数据,例如该 gif 中的帧数:

NSNumber *frames = [bitmapRep valueForProperty:@"NSImageFrameCount"];

但是,对于如何实际访问该框架作为它自己的对象,我有点困惑。

据我所知,你不能——不是来自 NSBitmapImageRep。

相反,从 GIF 数据创建一个 CGImageSource,并使用它CGImageSourceCreateImageAtIndex来提取每个帧(最好根据需要)。

或者,您可以尝试设置NSImageCurrentFrame属性。如果每个帧都需要一个代表,则制作与帧数一样多的副本(减去一个,因为您有原始帧),并将每个代表的当前帧设置为不同的数字。但我还没有尝试过,所以我不确定它是否真的有效。

基本上,NSBitmapImageRep 的 GIF 支持很奇怪,所以你应该只使用 CGImageSource。

我认为这两种方法中的一种会有所帮助,但我实际上不确定他们将如何为我获得单独的框架。

+ representationOfImageRepsInArray:usingType:properties:
– representationUsingType:properties:

不,这些方法用于序列化图像(或图像代表)。它们用于将数据写出,而不是读入。(注意这些方法在其type参数中期望的常量。)

于 2013-06-18T07:32:43.923 回答
1

如果您想查看一些适用于 iOS 的 GIF 解码器的工作源代码(也适用于 MacOSX),那么您可以在 github 找到 AVGIF89A2MvidResourceLoader.m。方法是使用 ImageIO 框架并调用 CGImageSourceCreateWithData() 和 CGI​​mageSourceCreateImageAtIndex() 来访问文件中的第 N 个 gif 图像。但是,有一些棘手的细节与检测 GIF 中是否出现透明像素以及如何将结果写入文件以避免在 GIF 真的很长时内存不足可能不明显。

于 2013-06-18T07:59:17.453 回答