用UIImages创建一个gif [英] Create a gif with UIImages

查看:169
本文介绍了用UIImages创建一个gif的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我指的是发布。我试图用截图创建的图像制作一个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帧 UIView 。

This creates the gif with 10 frames of my UIView.

现在....

我要做的是:

我用手指在我的 UIView 使用 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:


  1. 启动应用程序。

  2. 点击启动计时器的按钮,每0.1秒拍摄一次图片

  3. 用手指绘制(所以所有绘图都将被捕获,每秒0.1秒)

  4. 在每个快照之后,我调用 makeanimatedgif 方法,这样拍摄的快照将添加到gif文件中的上一帧

  5. 停止一切

  1. Start the App.
  2. Tap on a button which starts the timer, and take pics for every 0.1 sec
  3. Draw with finger (so all the drawing will be captured evry 0.1 secs)
  4. After each snapshot, I call makeanimatedgif method,so that the snapshot taken will be added to the previous frame in the gif file
  5. Stop everything

问题:

- 案例1:


  1. 点击按钮(确实创建了gif immediatley)

  2. 开始绘图

  3. 停止

  4. 检查gif(带有10帧的gif是用白色背景创建的,因为当我按下按钮时我什么都没画)

  1. Tap on button (which does create gif immediatley)
  2. Start drawing
  3. Stop
  4. 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:


  1. 点击按钮(启动计时器,拍摄快照,并行调用makeGifMethod)

  2. Draw somthing

  3. 停止

  4. 检查gif(空gif创建时没有任何框架,我每隔0.1秒调用makeGifMethod就不会按预期工作)

  1. Hit button (start timer, take snapshot, call makeGifMethod in parallel to it)
  2. Draw somthing
  3. Stop
  4. 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆