使用UIImages创建gif

4

我指的是这篇文章。我正在尝试使用屏幕截图创建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);
        }
    }

这将会用我的UIView创建一个包含10帧的gif图像。
现在... 我的目标是: 我正在使用UIBeizerPath在我的UIView上用手指画一个简单的图形,并且同时拍摄快照,这样我将会有大约50-100个PNG文件。我试图将所有这些图像传递给makeGifMethod。 工作流程:
  1. 启动应用程序。
  2. 点击一个按钮开始计时器,并每隔0.1秒拍照
  3. 用手指画(所以每隔0.1秒会捕捉到所有的绘图)
  4. 在每个快照后,我调用makeanimatedgif方法,以便将所拍摄的快照添加到gif文件中的前一帧
  5. 停止所有
问题:

-案例1:

  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动画吗?

1个回答

5

在尝试了一些解决方案后,我选择将所有捕获的图像存储到一个数组中,并使用该数组将图像传递给 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);

  }

1
你能否详细说明一下你用来解决这个问题的代码?你说你将一个数组传递到gifMethod中,但在哪里使用了它呢? - Eytan Schulman

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接