如何在iOS中生成24位真彩色动画GIF?

我想从几个表示为base64字符串的PNG文件中生成一个真彩色动画Gif。 我找到了这篇文章并做了类似的事情。 我有一个dataUrls数组:

NSArray* imageDataUrls; // array with the data urls without data:image/png;base64, prefix 

这是我做的:

  NSDictionary *fileProperties = @{ (__bridge id)kCGImagePropertyGIFDictionary: @{ (__bridge id)kCGImagePropertyGIFLoopCount: @0, // 0 means loop forever } }; NSDictionary *frameProperties = @{ (__bridge id)kCGImagePropertyGIFDictionary: @{ (__bridge id)kCGImagePropertyGIFDelayTime: @0.4f, // a float (not double!) in seconds, rounded to centiseconds in the GIF data } }; NSURL *documentsDirectoryURL = [[NSFileManager defaultManager] URLForDirectory:NSDocumentDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:YES error:nil]; NSURL *fileURL = [documentsDirectoryURL URLByAppendingPathComponent:@"animated.gif"]; CFMutableDataRef destinationData = CFDataCreateMutable(kCFAllocatorDefault, 0); CGImageDestinationRef destination = CGImageDestinationCreateWithData(destinationData, kUTTypeGIF, kFrameCount, NULL); CGImageDestinationSetProperties(destination, (__bridge CFDictionaryRef)fileProperties); NSData* myImageData; UIImage *myImage = [UIImage alloc]; for (NSUInteger i = 0; i < kFrameCount; i++) { @autoreleasepool { myImageData = [NSData dataFromBase64String:[imageDataUrls objectAtIndex:i]]; myImage = [myImage initWithData: myImageData]; CGImageDestinationAddImage(destination, myImage.CGImage, (__bridge CFDictionaryRef)frameProperties); } } myImageData = nil; myImage = nil; CFRelease(destination); NSData* data = nil; data = (__bridge NSData *)destinationData; 

最后,我将gif图像作为base64EncodedString发送回phonegap容器。

 // send back gif image CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString: [data base64EncodedString]]; 

它工作得很好但是生成的gif图像的质量很差。 这是因为它只有256种颜色。

这是原始的png图像:

在此处输入图像描述

以下是生成的gif图像的屏幕截图:

在此处输入图像描述

如何获得与导入相同的质量,即如何提高生成的gif的质量等级? 如何在iOS上生成真彩色GIF?

GIF不是为存储真彩色数据而设计的,它们也不适合动画1 。 由于这是GIF的一种不寻常的使用,你必须编写很多自己的代码。

  1. 将每个帧分成矩形块,其中每个块包含最多256种不同的颜色。 最简单的方法是使用16×16块。

  2. 将每个块转换为索引图像。

  3. 将每个块添加到GIF。 对于帧中的第一个块,请使用帧延迟。 对于帧中的其他块,请使用0的延迟。

完成。 您必须熟悉GIF规范,该规范可在线免费获取( W3.org上的GIF89a规范 ,请参阅第23节)。 你还需要找一个LZW压缩机,这个压缩机并不难找。 动画还将使用一个淫秽的存储空间:包括base64转换,我估计大约43位/像素,或720pvideo大约1.2 Gbit / s,这是你用于高质量MPEG4的存储量的400倍或者WebM,可能是PNG所需存储量的3倍。 除非动画非常短且很小,否则存储和带宽要求可能会给主机和客户带来不必要的成本。

请注意,这不允许您使用Alpha透明度,这是GIF格式的硬性限制。

意见

将高质量动画放入GIF中的想法在极端情况下是荒谬的,即使它是可能的。 鉴于可用的替代方案,这是特别荒谬的:

  • 如果您的目标是现代浏览器或移动设备,MPEG4( 支持矩阵 )和WebM( 支持矩阵 )是明显的选择。 在两种格式之间,只有Opera Mini不支持。

  • 如果您要定位较旧的浏览器或function较少的设备,或者您无法负担MPEG4编码,则可以将这些帧编码为单独的JPEG或PNG图像。 使用时序将这些与JSON有效负载捆绑在一起,并使用JavaScript或其他客户端脚本在动画帧之间切换。 这非常有效。

笔记

1来自GIF 89a规格 :

动画 – 图形交换格式不是用作动画的平台,即使它可以以有限的方式完成。