ios - 如何在iOS中生成24位True Color动画Gif?

标签 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图片:



这是生成的gif图像的屏幕截图:



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

最佳答案

GIF并非旨在存储真彩色数据,并且也不适用于动画1。由于这是GIF的异常用法,因此您将不得不编写许多自己的代码。

  • 将每个帧分成矩形块,其中每个块最多包含256种不同的颜色。最简单的方法是使用16x16的块。
  • 将每个块转换为索引图像。
  • 将每个块添加到GIF。对于帧中的第一个块,请使用帧延迟。对于帧中的其他块,请使用0延迟。

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

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

    意见

    即使有可能,将高质量动画制作到GIF中的想法也是极端荒谬的。鉴于可用的替代方案,这尤其荒谬:
  • 如果您的目标是现代浏览器或移动设备,则MPEG4(support matrix)和WebM(support matrix)是显而易见的选择。在这两种格式之间,仅Opera Mini不支持。
  • 如果您以较旧的浏览器或功能较弱的设备为目标,或者无法负担MPEG4编码,则可以将帧编码为单独的JPEG或PNG图像。将这些内容与JSON有效负载与时间捆绑在一起,并使用JavaScript或其他客户端脚本在动画帧之间进行切换。这出奇地好。

  • 笔记

    1从GIF 89a specification:

    动画-图形交换格式不旨在用作以下平台
    动画,即使可以通过有限的方式完成。

    关于ios - 如何在iOS中生成24位True Color动画Gif?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24535149/

    相关文章:

    ios - 在 Collection View 之上创建 View ?

    ios - 检测单元格编辑中的单元格点击,显示重新排序控制 + 披露控制作为 Safari 书签编辑

    ios - 表达式中的 NSExpression 自定义变量

    objective-c - iOS 对象被识别为错误的类

    iphone - 有没有办法在 Xcode 中安装旧的 iOS SDK?

    ios - 在 iOS 7 上读取视频元数据 - 始终为空

    ios - Realm.io 压缩数据库

    html - 填充在 iOS 上似乎无法正确显示

    ios - 为什么数据多次添加到数组中?

    ios - cellForRowAtIndexPath 中 if 条件中的多个 return 语句抛出 "Control may reach end of non-void function"错误