【问题标题】:Create a gif with UIImages使用 UIImages 创建 gif
【发布时间】:2016-01-06 12:18:27
【问题描述】:

我指的是post。我正在尝试使用屏幕截图创建的图像制作一个 gif 文件。我正在使用计时器来创建屏幕快照,以便获得可用于创建 gif 的所需帧数。我每 0.1 秒拍摄一次快照(稍后我将在 3 秒后结束此计时器)。

这是我拍摄 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 的辅助函数。我不确定如何将图像传递给辅助函数。这是我尝试过的:

我试图修改这部分:

 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 的 gif。

现在....

我想做的是:

我正在使用UIBeizerPath 用手指在我的UIView 上绘制一个简单的绘图,并且我正在与我的绘图并行拍摄快照,这样我将拥有大约50-100 个PNG 文件。我正在尝试将所有这些图像传递给 makeGifMethod。

工作流程:

  1. 启动应用程序。
  2. 点击启动计时器的按钮,每 0.1 秒拍照一次
  3. 用手指绘图(因此所有绘图将每 0.1 秒捕获一次)
  4. 每次抓拍后,我都会调用makeanimatedgif方法,这样抓拍的抓拍就会添加到gif文件的前一帧中
  5. 停止一切

问题:

-案例一:

  1. 点击按钮(会立即创建 gif)
  2. 开始绘图
  3. 停止
  4. 检查 gif(一个 10 帧的 gif 是用白色背景创建的,因为我点击按钮时什么也没画)

如果我在循环中调用我的 snapShot 方法,我会得到我绘图的最后 10 帧,但不是全部。

for (NSUInteger i = 0; i < 10; i++) {
        @autoreleasepool {
            UIImage *image = [self takeSnapShot];
            CGImageDestinationAddImage(destination, image.CGImage, (__bridge CFDictionaryRef)frameProperties);
        }
    }

-案例 2:

  1. 点击按钮(启动计时器,拍摄快照,同时调用 makeGifMethod)
  2. 画东西
  3. 停止
  4. 检查 gif(空 gif 创建时没有任何帧,我相信每 0.1 秒调用一次 makeGifMethod 没有按预期工作)

这是案例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 吗?

【问题讨论】:

    标签: ios objective-c gif cgimage


    【解决方案1】:

    经过几次变通后,我选择将所有捕获的图像存储到一个数组中,并使用该数组将图像传递给 gifMethod。而且效果很好!!!

    我已将所有图像存储到数组中:

    -(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]; 
    
    } 
    

    注意:确保在将图像存储到数组之前调整图像大小,否则如果长时间使用,可能会出现内存警告,然后是应用程序崩溃。

    后来使用了相同的数组:

    -(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);
    
      }
    

    【讨论】:

    • 您能否详细说明您用于解决此问题的代码?你说你将一个数组传递给 gifMethod 但你在哪里使用它?
    猜你喜欢
    • 2016-05-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-16
    • 2012-06-25
    • 2016-10-18
    • 2015-01-15
    相关资源
    最近更新 更多