在iOS10上生成的GIF图像不再在浏览器上永久循环

mkt*_*kto 5 objective-c gif animated-gif ios10

这是一个生成GIF图像的ObjectiveC方法:

@implementation NSArray (GIFImage)

- (NSString*)GIFImageWithImageDuration:(CGFloat)GIFImageDuration
{
    NSArray *images = self;

    NSString *path = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:@"animated.gif"];
    CGImageDestinationRef destination = CGImageDestinationCreateWithURL((CFURLRef)[NSURL fileURLWithPath:path],
                                                                        kUTTypeGIF,
                                                                        images.count,
                                                                        NULL);

    NSDictionary *frameProperties = [NSDictionary dictionaryWithObject:[NSDictionary dictionaryWithObject:[NSNumber numberWithFloat:GIFImageDuration]
                                                                                                   forKey:(NSString *)kCGImagePropertyGIFDelayTime]
                                                                forKey:(NSString *)kCGImagePropertyGIFDictionary];


    NSDictionary *gifProperties = [NSDictionary dictionaryWithObject:[NSDictionary dictionaryWithObject:[NSNumber numberWithInt:0] forKey:(NSString *)kCGImagePropertyGIFLoopCount]
                                                              forKey:(NSString *)kCGImagePropertyGIFDictionary];

    for ( NSInteger index = 0; index < images.count; index++ )
    {
        UIImage *image = (UIImage *)[images objectAtIndex:index];
        CGImageDestinationAddImage(destination, image.CGImage, (CFDictionaryRef)frameProperties);
    }

    CGImageDestinationSetProperties(destination, (CFDictionaryRef)gifProperties);
    CGImageDestinationFinalize(destination);
    CFRelease(destination);
    NSLog(@"animated GIF file created at %@", path);
    return path;
}

@end
Run Code Online (Sandbox Code Playgroud)

在iOS9上运行此方法工作正常,GIF在浏览器上永久生成循环:

在此输入图像描述

在iOS10上运行相同的方法失败,GIF在浏览器上不再生成永久循环,它只播放一次:

在此输入图像描述

此外,受到这个答案的启发:https://stackoverflow.com/a/38082881/448662,我对iOS9和iOS10中生成的两个GIF进行了十六进制比较,似乎缺少一个段(Netscape应用程序扩展) iOS10生成的GIF,这可能是它不循环的原因,但我不能确定.

简而言之,我们如何生成在浏览器上永远循环的GIF图像(使用ObjectiveC)?

在此输入图像描述

mkt*_*kto 4

我在这个 GitHub 存储库上的最近提交中找到了解决方案: https://github.com/NSRare/NSGIF/pull/23/files ?diff=split

基本上,在CGImageDestinationAddImage之前调用CGImageDestinationSetProperties可以解决 iOS10 上的问题。

这是工作代码:

@implementation NSArray (GIFImage)
- (NSString*)GIFImageWithImageDuration:(CGFloat)GIFImageDuration
{
    NSArray *images = self;

    NSString *path = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:@"animated.gif"];
    CGImageDestinationRef destination = CGImageDestinationCreateWithURL((CFURLRef)[NSURL fileURLWithPath:path],
                                                                        kUTTypeGIF,
                                                                        images.count,
                                                                        NULL);

    NSDictionary *frameProperties = [NSDictionary dictionaryWithObject:[NSDictionary dictionaryWithObject:[NSNumber numberWithFloat:GIFImageDuration]
                                                                                                   forKey:(NSString *)kCGImagePropertyGIFDelayTime]
                                                                forKey:(NSString *)kCGImagePropertyGIFDictionary];


    NSDictionary *gifProperties = [NSDictionary dictionaryWithObject:[NSDictionary dictionaryWithObject:[NSNumber numberWithInt:0] forKey:(NSString *)kCGImagePropertyGIFLoopCount]
                                                              forKey:(NSString *)kCGImagePropertyGIFDictionary];

    CGImageDestinationSetProperties(destination, (CFDictionaryRef)gifProperties);

    for ( NSInteger index = 0; index < images.count; index++ )
    {
        UIImage *image = (UIImage *)[images objectAtIndex:index];
        CGImageDestinationAddImage(destination, image.CGImage, (CFDictionaryRef)frameProperties);
    }

    CGImageDestinationFinalize(destination);
    CFRelease(destination);
    NSLog(@"animated GIF file created at %@", path);
    return path;
}
Run Code Online (Sandbox Code Playgroud)