? ? ? ImageIO框架提供了讀取與寫入數(shù)據(jù)的基本方法,使用它可以直接獲取到圖片文件的內(nèi)容數(shù)據(jù),ImageIO框架包含6個(gè)頭文件;
CGImageSource.h:負(fù)責(zé)讀取圖片的數(shù)據(jù);
CGImageDestination.h:負(fù)責(zé)寫入圖片數(shù)據(jù)。
CGImageMetadata.h: ? ?圖片文件元數(shù)據(jù)類。
CGImageProperties:定義了框架中使用的字符串常量和宏。
CGImageIOBase.h: ?預(yù)處理邏輯。
一、CGImageSource
? ? ? ? CGImageSource類的主要作用是用來(lái)讀取圖片數(shù)據(jù),在平時(shí)開發(fā)中我們使用的最多的可能是UIImage類,UIImage是iOS系統(tǒng)UI中用于構(gòu)建圖像對(duì)象的類,但是其中只有圖像數(shù)據(jù),實(shí)際上一個(gè)圖片文件中存儲(chǔ)的除了圖像數(shù)據(jù)外,還有一些地理位置、設(shè)備類型、時(shí)間等信息,除此之外,一個(gè)圖片文件中可能存儲(chǔ)的也不只一張圖像(例如gif文件)。CGImageSource就是這樣的一個(gè)抽象圖片數(shù)據(jù)示例,從其中可以獲取到我們所關(guān)心的所有數(shù)據(jù)。
NSString* path = [[NSBundlemainBundle]pathForResource:@"timg"ofType:@"jpeg"];
NSURL* url = [NSURLfileURLWithPath:path];
CGImageRefmyImage =NULL;
CGImageSourceRef? myImageSource =CGImageSourceCreateWithURL((CFURLRef)url,NULL);;//通過文件路徑創(chuàng)建CGImageSource對(duì)象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];
除了上面的創(chuàng)建方法,還有:CGImageSourceCreateWithDataProvider,CGImageSourceCreateWithData,兩個(gè)方法可以創(chuàng)建CGImageSource對(duì)象。這兩個(gè)方法中都需要傳入一個(gè)CFDictionaryRef類型的字典??梢耘渲玫逆I值意義如下:
const ?CFStringRef ?kCGImageSourceTypeIdentifierHint:設(shè)置一個(gè)預(yù)期的圖片文件格式,jpg、png等字符串類型。
const CFStringRef? kCGImageSourceShouldCache;是否以解碼方式讀取數(shù)據(jù),默認(rèn)為kCFBooleanTure 如果為true,在讀取時(shí)候解碼,如果為false,在渲染時(shí)候解碼。
const CFStringRef ?kCGImageSourceCreateThumbnailFromImageIfAbsent;如果不存在縮略圖就創(chuàng)建一個(gè)
const CFStringRef ?kCGImageSourceCreateThumbnailFromImageAlways;不論是否存在都創(chuàng)建縮略圖。
const CFStringRef ?kCGImageSourceThumbnailMaxPixelSize;設(shè)置縮略圖的寬高尺寸,CFNumber值
const CFStringRef ?kCGImageSourceCreateThumbnailWithTransform;設(shè)置縮略圖是否進(jìn)行Transfrom變換。
CFTypeID CGImageSourceGetTypeID(void)//獲取CGImageSource類在CoreFundation框架中的id;
CFArrayRef __nonnullCGImageSourceCopyTypeIdentifiers(void)//獲取所支持的圖片格式數(shù)組;
CFStringRef __nullableCGImageSourceGetType(CGImageSourceRef__nonnullisrc);//獲取CGImageSource對(duì)象的圖片格式//
size_t CGImageSourceGetCount(CGImageSourceRef__nonnullisrc);獲取CGImageSource中的圖片張數(shù) 不包括縮略圖//
獲取CGImageSource的文件信息/*
字典參數(shù)可配置的鍵值對(duì)與創(chuàng)建CGImageSource所傳參數(shù)意義一致
返回的字典中的鍵值意義后面介紹
*/CFDictionaryRef__nullableCGImageSourceCopyProperties(CGImageSourceRef__nonnullisrc,CFDictionaryRef__nullableoptions);//獲取CGImageSource中某個(gè)圖像的附加數(shù)據(jù)
/*index參數(shù)設(shè)置獲取第幾張圖像 options參數(shù)可配置的鍵值對(duì)與創(chuàng)建CGImageSource所傳參數(shù)意義一致
返回的字典中的鍵值意義后面介紹
CFDictionaryRef __nullableCGImageSourceCopyPropertiesAtIndex(CGImageSourceRef__nonnullisrc, size_t index,CFDictionaryRef__nullableoptions);*/
/*/獲取圖片的元數(shù)據(jù)信息 CGImageMetadataRef類是圖像原數(shù)據(jù)的抽象CGImageMetadataRef__nullableCGImageSourceCopyMetadataAtIndex(CGImageSourceRef__nonnullisrc, size_t index,CFDictionaryRef__nullableoptions);*/
/*/獲取CGImageSource中的圖片數(shù)據(jù)?
CGImageRef __nullableCGImageSourceCreateImageAtIndex(CGImageSourceRef__nonnullisrc, size_t index,CFDictionaryRef__nullableoptions);*/
/*刪除一個(gè)指定索引圖像的緩存voidCGImageSourceRemoveCacheAtIndex(CGImageSourceRef__nonnullisrc, size_t index);/*
/*獲取某一幀圖片的縮略圖
CGImageRef __nullableCGImageSourceCreateThumbnailAtIndex(CGImageSourceRef__nonnullisrc, size_t index,CFDictionaryRef__nullableoptions);/*
/*創(chuàng)建一個(gè)空的CGImageSource容器,逐步加載大圖片CGImageSourceRef__nonnullCGImageSourceCreateIncremental(CFDictionaryRef__nullableoptions);*/
/*使用新的數(shù)據(jù)更新CGImageSource容器voidCGImageSourceUpdateData(CGImageSourceRef__nonnullisrc,CFDataRef__nonnulldata,boolfinal);*/
/*更新數(shù)據(jù)提供器來(lái)填充CGImageSource容器void CGImageSourceUpdateDataProvider(CGImageSourceRef__nonnullisrc,CGDataProviderRef__nonnullprovider,boolfinal);*/
/*獲取當(dāng)前CGImageSource的狀態(tài)/*
CGImageSourceStatus枚舉意義:
typedef CF_ENUM(int32_t, CGImageSourceStatus) {
kCGImageStatusUnexpectedEOF = -5, //文件結(jié)尾出錯(cuò)
kCGImageStatusInvalidData = -4,? //數(shù)據(jù)無(wú)效
kCGImageStatusUnknownType = -3,? //未知的圖片類型
kCGImageStatusReadingHeader = -2, //讀標(biāo)題過程中
kCGImageStatusIncomplete = -1,? ? //操作不完整
kCGImageStatusComplete = 0? ? ? ? //操作完整
};
*/CGImageSourceStatusCGImageSourceGetStatus(CGImageSourceRef__nonnullisrc);//同上,獲取某一個(gè)圖片的狀態(tài)CGImageSourceStatusCGImageSourceGetStatusAtIndex(CGImageSourceRef__nonnullisrc, size_t index);
二、CGImageDestination
//創(chuàng)建存儲(chǔ)路徑
NSArray*paths=NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES);
NSString*newPath = [paths.firstObject stringByAppendingPathComponent:[NSStringstringWithFormat:@"image.png"]];
CFURLRef URL =CFURLCreateWithFileSystemPath(kCFAllocatorDefault,(CFStringRef)newPath,
kCFURLPOSIXPathStyle,false);
//創(chuàng)建CGImageDestination對(duì)象
CGImageDestinationRef myImageDest =CGImageDestinationCreateWithURL(URL,CFSTR("public.png"),1,NULL);
UIImage* image = [UIImageimageNamed:@"timg.jpeg"];
//寫入圖片
CGImageDestinationAddImage(myImageDest, image.CGImage,NULL);
CGImageDestinationFinalize(myImageDest);
CFRelease(myImageDest);
//創(chuàng)建CGImageDestination對(duì)象
CGImageDestinationRef myImageDest =CGImageDestinationCreateWithURL(URL,CFSTR("public.png"),1,NULL);
UIImage* image = [UIImageimageNamed:@"timg.jpeg"];//寫入圖片CGImageDestinationAddImage(myImageDest, image.CGImage,NULL);
CGImageDestinationFinalize(myImageDest);
CFRelease(myImageDest);
//將圖片數(shù)據(jù)寫入數(shù)據(jù)消費(fèi)者
CGImageDestinationRef __nullableCGImageDestinationCreateWithDataConsumer(CGDataConsumerRef__nonnullconsumer,CFStringRef__nonnulltype, size_t count,CFDictionaryRef__nullableoptions);
//將圖片數(shù)據(jù)寫入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);//設(shè)置圖片文件屬性/*
可以設(shè)置的鍵值對(duì)意義如下:
const CFStringRef kCGImageDestinationLossyCompressionQuality; //設(shè)置壓縮質(zhì)量 0-1之間的cfnumberref值
const CFStringRef kCGImageDestinationBackgroundColor;? //將圖片數(shù)據(jù)寫為無(wú)alpha通道時(shí)的默認(rèn)背景色 cgcolor值
*/
void CGImageDestinationSetProperties(CGImageDestinationRef__nonnullidst,CFDictionaryRef__nullableproperties);
//向CGImageDestination中添加一張圖片 其中的option參數(shù)意義和上面一致,設(shè)置此圖片的質(zhì)量與無(wú)alpha默認(rèn)背景色voidCGImageDestinationAddImage(CGImageDestinationRef__nonnullidst,CGImageRef__nonnullimage,CFDictionaryRef__nullableproperties);
//通過CGImageSource對(duì)象來(lái)向CGImageDestination中添加圖片void CGImageDestinationAddImageFromSource(CGImageDestinationRef__nonnullidst,CGImageSourceRef__nonnullisrc, size_t index,CFDictionaryRef__nullableproperties);
//進(jìn)行寫入操作 執(zhí)行此方法后 不可以在寫入其他信息boolCGImageDestinationFinalize(CGImageDestinationRef__nonnullidst);//添加圖片元信息voidCGImageDestinationAddImageAndMetadata(CGImageDestinationRef__nonnullidst,CGImageRef__nonnullimage,CGImageMetadataRef__nullablemetadata,CFDictionaryRef__nullableoptions);
//將CGImageSource信息拷貝進(jìn)CGImageDestination/*
options參數(shù)可以用來(lái)添加元信息
*/boolCGImageDestinationCopyImageSource(CGImageDestinationRef__nonnullidst,CGImageSourceRef__nonnullisrc,CFDictionaryRef__nullableoptions, __nullableCFErrorRef* __nullableerr);
//設(shè)置元信息 需要設(shè)置為CGImageMetadataRef對(duì)象
const CFStringRef kCGImageDestinationMetadata;
//是否將CGImageSource的元信息信息合并操作 默認(rèn)為kCFBooleanFalse
const CFStringRef kCGImageDestinationMergeMetadata;
//XMP數(shù)據(jù)是否不被寫入 默認(rèn)為kCFBooleanFalse?
const CFStringRef kCGImageMetadataShouldExcludeXMP;
//GPS信息是否不被寫入 默認(rèn)為kCFBooleanFalse
const CFStringRef kCGImageMetadataShouldExcludeGPS;
//更新元數(shù)據(jù)的時(shí)間值 需要設(shè)置為CFStringRef或者CFDateRef?
const CFStringRef kCGImageDestinationDateTime;
//更新元數(shù)據(jù)的方向值 需要設(shè)置為NSNumber1-8
const CFStringRef kCGImageDestinationOrientation;
三、關(guān)于CGImageMetadata
? ? ? ?前面我們很多次提到元數(shù)據(jù),CGImageMetadata類就是元數(shù)據(jù)的抽象,其中封裝了一些方法供開發(fā)者讀取或?qū)懭朐獢?shù)據(jù)信息。奇怪的是Apple的官方文檔與API文檔中并沒有CGImageMetadata的介紹與解釋,博客中本部分的內(nèi)容,多出自作者的理解。
? ? ? ? 前邊介紹,CGImageSource中有獲取圖片元數(shù)據(jù)的方法,CGImageDestination中也有寫入圖片元數(shù)據(jù)的方法,元數(shù)據(jù)中抽象出的CGImageMetadataTag是對(duì)具體數(shù)據(jù)內(nèi)容的封裝。CGImageMetadata解析如下:
//獲取CGImageMetadata類的CFTypeID
CFTypeID CGImageMetadataGetTypeID(void);
//創(chuàng)建一個(gè)空的可變的CGImageMetadata對(duì)象CGMutableImageMetadataRef?
__nonnull CGImageMetadataCreateMutable(void);
//拷貝一個(gè)可變的CGImageMetadata對(duì)象CGMutableImageMetadataRef
__nullable CGImageMetadataCreateMutableCopy(CGImageMetadataRef__nonnullmetadata);
//獲取CGImageMetadataTag類的CFTypeID CFTypeID?
CGImageMetadataTagGetTypeID(void);
//創(chuàng)建一個(gè)CGImageMetadataTag對(duì)象/*
這個(gè)方法比較復(fù)雜
xmlns參數(shù)設(shè)置命名空間
prefix參數(shù)設(shè)置命名空間的縮寫或前綴
name參數(shù)設(shè)置CGImageMetadataTag的名稱
type參數(shù)設(shè)置CGImageMetadataTag對(duì)應(yīng)值的類型
value參數(shù)設(shè)置CGImageMetadataTag的對(duì)應(yīng)值
*/CGImageMetadataTagRef__nullableCGImageMetadataTagCreate(CFStringRef__nonnullxmlns,CFStringRef__nullableprefix,CFStringRef__nonnullname,CGImageMetadataTypetype,CFTypeRef__nonnullvalue);
獲取到CGImageMetadataTag后,可以通過如下方法來(lái)獲取其中封裝的信息:
//獲取標(biāo)簽的命名空間CFStringRef__nullableCGImageMetadataTagCopyNamespace(CGImageMetadataTagRef__nonnulltag);
//獲取標(biāo)簽的命名空間前綴CFStringRef__nullableCGImageMetadataTagCopyPrefix(CGImageMetadataTagRef__nonnulltag);
//獲取標(biāo)簽名稱CFStringRef__nullableCGImageMetadataTagCopyName(CGImageMetadataTagRef__nonnulltag);
//獲取標(biāo)簽的值CFTypeRef__nullableCGImageMetadataTagCopyValue(CGImageMetadataTagRef__nonnulltag);
//獲取標(biāo)簽值的類型CGImageMetadataTypeCGImageMetadataTagGetType(CGImageMetadataTagRef__nonnulltag);
//獲取標(biāo)簽的Qualifier數(shù)組CFArrayRef__nullableCGImageMetadataTagCopyQualifiers(CGImageMetadataTagRef__nonnulltag);
下面這些方法用于向CGImageMetadata中添加標(biāo)簽或者獲取標(biāo)簽:
//獲取CGImageMetadata中的所有標(biāo)簽CFArrayRef__nullableCGImageMetadataCopyTags(CGImageMetadataRef__nonnullmetadata);
//通過路徑查找特殊的標(biāo)簽CGImageMetadataTagRef__nullableCGImageMetadataCopyTagWithPath(CGImageMetadataRef__nonnullmetadata,CGImageMetadataTagRef__nullableparent,CFStringRef__nonnullpath);
//通過路徑查找特殊標(biāo)簽的值CFStringRef__nullableCGImageMetadataCopyStringValueWithPath(CGImageMetadataRef__nonnullmetadata,CGImageMetadataTagRef__nullableparent,CFStringRef__nonnullpath);
//為一個(gè)前綴注冊(cè)一個(gè)命名空間boolCGImageMetadataRegisterNamespaceForPrefix(CGMutableImageMetadataRef__nonnullmetadata,CFStringRef__nonnullxmlns,CFStringRef__nonnullprefix, __nullableCFErrorRef* __nullableerr);
//通過路徑為CGImageMetadata設(shè)置標(biāo)簽boolCGImageMetadataSetTagWithPath(CGMutableImageMetadataRef__nonnullmetadata,CGImageMetadataTagRef__nullableparent,CFStringRef__nonnullpath,CGImageMetadataTagRef__nonnulltag);
//通過路徑為CGImageMetadata設(shè)置標(biāo)簽的值boolCGImageMetadataSetValueWithPath(CGMutableImageMetadataRef__nonnullmetadata,CGImageMetadataTagRef__nullableparent,CFStringRef__nonnullpath,CFTypeRef__nonnullvalue);
//通過路徑移除一個(gè)標(biāo)簽boolCGImageMetadataRemoveTagWithPath(CGMutableImageMetadataRef__nonnullmetadata,CGImageMetadataTagRef__nullableparent,CFStringRef__nonnullpath);
//對(duì)標(biāo)簽進(jìn)行枚舉voidCGImageMetadataEnumerateTagsUsingBlock(CGImageMetadataRef__nonnullmetadata,CFStringRef__nullablerootPath,CFDictionaryRef__nullableoptions,CGImageMetadataTagBlock__nonnullblock);
CGImageSourceCopyProperties方法與CGImageSourceCopyPropertiesAtIndex方法都會(huì)返回一個(gè)字典
字典意義從名字中就就可以看出來(lái)。
CGImageSourceCopyPropertiesAtIndex方法中可能包含的特殊鍵:
//像素高度constCFStringRefkCGImagePropertyPixelHeight;
//像素寬度constCFStringRefkCGImagePropertyPixelWidth;
//DPI高度constCFStringRefkCGImagePropertyDPIHeight;
//DPI寬度constCFStringRefkCGImagePropertyDPIWidth;
//顏色位數(shù)constCFStringRefkCGImagePropertyDepth;
//圖片的顯示方向/*
對(duì)應(yīng)Number值
*? 1? =? 左上到右下.
*? 2? =? 右上到左下.
*? 3? =? 右下到左上.
*? 4? =? 左下到右上.
*? 5? =? 行列置換 左上到右下.
*? 6? =? 行列置換 右上到左下.
*? 7? =? 行列置換 右下到左上.
*? 8? =? 行列置換 左下到右上.
*/constCFStringRefkCGImagePropertyOrientation;
//顏色是否支持浮點(diǎn)數(shù)constCFStringRefkCGImagePropertyIsFloat;
//圖像是否包含像素樣本constCFStringRefkCGImagePropertyIsIndexed;
//圖像是否包含alpha通道constCFStringRefkCGImagePropertyHasAlpha;
//圖像的顏色模式constCFStringRefkCGImagePropertyColorModel;
//嵌入圖片的ICC配置文件名稱constCFStringRefkCGImagePropertyProfileName;
三、ImageIO框架在實(shí)際開發(fā)中的幾個(gè)應(yīng)用
1.顯示特殊格式的圖片
在平時(shí)開發(fā)中,我們通常使用UIImage來(lái)讀取圖片,UIImage支持的圖片包括png與jpg等,但是類似windows系統(tǒng)的ico圖標(biāo),UIImage默認(rèn)是無(wú)法顯示的,可以通過ImageIO框架來(lái)在iOS系統(tǒng)中使用ico圖標(biāo),示例如下:
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、讀取數(shù)碼相機(jī)拍攝圖片地理位置、時(shí)間信息。
3、對(duì)相冊(cè)中的圖片地理位置,時(shí)間等信息進(jìn)行自定義修改。
4、將自定義格式的圖片數(shù)據(jù)寫入本地文件
5、播放gif圖片
這些功能在其他文章中展現(xiàn)