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

时间:2014-07-02 15:26:48

标签: ios objective-c iphone gif

我想从几个表示为base64字符串的PNG文件生成一个真彩色动画Gif。我找到this帖子并做了类似的事情。我有一个包含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图像:

enter image description here

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

enter image description here

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

1 个答案:

答案 0 :(得分:3)

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

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

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

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

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

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

    意见

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

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

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

    注释

    1 来自GIF 89a specification

      

    动画 - 图形交换格式不适合作为平台   动画,即使它可以以有限的方式完成。