-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathUIImage+GIFFromMovie.m
104 lines (75 loc) · 4.33 KB
/
UIImage+GIFFromMovie.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
//
// UIImage+GIFFromMovie.m
// wecarepet
//
// Created by MaHang on 12/11/15.
// Copyright © 2015 wecarepet. All rights reserved.
//
#import "UIImage+GIFFromMovie.h"
#import <ImageIO/ImageIO.h>
#import <objc/runtime.h>
#import <MobileCoreServices/MobileCoreServices.h>
#import "UIImage+animatedGIF.h"
@implementation UIImage (GIFFromMovie)
+(void)AnimatedGIFFromMovieAsset:(AVURLAsset *)movie timeIncrement:(float)increment completion:(GIFFromMovieCompletion)completion{
//Instantiate an AVAssetImageGenerator for the target Movie.
AVAssetImageGenerator *generator = [AVAssetImageGenerator assetImageGeneratorWithAsset:movie];
//Calculate the frames in the final GIF by the movie's length and the given time increment.
float movieLength = (float)movie.duration.value /movie.duration.timescale;
int frameCount = movieLength / increment;
float tolerance = 0.01f;
//Create a temp gif file as the output destination.
//By adding all the thumbnails to this file, we could generate the desired gif file holding the data.
NSString *tempFile = [NSTemporaryDirectory() stringByAppendingString:@"temp.gif"];
CFURLRef fileURL = (__bridge CFURLRef) [NSURL fileURLWithPath:tempFile];
CGImageDestinationRef destination = CGImageDestinationCreateWithURL(fileURL, kUTTypeGIF, frameCount,nil);
//Set properties for the generator and gif.
generator.requestedTimeToleranceBefore = CMTimeMakeWithSeconds(tolerance, 600) ;
generator.requestedTimeToleranceAfter = CMTimeMakeWithSeconds(tolerance, 600);
generator.appliesPreferredTrackTransform = YES;
NSDictionary *frameProperties = [NSDictionary dictionaryWithObject:[NSDictionary dictionaryWithObject:[NSNumber numberWithFloat:increment] forKey:(NSString *)kCGImagePropertyGIFDelayTime] forKey:(NSString *)kCGImagePropertyGIFDictionary];
NSDictionary *gifProperties = [NSDictionary dictionaryWithObject:[NSDictionary dictionaryWithObject:[NSNumber numberWithInt:0] forKey:(NSString *)kCGImagePropertyGIFLoopCount] forKey:(NSString *)kCGImagePropertyGIFDictionary];
//Get the size of the target Movie;
CGSize videoSize = [[[movie tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0] naturalSize];
//Set the out put size of thumbnails. Here we force the output image to be 320 in width
float imageWidth = 320.0f;
generator.maximumSize = CGSizeMake( imageWidth , imageWidth/videoSize.width * videoSize.height);
//Perform the converting asynchronously
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSError *error = nil;
//Repeatly generate thumbnail of video and put them together
for (int i = 0 ; i < frameCount; i++) {
//Time for current thumbnail
CMTime imageTime = CMTimeMakeWithSeconds(i*increment, 600);
//Generate the thumbnail
CGImageRef image = [generator copyCGImageAtTime:imageTime actualTime:nil error:&error];
if (error) {
//Once there is any error during converting, stop and call back.
completion(nil,error);
return;
}
//Add current thumbnail to the destination
CGImageDestinationAddImage(destination, image, (CFDictionaryRef)frameProperties);
}
//set gif properties (infinite loop)
CGImageDestinationSetProperties(destination, (CFDictionaryRef)gifProperties);
//Finalize temp file
CGImageDestinationFinalize(destination);
//Get the gifData and Associate it with the UIImage instance;
NSData *gifData = [NSData dataWithContentsOfURL:[NSURL fileURLWithPath:tempFile]];
UIImage *result = [UIImage animatedImageWithAnimatedGIFData:gifData];
objc_setAssociatedObject(result, @"gifData",gifData,OBJC_ASSOCIATION_RETAIN);
//Release the temp file
CFRelease(destination);
//callback
completion(result,error);
});
}
-(NSData *)getGifData{
//return the assocated gif Data
return objc_getAssociatedObject(self, @"gifData");
//FOR EXAMPLE:
//If we need the dataUrl of this UIImage
//[NSString stringWithFormat:@"data:%@;base64,%@", @"image/gif", [[image getGifData] base64EncodedStringWithOptions:0]]
}
@end