ImageIO框架提供了读取与写入数据的基本方法,使用它可以直接获取到图片文件的内容数据,ImageIO框架包含6个头文件;
CGImageSource.h:负责读取图片的数据;
CGImageDestination.h:负责写入图片数据。
CGImageMetadata.h: 图片文件元数据类。
CGImageProperties:定义了框架中使用的字符串常量和宏。
CGImageIOBase.h: 预处理逻辑。
一、CGImageSource
CGImageSource类的主要作用是用来读取图片数据,在平时开发中我们使用的最多的可能是UIImage类,UIImage是iOS系统UI中用于构建图像对象的类,但是其中只有图像数据,实际上一个图片文件中存储的除了图像数据外,还有一些地理位置、设备类型、时间等信息,除此之外,一个图片文件中可能存储的也不只一张图像(例如gif文件)。CGImageSource就是这样的一个抽象图片数据示例,从其中可以获取到我们所关心的所有数据。
NSString* path = [[NSBundlemainBundle]pathForResource:@"timg"ofType:@"jpeg"];
NSURL* url = [NSURLfileURLWithPath:path];
CGImageRefmyImage =NULL;
CGImageSourceRef myImageSource =CGImageSourceCreateWithURL((CFURLRef)url,NULL);;//通过文件路径创建CGImageSource对象myImageSource //获取第一张图片myImage=CGImageSourceCreateImageAtIndex(myImageSource,0,NULL);
CFRelease(myImageSource);
UIImageView* image = [[UIImageViewalloc]initWithFrame:CGRectMake(0,0,200,200)];
image.image = [UIImageimageWithCGImage:myImage];
[self.view addSubview:image];
除了上面的创建方法,还有:CGImageSourceCreateWithDataProvider,CGImageSourceCreateWithData,两个方法可以创建CGImageSource对象。这两个方法中都需要传入一个CFDictionaryRef类型的字典。可以配置的键值意义如下:
const CFStringRef kCGImageSourceTypeIdentifierHint:设置一个预期的图片文件格式,jpg、png等字符串类型。
const CFStringRef kCGImageSourceShouldCache;是否以解码方式读取数据,默认为kCFBooleanTure 如果为true,在读取时候解码,如果为false,在渲染时候解码。
const CFStringRef kCGImageSourceCreateThumbnailFromImageIfAbsent;如果不存在缩略图就创建一个
const CFStringRef kCGImageSourceCreateThumbnailFromImageAlways;不论是否存在都创建缩略图。
const CFStringRef kCGImageSourceThumbnailMaxPixelSize;设置缩略图的宽高尺寸,CFNumber值
const CFStringRef kCGImageSourceCreateThumbnailWithTransform;设置缩略图是否进行Transfrom变换。
CFTypeID CGImageSourceGetTypeID(void)//获取CGImageSource类在CoreFundation框架中的id;
CFArrayRef __nonnullCGImageSourceCopyTypeIdentifiers(void)//获取所支持的图片格式数组;
CFStringRef __nullableCGImageSourceGetType(CGImageSourceRef__nonnullisrc);//获取CGImageSource对象的图片格式//
size_t CGImageSourceGetCount(CGImageSourceRef__nonnullisrc);获取CGImageSource中的图片张数 不包括缩略图//
获取CGImageSource的文件信息/*
字典参数可配置的键值对与创建CGImageSource所传参数意义一致
返回的字典中的键值意义后面介绍
*/CFDictionaryRef__nullableCGImageSourceCopyProperties(CGImageSourceRef__nonnullisrc,CFDictionaryRef__nullableoptions);//获取CGImageSource中某个图像的附加数据
/*index参数设置获取第几张图像 options参数可配置的键值对与创建CGImageSource所传参数意义一致
返回的字典中的键值意义后面介绍
CFDictionaryRef __nullableCGImageSourceCopyPropertiesAtIndex(CGImageSourceRef__nonnullisrc, size_t index,CFDictionaryRef__nullableoptions);*/
/*/获取图片的元数据信息 CGImageMetadataRef类是图像原数据的抽象CGImageMetadataRef__nullableCGImageSourceCopyMetadataAtIndex(CGImageSourceRef__nonnullisrc, size_t index,CFDictionaryRef__nullableoptions);*/
/*/获取CGImageSource中的图片数据
CGImageRef __nullableCGImageSourceCreateImageAtIndex(CGImageSourceRef__nonnullisrc, size_t index,CFDictionaryRef__nullableoptions);*/
/*删除一个指定索引图像的缓存voidCGImageSourceRemoveCacheAtIndex(CGImageSourceRef__nonnullisrc, size_t index);/*
/*获取某一帧图片的缩略图
CGImageRef __nullableCGImageSourceCreateThumbnailAtIndex(CGImageSourceRef__nonnullisrc, size_t index,CFDictionaryRef__nullableoptions);/*
/*创建一个空的CGImageSource容器,逐步加载大图片CGImageSourceRef__nonnullCGImageSourceCreateIncremental(CFDictionaryRef__nullableoptions);*/
/*使用新的数据更新CGImageSource容器voidCGImageSourceUpdateData(CGImageSourceRef__nonnullisrc,CFDataRef__nonnulldata,boolfinal);*/
/*更新数据提供器来填充CGImageSource容器void CGImageSourceUpdateDataProvider(CGImageSourceRef__nonnullisrc,CGDataProviderRef__nonnullprovider,boolfinal);*/
/*获取当前CGImageSource的状态/*
CGImageSourceStatus枚举意义:
typedef CF_ENUM(int32_t, CGImageSourceStatus) {
kCGImageStatusUnexpectedEOF = -5, //文件结尾出错
kCGImageStatusInvalidData = -4, //数据无效
kCGImageStatusUnknownType = -3, //未知的图片类型
kCGImageStatusReadingHeader = -2, //读标题过程中
kCGImageStatusIncomplete = -1, //操作不完整
kCGImageStatusComplete = 0 //操作完整
};
*/CGImageSourceStatusCGImageSourceGetStatus(CGImageSourceRef__nonnullisrc);//同上,获取某一个图片的状态CGImageSourceStatusCGImageSourceGetStatusAtIndex(CGImageSourceRef__nonnullisrc, size_t index);
二、CGImageDestination
//创建存储路径
NSArray*paths=NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES);
NSString*newPath = [paths.firstObject stringByAppendingPathComponent:[NSStringstringWithFormat:@"image.png"]];
CFURLRef URL =CFURLCreateWithFileSystemPath(kCFAllocatorDefault,(CFStringRef)newPath,
kCFURLPOSIXPathStyle,false);
//创建CGImageDestination对象
CGImageDestinationRef myImageDest =CGImageDestinationCreateWithURL(URL,CFSTR("public.png"),1,NULL);
UIImage* image = [UIImageimageNamed:@"timg.jpeg"];
//写入图片
CGImageDestinationAddImage(myImageDest, image.CGImage,NULL);
CGImageDestinationFinalize(myImageDest);
CFRelease(myImageDest);
//创建CGImageDestination对象
CGImageDestinationRef myImageDest =CGImageDestinationCreateWithURL(URL,CFSTR("public.png"),1,NULL);
UIImage* image = [UIImageimageNamed:@"timg.jpeg"];//写入图片CGImageDestinationAddImage(myImageDest, image.CGImage,NULL);
CGImageDestinationFinalize(myImageDest);
CFRelease(myImageDest);
//将图片数据写入数据消费者
CGImageDestinationRef __nullableCGImageDestinationCreateWithDataConsumer(CGDataConsumerRef__nonnullconsumer,CFStringRef__nonnulltype, size_t count,CFDictionaryRef__nullableoptions);
//将图片数据写入DataCGImageDestinationRef__nullableCGImageDestinationCreateWithData(CFMutableDataRef__nonnulldata,CFStringRef__nonnulltype, size_t count,CFDictionaryRef__nullableoptions);
//获取CGImageDestination的CFTypeID
CFTypeID CGImageDestinationGetTypeID(void);
//获取CGImageDestination所支持的图片文件类型/*
目前支持如下:iOS10.1
(
"public.jpeg",
"public.png",
"com.compuserve.gif",
"public.tiff",
"public.jpeg-2000",
"com.microsoft.ico",
"com.microsoft.bmp",
"com.adobe.photoshop-image",
"com.adobe.pdf",
"com.truevision.tga-image",
"com.ilm.openexr-image",
"public.pbm",
"public.pvr",
"org.khronos.astc",
"org.khronos.ktx",
"com.microsoft.dds",
"com.apple.rjpeg"
)
*/
CFArrayRef __nonnullCGImageDestinationCopyTypeIdentifiers(void);//设置图片文件属性/*
可以设置的键值对意义如下:
const CFStringRef kCGImageDestinationLossyCompressionQuality; //设置压缩质量 0-1之间的cfnumberref值
const CFStringRef kCGImageDestinationBackgroundColor; //将图片数据写为无alpha通道时的默认背景色 cgcolor值
*/
void CGImageDestinationSetProperties(CGImageDestinationRef__nonnullidst,CFDictionaryRef__nullableproperties);
//向CGImageDestination中添加一张图片 其中的option参数意义和上面一致,设置此图片的质量与无alpha默认背景色voidCGImageDestinationAddImage(CGImageDestinationRef__nonnullidst,CGImageRef__nonnullimage,CFDictionaryRef__nullableproperties);
//通过CGImageSource对象来向CGImageDestination中添加图片void CGImageDestinationAddImageFromSource(CGImageDestinationRef__nonnullidst,CGImageSourceRef__nonnullisrc, size_t index,CFDictionaryRef__nullableproperties);
//进行写入操作 执行此方法后 不可以在写入其他信息boolCGImageDestinationFinalize(CGImageDestinationRef__nonnullidst);//添加图片元信息voidCGImageDestinationAddImageAndMetadata(CGImageDestinationRef__nonnullidst,CGImageRef__nonnullimage,CGImageMetadataRef__nullablemetadata,CFDictionaryRef__nullableoptions);
//将CGImageSource信息拷贝进CGImageDestination/*
options参数可以用来添加元信息
*/boolCGImageDestinationCopyImageSource(CGImageDestinationRef__nonnullidst,CGImageSourceRef__nonnullisrc,CFDictionaryRef__nullableoptions, __nullableCFErrorRef* __nullableerr);
//设置元信息 需要设置为CGImageMetadataRef对象
const CFStringRef kCGImageDestinationMetadata;
//是否将CGImageSource的元信息信息合并操作 默认为kCFBooleanFalse
const CFStringRef kCGImageDestinationMergeMetadata;
//XMP数据是否不被写入 默认为kCFBooleanFalse
const CFStringRef kCGImageMetadataShouldExcludeXMP;
//GPS信息是否不被写入 默认为kCFBooleanFalse
const CFStringRef kCGImageMetadataShouldExcludeGPS;
//更新元数据的时间值 需要设置为CFStringRef或者CFDateRef
const CFStringRef kCGImageDestinationDateTime;
//更新元数据的方向值 需要设置为NSNumber1-8
const CFStringRef kCGImageDestinationOrientation;
三、关于CGImageMetadata
前面我们很多次提到元数据,CGImageMetadata类就是元数据的抽象,其中封装了一些方法供开发者读取或写入元数据信息。奇怪的是Apple的官方文档与API文档中并没有CGImageMetadata的介绍与解释,博客中本部分的内容,多出自作者的理解。
前边介绍,CGImageSource中有获取图片元数据的方法,CGImageDestination中也有写入图片元数据的方法,元数据中抽象出的CGImageMetadataTag是对具体数据内容的封装。CGImageMetadata解析如下:
//获取CGImageMetadata类的CFTypeID
CFTypeID CGImageMetadataGetTypeID(void);
//创建一个空的可变的CGImageMetadata对象CGMutableImageMetadataRef
__nonnull CGImageMetadataCreateMutable(void);
//拷贝一个可变的CGImageMetadata对象CGMutableImageMetadataRef
__nullable CGImageMetadataCreateMutableCopy(CGImageMetadataRef__nonnullmetadata);
//获取CGImageMetadataTag类的CFTypeID CFTypeID
CGImageMetadataTagGetTypeID(void);
//创建一个CGImageMetadataTag对象/*
这个方法比较复杂
xmlns参数设置命名空间
prefix参数设置命名空间的缩写或前缀
name参数设置CGImageMetadataTag的名称
type参数设置CGImageMetadataTag对应值的类型
value参数设置CGImageMetadataTag的对应值
*/CGImageMetadataTagRef__nullableCGImageMetadataTagCreate(CFStringRef__nonnullxmlns,CFStringRef__nullableprefix,CFStringRef__nonnullname,CGImageMetadataTypetype,CFTypeRef__nonnullvalue);
获取到CGImageMetadataTag后,可以通过如下方法来获取其中封装的信息:
//获取标签的命名空间CFStringRef__nullableCGImageMetadataTagCopyNamespace(CGImageMetadataTagRef__nonnulltag);
//获取标签的命名空间前缀CFStringRef__nullableCGImageMetadataTagCopyPrefix(CGImageMetadataTagRef__nonnulltag);
//获取标签名称CFStringRef__nullableCGImageMetadataTagCopyName(CGImageMetadataTagRef__nonnulltag);
//获取标签的值CFTypeRef__nullableCGImageMetadataTagCopyValue(CGImageMetadataTagRef__nonnulltag);
//获取标签值的类型CGImageMetadataTypeCGImageMetadataTagGetType(CGImageMetadataTagRef__nonnulltag);
//获取标签的Qualifier数组CFArrayRef__nullableCGImageMetadataTagCopyQualifiers(CGImageMetadataTagRef__nonnulltag);
下面这些方法用于向CGImageMetadata中添加标签或者获取标签:
//获取CGImageMetadata中的所有标签CFArrayRef__nullableCGImageMetadataCopyTags(CGImageMetadataRef__nonnullmetadata);
//通过路径查找特殊的标签CGImageMetadataTagRef__nullableCGImageMetadataCopyTagWithPath(CGImageMetadataRef__nonnullmetadata,CGImageMetadataTagRef__nullableparent,CFStringRef__nonnullpath);
//通过路径查找特殊标签的值CFStringRef__nullableCGImageMetadataCopyStringValueWithPath(CGImageMetadataRef__nonnullmetadata,CGImageMetadataTagRef__nullableparent,CFStringRef__nonnullpath);
//为一个前缀注册一个命名空间boolCGImageMetadataRegisterNamespaceForPrefix(CGMutableImageMetadataRef__nonnullmetadata,CFStringRef__nonnullxmlns,CFStringRef__nonnullprefix, __nullableCFErrorRef* __nullableerr);
//通过路径为CGImageMetadata设置标签boolCGImageMetadataSetTagWithPath(CGMutableImageMetadataRef__nonnullmetadata,CGImageMetadataTagRef__nullableparent,CFStringRef__nonnullpath,CGImageMetadataTagRef__nonnulltag);
//通过路径为CGImageMetadata设置标签的值boolCGImageMetadataSetValueWithPath(CGMutableImageMetadataRef__nonnullmetadata,CGImageMetadataTagRef__nullableparent,CFStringRef__nonnullpath,CFTypeRef__nonnullvalue);
//通过路径移除一个标签boolCGImageMetadataRemoveTagWithPath(CGMutableImageMetadataRef__nonnullmetadata,CGImageMetadataTagRef__nullableparent,CFStringRef__nonnullpath);
//对标签进行枚举voidCGImageMetadataEnumerateTagsUsingBlock(CGImageMetadataRef__nonnullmetadata,CFStringRef__nullablerootPath,CFDictionaryRef__nullableoptions,CGImageMetadataTagBlock__nonnullblock);
CGImageSourceCopyProperties方法与CGImageSourceCopyPropertiesAtIndex方法都会返回一个字典
字典意义从名字中就就可以看出来。
CGImageSourceCopyPropertiesAtIndex方法中可能包含的特殊键:
//像素高度constCFStringRefkCGImagePropertyPixelHeight;
//像素宽度constCFStringRefkCGImagePropertyPixelWidth;
//DPI高度constCFStringRefkCGImagePropertyDPIHeight;
//DPI宽度constCFStringRefkCGImagePropertyDPIWidth;
//颜色位数constCFStringRefkCGImagePropertyDepth;
//图片的显示方向/*
对应Number值
* 1 = 左上到右下.
* 2 = 右上到左下.
* 3 = 右下到左上.
* 4 = 左下到右上.
* 5 = 行列置换 左上到右下.
* 6 = 行列置换 右上到左下.
* 7 = 行列置换 右下到左上.
* 8 = 行列置换 左下到右上.
*/constCFStringRefkCGImagePropertyOrientation;
//颜色是否支持浮点数constCFStringRefkCGImagePropertyIsFloat;
//图像是否包含像素样本constCFStringRefkCGImagePropertyIsIndexed;
//图像是否包含alpha通道constCFStringRefkCGImagePropertyHasAlpha;
//图像的颜色模式constCFStringRefkCGImagePropertyColorModel;
//嵌入图片的ICC配置文件名称constCFStringRefkCGImagePropertyProfileName;
三、ImageIO框架在实际开发中的几个应用
1.显示特殊格式的图片
在平时开发中,我们通常使用UIImage来读取图片,UIImage支持的图片包括png与jpg等,但是类似windows系统的ico图标,UIImage默认是无法显示的,可以通过ImageIO框架来在iOS系统中使用ico图标,示例如下:
NSString* path = [[NSBundlemainBundle]pathForResource:@"image"ofType:@"ico"];
NSURL* url = [NSURLfileURLWithPath:path];
CGImageRefmyImage =NULL;
CGImageSourceRef myImageSource;
CFDictionaryRef myOptions =NULL;
myImageSource =CGImageSourceCreateWithURL((CFURLRef)url,NULL);
myImage =CGImageSourceCreateImageAtIndex(myImageSource,0,NULL);
CFRelease(myImageSource);
UIImageView* image = [[UIImageView alloc]initWithFrame:CGRectMake(0,0,200,200)];
image.image = [UIImage imageWithCGImage:myImage];
2、读取数码相机拍摄图片地理位置、时间信息。
3、对相册中的图片地理位置,时间等信息进行自定义修改。
4、将自定义格式的图片数据写入本地文件
5、播放gif图片
这些功能在其他文章中展现