This is an ObjectiveC method that generates GIF image:
@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
Running this method on iOS9 works fine, GIF generated loops forever on browsers:
Running the same method on iOS10 fails, GIF generated no longer loops forever on browsers, it only play once:
Besides, inspired by this answer: https://stackoverflow.com/a/38082881/448662, I did a hex comparison of the two GIFs generated in both iOS9 and iOS10, it appears that a segment (Netscape application extension) is missing in the iOS10 generated GIF, this could be the reason why it doesn't loop, but I can't be sure.
In short, how can we generate GIF image (using ObjectiveC) that loops forever on browser?
Upload a GIF file Select a GIF file from your folder after clicking on ‘Choose GIF File’. You can also drag and drop your GIF image into the box. 2. Loop your GIF Create a loop by adding the same GIF image. Just click on the plus (+) button on the bottom-right of the editor and select the same file. 3. Export your GIF Click on ‘Export’.
The GIF is completely fine the problem is on a modern internet browser's side. Affected browsers are Opera, IE, and Chrome (didn't test others). After some investigation on the matter (by comparing looping and non-looping images), I found out that these browsers' GIF decoders are ignoring the looping parameters in GIF files.
Create infinite looping GIFs in seconds, with just a few clicks. You don’t need to download an app or create an account. VEED’s online GIF editor lets you loop your animated GIF images. You can also create cool new GIFs from YouTube videos and convert videos of different formats into GIF files. Simply upload your video or paste a YouTube link.
If you don't see #images, it is possible that you are in a region where GIFs are not supported. In this situation, you can change the region to a country that supports this feature. On your iPhone, go to Settings and tap on "General". Scroll down to "Laguage & Region" to change the settings.
I found the solution on a recent commit on this GitHub repo: https://github.com/NSRare/NSGIF/pull/23/files?diff=split
Basically, calling CGImageDestinationSetProperties before CGImageDestinationAddImage solves the problem on iOS10.
This is the working code:
@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;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With