问题
I am referring to this post . I am trying to make a gif file with the images created by screenshot. I am using a timer to create the snapshot of the screen,so that I get required amount of frames that could be used to create a gif. I take snaphots every 0.1 seconds (I will later end this timer after 3 seconds).
Here is my code to take snapshots of my UIView:
-(void)recordScreen{
self.timer= [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(takeSnapShot) userInfo:nil repeats:YES];
}
-(void)takeSnapShot{
//capture the screenshot of the uiimageview and save it in camera roll
UIGraphicsBeginImageContext(self.drawView.frame.size);
[self.drawView.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
}
and the post I am referring to, shows a helper function to create gif. I am not sure how should I pass my images to the helper function. Here is what I tried:
I tried to modify this part :
static NSUInteger kFrameCount = 10;
for (NSUInteger i = 0; i < kFrameCount; i++) {
@autoreleasepool {
UIImage *image = [self takeSnaphot];
CGImageDestinationAddImage(destination, image.CGImage, (__bridge CFDictionaryRef)frameProperties);
}
}
This creates the gif with 10 frames of my UIView
.
Now....
What I am trying to do is:
I am drawing a simple drawing with finger on my UIView
using UIBeizerPath
and I am taking snapshots in parallel to my drawing ,so that I will have around 50-100 of PNG files. I am trying to pass all these images to the makeGifMethod.
WorkFlow:
- Start the App.
- Tap on a button which starts the timer, and take pics for every 0.1 sec
- Draw with finger (so all the drawing will be captured evry 0.1 secs)
- After each snapshot, I call
makeanimatedgif
method,so that the snapshot taken will be added to the previous frame in the gif file - Stop everything
Issue:
-Case 1:
- Tap on button (which does create gif immediatley)
- Start drawing
- Stop
- Check gif (a gif with 10 frames is created with white background,since I drew nothing when I hit button)
If I call my snapShot method in a loop, I get the last 10 frames of my drawing,but not everything.
for (NSUInteger i = 0; i < 10; i++) {
@autoreleasepool {
UIImage *image = [self takeSnapShot];
CGImageDestinationAddImage(destination, image.CGImage, (__bridge CFDictionaryRef)frameProperties);
}
}
-Case 2:
- Hit button (start timer, take snapshot, call makeGifMethod in parallel to it)
- Draw somthing
- Stop
- Check gif (empty gif is created without any frames,I beleieve calling makeGifMethod every 0.1 seconds didnt work as expected)
Here is the code for case 2:
-(void)recordScreen{
self.timer= [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(takeSnapShot) userInfo:nil repeats:YES];
}
-(void)takeSnapShot{
//capture the screenshot of the uiimageview and save it in camera roll
UIGraphicsBeginImageContext(self.drawView.frame.size);
[self.drawView.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[self makeAnimatedGif:(UIImage *)viewImage];
});
}
-(void) makeAnimatedGif:(UIImage *)image{
NSDictionary *fileProperties = @{
(__bridge id)kCGImagePropertyGIFDictionary: @{
(__bridge id)kCGImagePropertyGIFLoopCount: @0, // 0 means loop forever
}
};
NSDictionary *frameProperties = @{
(__bridge id)kCGImagePropertyGIFDictionary: @{
(__bridge id)kCGImagePropertyGIFDelayTime: @0.02f, // a float (not double!) in seconds, rounded to centiseconds in the GIF data
}
};
documentsDirectoryURL = [[NSFileManager defaultManager] URLForDirectory:NSDocumentDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:YES error:nil];
fileURL = [documentsDirectoryURL URLByAppendingPathComponent:@"animated.gif"];
CGImageDestinationRef destination = CGImageDestinationCreateWithURL((__bridge CFURLRef)fileURL, kUTTypeGIF, 10, NULL);
CGImageDestinationSetProperties(destination, (__bridge CFDictionaryRef)fileProperties);
CGImageDestinationAddImage(destination, image.CGImage, (__bridge CFDictionaryRef)frameProperties);
if (!CGImageDestinationFinalize(destination)) {
NSLog(@"failed to finalize image destination");
}
CFRelease(destination);
NSLog(@"url=%@", fileURL);
}
Can someone please suggest me how to pass the captured images to the above method to make a gif?
回答1:
After few work arounds, I choose to store all the captured images into an array, and use that array to pass the images to gifMethod. And it worked so cool!!!
I have stored all the images into array:
-(void)takeSnapShot{
//capture the screenshot of the uiimageview and save it in camera roll
UIGraphicsBeginImageContext(self.drawView.frame.size);
[self.drawView.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
//store all the images into array
[imgArray adDObject:viewImage];
}
NOTE: make sure you resize the image before you store them into array else you might end up with memory warning followed by app crash if this is used for a longer period.
and later used the same array :
-(void)makeAnimatedGif {
NSUInteger kFrameCount = imgArray.count;
NSDictionary *fileProperties = @{
(__bridge id)kCGImagePropertyGIFDictionary: @{
(__bridge id)kCGImagePropertyGIFLoopCount: @0, // 0 means loop forever
}
};
NSDictionary *frameProperties = @{
(__bridge id)kCGImagePropertyGIFDictionary: @{
(__bridge id)kCGImagePropertyGIFDelayTime: @0.08f, // 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"];
CGImageDestinationRef destination = CGImageDestinationCreateWithURL((__bridge CFURLRef)fileURL, kUTTypeGIF, kFrameCount, NULL);
CGImageDestinationSetProperties(destination, (__bridge CFDictionaryRef)fileProperties);
for (NSUInteger i = 0; i < kFrameCount; i++) {
@autoreleasepool {
UIImage *image =[imgArray objectAtIndex:i]; //Here is the change
CGImageDestinationAddImage(destination, image.CGImage, (__bridge CFDictionaryRef)frameProperties);
}
}
if (!CGImageDestinationFinalize(destination)) {
NSLog(@"failed to finalize image destination");
}
CFRelease(destination);
NSLog(@"url=%@", fileURL);
}
来源:https://stackoverflow.com/questions/33023196/create-a-gif-with-uiimages