版本记录
版本号 | 时间 |
---|---|
V1.0 | 2017.10.17 |
前言
ImageIO
框架主要用来读写大多数图像文件格式。 管理颜色和访问图像元数据。接下来几篇我们就详细的解析这个框架。感兴趣的可以看我写的上面几篇。
1. ImageIO框架详细解析(一) —— 基本概览
2. ImageIO框架详细解析(二) —— 使用ImageIO基础
3. ImageIO框架详细解析(三) —— 创建和使用图像源
Working with Image Destinations - Image Destinations使用
图像目的地抽象了数据写任务,消除了通过原始缓冲区管理数据的需要。图像目的地可以表示单个图像或多个图像。它可以包含缩略图和每个图像的属性。在为适当的目标(URL、CFData
对象或Quartz数据消费者)创建一个CGImageDestination
对象后,您可以添加图像数据和设置图像属性。当你完成添加数据时,调用函数CGImageDestinationFinalize。
Setting the Properties of an Image Destination - 设置图像目的地的属性
函数CGImageDestinationSetProperties将属性(键值对)的字典(CFDictionaryRef)添加到图像目标中的图像。虽然设置属性是可选的,但您可能需要设置许多情况。例如,如果您的应用程序允许用户向图像添加关键字或更改饱和度,曝光或其他值,则需要将该信息保存在选项字典中。
Image I / O
定义了一组广泛的键来指定压缩质量,背景合成颜色,Exif字典键,颜色模型值,GIF字典键,尼康和佳能相机键等等。请参阅CGImageProperties Reference参考。
设置字典时,您有两种选择。您可以创建一个CFDictionary
对象,或者您可以创建一个NSDictionary
对象,然后将其转换为CFDictionaryRef,当您将可选字典传递给函数CGImageDestinationSetProperties。 (CFDictionary
和NSDictionary
是可互换的,或自由桥接的。)。Listing 3-1
显示了一个代码片段,为三个属性分配键值对,然后创建一个包含这些属性的字典。因为这是一个代码片段,所以释放代码创建的CFNumber
和CFDictionary
对象的必须调用的没有展示出来。编写代码时,当您不再需要这些对象时,您需要调用CFRelease。
为属性设置键值对时,您需要参考参考文档(请参阅CGImageDestination Reference和CGImageProperties Reference参考)以获取该值的预期数据类型。如Listing 3-1
所示,数值通常需要包装在CFNumber
对象中。当您使用Core Foundation类型作为字典值类型时,您还可以在创建字典时提供回调常数-kCFTypeDictionaryKeyCallBacks
和kCFTypeDictionaryValueCallBacks。 (见CFDictionary Reference。)
// **Listing 3-1** Setting the properties of an image destination
float compression = 1.0; // Lossless compression if available.
int orientation = 4; // Origin is at bottom, left.
CFStringRef myKeys[3];
CFTypeRef myValues[3];
CFDictionaryRef myOptions = NULL;
myKeys[0] = kCGImagePropertyOrientation;
myValues[0] = CFNumberCreate(NULL, kCFNumberIntType, &orientation);
myKeys[1] = kCGImagePropertyHasAlpha;
myValues[1] = kCFBooleanTrue;
myKeys[2] = kCGImageDestinationLossyCompressionQuality;
myValues[2] = CFNumberCreate(NULL, kCFNumberFloatType, &compression);
myOptions = CFDictionaryCreate( NULL, (const void **)myKeys, (const void **)myValues, 3,
&kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
// Release the CFNumber and CFDictionary objects when you no longer need them.
Writing an Image to an Image Destination - 将图像写入图像目的地
要将图像写入目的地,首先需要通过调用 CGImageDestinationCreateWithURL,CGImageDestinationCreateWithData或 CGImageDestinationCreateWithDataConsumer函数创建一个图像目标对象。您需要提供生成的图像文件的UTI。您可以提供UTI或等效常数(如果有的话),见Table 1-1。
创建图像目的地后,可以通过调用CGImageDestinationAddImage
或者 CGImageDestinationAddImageFromSource函数来添加图像。如果图像目的地文件的格式支持多个图像,则可以反复添加图像。Image I / O
完成添加图像,调用函数CGImageDestinationFinalize。一旦完成,您不能再添加任何更多的数据到图像目的地。
Listing 3-2
显示了如何实现一种写入图像文件的方法。虽然此列表显示了如何使用Objective-C方法中的图像目标,但您可以轻松地在过程C函数中创建和使用图像目标。 可选参数包括您要为图像指定的任何属性,如相机或压缩设置。
// **Listing 3-2** A method that writes an image to a URL
- (void) writeCGImage: (CGImageRef) image toURL: (NSURL*) url withType: (CFStringRef) imageType andOptions: (CFDictionaryRef) options
{
CGImageDestinationRef myImageDest = CGImageDestinationCreateWithURL((CFURLRef)url, imageType, 1, nil);
CGImageDestinationAddImage(myImageDest, image, options);
CGImageDestinationFinalize(myImageDest);
CFRelease(myImageDest);
}
Creating an Animated Image - 创建一个动画图像
Image I / O
也可用于创建动画图像。 创建动画图像时,您可以为要添加到图像的每个帧调用CGImageDestinationAddImage。 您还必须指定控制动画执行方式的其他属性。
Listing 3-3
显示了如何创建动画PNG图像。 首先,它创建一对字典来保存动画属性。 第一个字典指定动画PNG在停止在最后一帧之前重复其动画的次数。 第二个字典指定序列中每个帧使用的帧延迟。 创建图像目标后,代码设置目标图像的文件属性,然后一次添加一个帧。 最后,调用CGImageDestinationFinalize方法来完成动画PNG。
// Listing 3-3 Creating an animated PNG file
let loopCount = 1
let frameCount = 60
var fileProperties = NSMutableDictionary()
fileProperties.setObject(kCGImagePropertyPNGDictionary, forKey: NSDictionary(dictionary: [kCGImagePropertyAPNGLoopCount: frameCount]))
var frameProperties = NSMutableDictionary()
frameProperties.setObject(kCGImagePropertyPNGDictionary, forKey: NSDictionary(dictionary: [kCGImagePropertyAPNGDelayTime: 1.0 / Double(frameCount)]))
guard let destination = CGImageDestinationCreateWithURL(fileURL, kUTTypePNG, frameCount, nil) else {
// Provide error handling here.
}
CGImageDestinationSetProperties(destination, fileProperties.copy() as? NSDictionary)
for i in 0..<frameCount {
autoreleasepool {
let radians = M_PI * 2.0 * Double(i) / Double(frameCount)
guard let image = imageForFrame(size: CGSize(width: 300, height: 300)) else {
return
}
CGImageDestinationAddImage(destination, image, frameProperties)
}
}
if !CGImageDestinationFinalize(destination) {
// Provide error handling here.
}
后记
未完,待续~~~