通过iOS创建和导出动画gif吗? [英] Create and export an animated gif via iOS?

查看:185
本文介绍了通过iOS创建和导出动画gif吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在iOS应用程序中有一系列用户自定义图像,这些图像以简单的逐帧翻转书样式进行动画处理.

I have a series of user-customized images within an iOS app that are being animated in a simple, frame-by-frame flip book style.

我的问题是:有没有办法允许用户将动画导出为动画gif?理想情况下,我希望使他们能够通过电子邮件发送电子邮件,社交共享(T/FB)或(最坏的情况.)将动画gif保存到他们的文档文件夹中,以便通过iTunes进行检索.

My question is this: is there a way to allow users to export their animation as an animated gif? Ideally, I'd like to enable them to email, social share (T/FB) or (worst case..) save an animated gif to their documents folder for retrieval via iTunes.

我知道如何将.png保存到图片库,并且找到了一种将动画录制为QT文件的方法(

I know how to save a .png to the photo library, and I found a way to record an animation as a QT file (http://www.cimgf.com/2009/02/03/record-your-core-animation-animation/), but I haven't found a way to just kick out a plain old animated gif. Am I missing something in Core Animation or somewhere else? Are there any approaches, frameworks, or resources that anyone can recommend? Sorry if the question is too general - struggling to find a starting point.

推荐答案

您可以使用Image I/O框架(iOS SDK的一部分)创建动画GIF.您还将需要包含MobileCoreServices框架,该框架定义了GIF类型常量.您需要将这些框架添加到目标中,并将其标头导入要创建动画GIF的文件中,如下所示:

You can create an animated GIF using the Image I/O framework (which is part of the iOS SDK). You will also want to include the MobileCoreServices framework, which defines the GIF type constant. You need to add these frameworks to your target, and import their headers in the file where you want to create the animated GIF, like this:

#import <ImageIO/ImageIO.h>
#import <MobileCoreServices/MobileCoreServices.h>

通过示例最容易解释.我将向您展示我在iPhone 5上制作此GIF的代码:

It's easiest to explain by example. I'll show you the code I used to make this GIF on my iPhone 5:

首先,这是一个辅助函数,该函数具有大小和角度,并以该角度返回红色磁盘的UIImage:

First, here's a helper function that takes a size and an angle and returns a UIImage of the red disk at that angle:

static UIImage *frameImage(CGSize size, CGFloat radians) {
    UIGraphicsBeginImageContextWithOptions(size, YES, 1); {
        [[UIColor whiteColor] setFill];
        UIRectFill(CGRectInfinite);
        CGContextRef gc = UIGraphicsGetCurrentContext();
        CGContextTranslateCTM(gc, size.width / 2, size.height / 2);
        CGContextRotateCTM(gc, radians);
        CGContextTranslateCTM(gc, size.width / 4, 0);
        [[UIColor redColor] setFill];
        CGFloat w = size.width / 10;
        CGContextFillEllipseInRect(gc, CGRectMake(-w / 2, -w / 2, w, w));
    }
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return image;
}

现在我们可以创建GIF.首先,我们将为帧数定义一个常数,因为以后需要两次:

Now we can create the GIF. First we'll define a constant for the number of frames, because we need it twice later:

static void makeAnimatedGif(void) {
    static NSUInteger const kFrameCount = 16;

我们需要一个属性字典来指定动画应重复的次数:

We'll need a property dictionary to specify the number of times the animation should repeat:

    NSDictionary *fileProperties = @{
        (__bridge id)kCGImagePropertyGIFDictionary: @{
            (__bridge id)kCGImagePropertyGIFLoopCount: @0, // 0 means loop forever
        }
    };

我们将需要另一个属性字典,该字典将附加到每个框架上,指定应显示该框架多长时间:

And we'll need another property dictionary, which we'll attach to each frame, specifying how long that frame should be displayed:

    NSDictionary *frameProperties = @{
        (__bridge id)kCGImagePropertyGIFDictionary: @{
            (__bridge id)kCGImagePropertyGIFDelayTime: @0.02f, // a float (not double!) in seconds, rounded to centiseconds in the GIF data
        }
    };

我们还将在文档目录中为GIF创建一个URL:

We'll also create a URL for the GIF in our documents directory:

    NSURL *documentsDirectoryURL = [[NSFileManager defaultManager] URLForDirectory:NSDocumentDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:YES error:nil];
    NSURL *fileURL = [documentsDirectoryURL URLByAppendingPathComponent:@"animated.gif"];

现在,我们可以创建一个CGImageDestination,该CGImageDestination将GIF写入指定的URL:

Now we can create a CGImageDestination that writes a GIF to the specified URL:

    CGImageDestinationRef destination = CGImageDestinationCreateWithURL((__bridge CFURLRef)fileURL, kUTTypeGIF, kFrameCount, NULL);
    CGImageDestinationSetProperties(destination, (__bridge CFDictionaryRef)fileProperties);

我发现将fileProperties作为CGImageDestinationCreateWithURL的最后一个参数传递不会有效.您必须使用CGImageDestinationSetProperties.

I discovered that passing fileProperties as the last argument of CGImageDestinationCreateWithURL does not work. You have to use CGImageDestinationSetProperties.

现在我们可以创建和编写框架:

Now we can create and write our frames:

    for (NSUInteger i = 0; i < kFrameCount; i++) {
        @autoreleasepool {
            UIImage *image = frameImage(CGSizeMake(300, 300), M_PI * 2 * i / kFrameCount);
            CGImageDestinationAddImage(destination, image.CGImage, (__bridge CFDictionaryRef)frameProperties);
        }
    }

请注意,我们将帧属性字典与每个帧图像一起传递.

Note that we pass the frame properties dictionary along with each frame image.

添加完指定数量的帧后,我们最终确定目标并释放它:

After we've added exactly the specified number of frames, we finalize the destination and release it:

    if (!CGImageDestinationFinalize(destination)) {
        NSLog(@"failed to finalize image destination");
    }
    CFRelease(destination);

    NSLog(@"url=%@", fileURL);
}

如果在模拟器上运行此命令,则可以从调试控制台复制URL,然后将其粘贴到浏览器中以查看图像.如果在设备上运行它,则可以使用Xcode Organizer窗口从设备下载应用程序沙箱并查看图像.或者,您可以使用iExplorer之类的应用程序,让您直接浏览设备的文件系统. (这不需要越狱.)

If you run this on the simulator, you can copy the URL from the debug console and paste it into your browser to see the image. If you run it on the device, you can use the Xcode Organizer window to download the app sandbox from the device and look at the image. Or you can use an app like iExplorer that lets you browse your device's filesystem directly. (This doesn't require jailbreaking.)

我在运行iOS 6.1的iPhone 5上进行了测试,但是我认为代码应该可以追溯到iOS 4.0.

I tested this on my iPhone 5 running iOS 6.1, but I believe the code should work as far back as iOS 4.0.

为了便于复制,我将所有代码都放在了此要点中.

I've put all the code in this gist for easy copying.

这篇关于通过iOS创建和导出动画gif吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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