用UIImages创建一个gif [英] Create a gif with UIImages
问题描述
我指的是发布。我试图用截图创建的图像制作一个gif文件。我正在使用计时器来创建屏幕快照,以便获得可用于创建gif的所需帧数。我每0.1秒拍摄一次快照(我将在3秒后结束这个计时器)。
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).
这是我拍摄UIView快照的代码:
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();
}
以及我所指的帖子,显示辅助功能创建gif。我不确定如何将我的图像传递给辅助函数。这是我试过的:
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:
我试图修改这部分:
static NSUInteger kFrameCount = 10;
for (NSUInteger i = 0; i < kFrameCount; i++) {
@autoreleasepool {
UIImage *image = [self takeSnaphot];
CGImageDestinationAddImage(destination, image.CGImage, (__bridge CFDictionaryRef)frameProperties);
}
}
这会创建一个包含10帧
This creates the gif with 10 frames of my UIView
.
现在....
我要做的是:
我用手指在我的 UIView $ c $上绘制一个简单的图画c>使用
UIBeizerPath
并且我将快照与我的绘图并行拍摄,这样我将有大约50-100个PNG文件。我试图将所有这些图片传递给makeGifMethod。
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:
- 启动应用程序。
- 点击启动计时器的按钮,每0.1秒拍摄一次图片
- 用手指绘制(所以所有绘图都将被捕获,每秒0.1秒)
- 在每个快照之后,我调用
makeanimatedgif
方法,这样拍摄的快照将添加到gif文件中的上一帧 - 停止一切
- 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
问题:
- 案例1:
- 点击按钮(确实创建了gif immediatley)
- 开始绘图
- 停止
- 检查gif(带有10帧的gif是用白色背景创建的,因为当我按下按钮时我什么都没画)
- 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)
如果我在循环中调用我的snapShot方法,得到了我绘图的最后10帧,但不是所有内容。
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);
}
}
- 案例2:
- 点击按钮(启动计时器,拍摄快照,并行调用makeGifMethod)
- Draw somthing
- 停止
- 检查gif(空gif创建时没有任何框架,我每隔0.1秒调用makeGifMethod就不会按预期工作)
- 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)
以下是案例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);
}
有人可以建议我如何将捕获的图像传递给上述方法制作一个gif?
Can someone please suggest me how to pass the captured images to the above method to make a gif?
推荐答案
经过几次解决后,我选择将所有捕获的图像存储到一个数组中,并使用该数组将图像传递给gifMethod。它工作得很酷!!!
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.
后来使用相同的数组:
-(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);
}
这篇关于用UIImages创建一个gif的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!