I want to convert a video file taken with the camera (.mp4) and convert it to an animated GIF image.
I looked up the Apple Docs and there doesn't seem to be any built-in function for this.
How should I approach this task?
You can do it in Some Step 1- Calculate the required Frame
CMTime vid_length = asset.duration;
float seconds = CMTimeGetSeconds(vid_length);
int required_frames_count = seconds * 12.5; //You can set according
to u
int64_t step = vid_length.value / required_frames_count;
int value = 0;
2- Make Gif File Setting Property
destination = CGImageDestinationCreateWithURL((CFURLRef)[NSURL fileURLWithPath:path],
kUTTypeGIF,
required_frames_count,
NULL);
frameProperties = [NSDictionary dictionaryWithObject:[NSDictionary dictionaryWithObject:[NSNumber numberWithInt:0.8] forKey:(NSString *)kCGImagePropertyGIFDelayTime]
forKey:(NSString *)kCGImagePropertyGIFDictionary];
gifProperties = [NSDictionary dictionaryWithObject:[NSDictionary dictionaryWithObject:[NSNumber numberWithInt:0] forKey:(NSString *)kCGImagePropertyGIFLoopCount]
forKey:(NSString *)kCGImagePropertyGIFDictionary];
Step 3 Generate Frame from Video Asset AVAssetImageGenerator
for (int i = 0; i < required_frames_count; i++) {
AVAssetImageGenerator *image_generator = [[AVAssetImageGenerator alloc] initWithAsset:asset];
image_generator.requestedTimeToleranceAfter = kCMTimeZero;
image_generator.requestedTimeToleranceBefore = kCMTimeZero;
image_generator.appliesPreferredTrackTransform = YES;
image_generator.maximumSize = CGSizeMake(wd, ht); //to get an unscaled image or define a bounding box of 640px, aspect ratio remains
CMTime time = CMTimeMake(value, vid_length.timescale);
CGImageRef image_ref = [image_generator copyCGImageAtTime:time actualTime:NULL error:NULL];
UIImage *thumb = [UIImage imageWithCGImage:image_ref];
[self mergeFrameForGif:thumb];
CGImageRelease(image_ref);
value += step;
}
NSLog(@"Over all Size of Image(bytes):%ld",t);
CGImageDestinationSetProperties(destination, (CFDictionaryRef)gifProperties);
CGImageDestinationFinalize(destination);
CFRelease(destination);
NSLog(@"animated GIF file created at %@", path);
Step 4 Add Frame in Gif file
- (void)mergeFrameForGif:(UIImage*)pic1
{
CGImageDestinationAddImage(destination, pic1.CGImage, (CFDictionaryRef)frameProperties);
pic1=nil;
}
There is no built-in API for that. I released a library that converts video files to animated GIF images while giving enough flexibility to tweak settings such as frame rate, frame duration, size, etc.
The library is called NSGIF. You can find it here: http://github.com/NSRare/NSGIF
This is the simplest way to convert a video to a GIF:
[NSGIF optimalGIFfromURL:url loopCount:0 completion:^(NSURL *GifURL) {
NSLog(@"Finished generating GIF: %@", GifURL);
}];
Using the optimalGIFfromURL
method, automatically generates the GIF based on the optimal settings. There is also room for way more flexibility. Check out the repo for more samples.
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