How can I generate 24-bit True Color Animated Gifs in iOS?

I want to create an animated Gif with true color from several PNG files represented as a base64 string. I found this article and did something similar. I have an array with dataUrls:

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

Here is what I did:

  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; 

Finally, I send the gif image as base64EncodedString back to the phonegap container.

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

It works well, but the quality of the resulting gif is poor. This is due to the fact that it has only 256 colors.

Here is the original png image:

enter image description here

Here is a screenshot of the generated gif image:

enter image description here

How to get the same quality as imported, i.e. how to increase the quality level of the created gif? How can I generate true gifs on iOS?

+1
ios objective-c iphone gif
Jul 02 '14 at 15:26
source share
1 answer

GIFs are not designed to store true color data, and they are also poorly suited for animations 1 . Since this is such an unusual use of GIFs, you will have to write a lot of your own code.

  • Divide each frame into rectangular pieces, where each fragment contains no more than 256 different colors. The easiest way to do this is to use 16x16 pieces.

  • Convert each fragment to an indexed image.

  • Add each piece to your GIF. For the first fragment in a frame, use frame delay. For other blocks in the frame, use a delay of 0.

Done. You will need to familiarize yourself with the GIF specification, which is freely available on the Internet ( the GIF89a specification on W3.org , see Section 23). You will also need to find an LZW compressor that is not so difficult to find. The animation will also use an obscene amount of memory: including base64 conversion, I estimate about 43 bit / pixel or about 1.2 Gbit / s for 720p video, which is about 400 times more than you would use for high-quality MPEG4 or WebM, and probably about 3 times bigger than required for PNG. Storage and bandwidth requirements are likely to be undesirable for hosts and clients if the animation is not very small and small.

Please note that this will not allow you to use alpha transparency, this is a strict limitation of the GIF format.

Opinion

The idea of ​​posting high-quality animations in GIFs is absurd as a last resort, although it is possible. This is especially absurd, given the available alternatives:

  • If you focus on modern browsers or mobile devices, MPEG4 ( matrix support ) and WebM ( matrix support ) are the obvious choice. Between the two formats, only Opera Mini is supported.

  • If you are targeting older browsers or devices with less ability, or if you cannot afford MPEG4 encoding, you can encode frames as separate JPEG or PNG images. Associate them with a JSON payload with time and use JavaScript or other client scripts to switch between frames of the animation. This works surprisingly well.

Notes

1 From the specification of GIF 89a :

Animation. The image sharing format is not intended for the animation platform, although this can be done in a limited way.

+3
Jul 03 '14 at 20:37
source share



All Articles