我在iOS应用程序中有一系列用户自定义图像,这些图像以简单的逐帧翻转书样式进行动画处理。
我的问题是:有没有办法允许用户将其动画导出为动画gif?理想情况下,我希望使他们能够通过电子邮件发送电子邮件,社交共享(T / FB)或(最坏的情况。)将动画gif保存到他们的文档文件夹中,以便通过iTunes进行检索。
我知道如何将.png保存到图片库,并且找到了一种将动画录制为QT文件的方法(http://www.cimgf.com/2009/02/03/record- your-core-animation -animation /),但我还没有找到一种方法来踢出普通的老式gif动画。我在核心动画或其他地方缺少什么吗?有没有人可以推荐的方法,框架或资源?很抱歉,这个问题过于笼统- 努力寻找起点。
您可以使用Image I / O框架(iOS SDK的一部分)创建动画GIF。您还将需要包括MobileCoreServices定义GIF类型常量的框架。您需要将这些框架添加到目标中,并将它们的标头导入要创建动画GIF的文件中,如下所示:
MobileCoreServices
#import <ImageIO/ImageIO.h> #import <MobileCoreServices/MobileCoreServices.h>
通过示例最容易解释。我将向您展示我在iPhone 5上制作此GIF的代码:
首先,这是一个帮助函数,该函数采用大小和角度,并以该角度返回UIImage红色磁盘的a :
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写入指定URL的:
CGImageDestination
CGImageDestinationRef destination = CGImageDestinationCreateWithURL((__bridge CFURLRef)fileURL, kUTTypeGIF, kFrameCount, NULL); CGImageDestinationSetProperties(destination, (__bridge CFDictionaryRef)fileProperties);
我发现,通过fileProperties作为最后一个参数CGImageDestinationCreateWithURL确实 没有 工作。您必须使用CGImageDestinationSetProperties。
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); }
如果在模拟器上运行它,则可以从调试控制台复制URL,然后将其粘贴到浏览器中以查看图像。如果在设备上运行它,则可以使用Xcode Organizer窗口从设备下载应用程序沙箱并查看图像。或者,您可以使用类似的应用程序iExplorer来直接浏览设备的文件系统。(这不需要越狱。)
iExplorer
我在运行iOS 6.1的iPhone 5上进行了测试,但是我认为代码应该可以追溯到iOS 4.0。
为了方便复制,我将所有代码都放在了要点中。