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

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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,772评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,458评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,610评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,640评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,657评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,590评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,962评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,631评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,870评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,611评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,704评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,386评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,969评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,944评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,179评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,742评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,440评论 2 342

推荐阅读更多精彩内容