iOS_ImageI/O學(xué)習(xí)

? ? ? 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)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容