您可以使用 Image I/O 框架(它是 iOS SDK 的一部分)创建动画 GIF。您还需要包含MobileCoreServices
定义 GIF 类型常量的框架。您需要将这些框架添加到您的目标中,并将它们的标题导入您要创建动画 GIF 的文件中,如下所示:
#import <ImageIO/ImageIO.h>
#import <MobileCoreServices/MobileCoreServices.h>
用例子来解释是最容易的。我将向您展示我用来在 iPhone 5 上制作此 GIF 的代码:
首先,这是一个辅助函数,它接受一个大小和一个角度,并以该角度返回UIImage
红色圆盘的 a:
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 的方法:
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);
}
如果您在模拟器上运行它,您可以从调试控制台复制 URL 并将其粘贴到浏览器中以查看图像。如果您在设备上运行它,您可以使用 Xcode Organizer 窗口从设备下载应用程序沙箱并查看图像。或者您可以使用这样的应用程序iExplorer
,让您直接浏览设备的文件系统。(这不需要越狱。)
我在运行 iOS 6.1 的 iPhone 5 上对此进行了测试,但我相信代码应该可以追溯到 iOS 4.0。
我已将所有代码放在此要点中,以便于复制。