创建并通过iOS的导出为GIF动画?(Create and export an animated g

2019-07-20 01:25发布

我有在一个简单的,一帧一帧翻转书样式进行动画iOS应用中的一系列用户自定义图像。

我的问题是:有没有办法可以让用户将他们的动画导出为GIF动画? 理想情况下,我想,让他们到电子邮件,社交共享(T / FB)或(最坏情况..)通过iTunes GIF动画保存到自己的文件夹进行检索。

我知道如何.png文件保存到照片库,我找到了一种方法来记录动画为QT文件( http://www.cimgf.com/2009/02/03/record-your-core-animation -动画/ ),但我还没有找到一种方法来只踢了一个普通的老gif动画。 我缺少的核心动画东西,或别的地方? 是否有任何方法,框架或资源,任何人都可以推荐? 很抱歉,如果问题是过于笼统 - 努力寻找一个起点。

Answer 1:

您可以使用图像I / O框架(这是iOS的SDK的一部分)创建动画GIF。 您还希望包括MobileCoreServices框架,它定义了GIF类型常量。 您需要这些框架要在其中创建动画GIF,像这样的文件添加到您的目标,并导入自己的头:

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

这是最简单的例子来解释。 我会告诉你我用来做在我的iPhone 5这个GIF的代码:

首先,这里是一个辅助函数,它的尺寸和角度,并返回一个UIImage那个角红盘的:

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。 首先,我们将定义一个常数的帧数,因为我们需要它后来两次:

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

我们需要一个属性字典,以指定的时间动画应该重复次数:

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

我们也将创建在我们的文件目录中的GIF的URL:

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

现在,我们可以创建一个CGImageDestination写入一个GIF到指定的网址:

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

我发现,通过fileProperties作为最后一个参数CGImageDestinationCreateWithURL 不起作用 。 你必须使用CGImageDestinationSetProperties

现在,我们可以创建并写入我们的框架:

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

请注意,我们通过框架属性每帧图像字典一起。

之后,我们已经添加了准确的帧的指定数量,我们完成目标,并释放它:

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

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

如果您在模拟器中运行这个,你可以从调试控制台复制网址并将其粘贴到浏览器中看到的图像。 如果您在设备上运行它,你可以使用Xcode的管理窗口,从设备下载的应用程序沙箱,并期待在图像。 或者你可以像使用一个应用程序iExplorer ,可以让你直接浏览设备的文件系统。 (这不需要越狱)。

我测试了这个在我的iPhone 5运行iOS 6.1,但我相信代码应工作早的iOS 4.0。

我已经把所有的代码都在这个要点 ,便于复制。



Answer 2:

如果您正在寻找斯威夫特3解决方案,你可以看看https://github.com/onmyway133/GifMagic 。 它具有EncoderDecoder ,其组装和拆卸gif文件。

基本上,你应该使用Image IO框架,这些功能CGImageDestinationCreateWithURLCGImageDestinationSetPropertiesCGImageDestinationAddImageCGImageDestinationFinalize

还与斯威夫特https://developer.apple.com/library/content/documentation/Swift/Conceptual/BuildingCocoaApps/WorkingWithCocoaDataTypes.html

核心基础,从注释的API返回的对象是自动存储在管理斯威夫特,你不需要调用CFRetain,CFRelease,或CFAutorelease功能自己。



Answer 3:

对于斯威夫特3

import Foundation
import UIKit
import ImageIO
import MobileCoreServices

extension UIImage {
    static func animatedGif(from images: [UIImage]) {
        let fileProperties: CFDictionary = [kCGImagePropertyGIFDictionary as String: [kCGImagePropertyGIFLoopCount as String: 0]]  as CFDictionary
        let frameProperties: CFDictionary = [kCGImagePropertyGIFDictionary as String: [(kCGImagePropertyGIFDelayTime as String): 1.0]] as CFDictionary

        let documentsDirectoryURL: URL? = try? FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true)
        let fileURL: URL? = documentsDirectoryURL?.appendingPathComponent("animated.gif")

        if let url = fileURL as CFURL? {
            if let destination = CGImageDestinationCreateWithURL(url, kUTTypeGIF, images.count, nil) {
                CGImageDestinationSetProperties(destination, fileProperties)
                for image in images {
                    if let cgImage = image.cgImage {
                        CGImageDestinationAddImage(destination, cgImage, frameProperties)
                    }
                }
                if !CGImageDestinationFinalize(destination) {
                    print("Failed to finalize the image destination")
                }
                print("Url = \(fileURL)")
            }
        }
    }
}

我从转换它上面的回答 。 我希望它能帮助。

可以作为一个依据 。

编辑欢迎。



文章来源: Create and export an animated gif via iOS?