iOS_ImageI/O学习

      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图片

这些功能在其他文章中展现

推荐阅读更多精彩内容