Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Convert video to animated GIF on iOS

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?

like image 902
pixthecoder Avatar asked Jan 08 '23 14:01

pixthecoder


2 Answers

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;

}
like image 183
atul awasthi Avatar answered Jan 31 '23 00:01

atul awasthi


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.

like image 42
Sebyddd Avatar answered Jan 30 '23 23:01

Sebyddd