Image I/O編程指南

一、基本的Image I/O使用
Image I/O框架提供了不透明數據類型來讀取圖像數據和寫圖像數據到一個目的地(CGImageSourceRef和CGImageDestinationRef)。它支持很多圖像格式,包括標準web格式、搞動態範圍圖像,和原始相機數據。Image I/O還有許多其他特性:
1)mac平臺上的最快的圖像解碼和編碼。
2)逐步加載圖片的能力。
3)支持圖像元數據。
4)緩存效果。
你可以通過下面的對象來創建image source和image destination:
1)URLs:即CFURLRef對象。
2)Core Foundation對象:CFDataRef和CFmutableDataRef。
3)Quartz data consumer(CGDataConsumerRef)和data provider(CGDataProviderRef)對象。

1、使用Image I/O框架: #import 《ImageIO/ImageIO.h》
2、支持的圖像格式:例如JPEG、JPEG2000、RAW、TIFF、BMP、PNG。在不同的平臺不是所有的格式都支持。你可以調用下列函數來獲得支持的格式:
1)CGImageSourceCopyTypeIdentifiers:返回同一類型修飾符的數組,表示支持的圖像源。
2)CGImageDestinationCopyTypeIdentifiers:返回支持的目的地的Uniform Type Identifiers(UTIs)。

你可以使用CFShow函數來打印結果。
CFArrayRef mySourceTypes = CGImageSourceCopyTypeIdentifiers();
CFShow(mySourceTypes);
CFArrayRef myDestinationTypes = CGImageDestinationCopyTypeIdentifiers();
CFShow(myDestinationTypes);
一般格式是com.apple.pict,public.jpeg,public.tiff等。

二、創建和使用Image Sources
1、從一個Image Source創建一個Image:
下面的例子顯示瞭如何從一個路徑中創建一個image source然後提取出image。當你創建一個image source時,你可以提供一個提示作爲image source file的格式。
當你從image source中創建image時,你必須指定一個index,並且可以提供一個屬性字典來指定一些事情,如是否創建一個縮略圖或是否允許緩存。CGImageSource Reference和CGImageProperties Reference提供了鍵和期待的數據類型的列表。
你需要提供一個index值,因爲一些image file 格式允許多個image存在於一個source file中。對於只有一個image的image source,傳遞0就可以了。你可以通過函數CGImageSourceGetCount來獲得image source file中包含的image的數量。
例子:
CGImageRef MyCreateCGImageFromFile (NSString* path)
{
// Get the URL for the pathname passed to the function.
NSURL *url = [NSURL fileURLWithPath:path];
CGImageRef myImage = NULL;
CGImageSourceRef myImageSource;
CFDictionaryRef myOptions = NULL;
CFStringRef myKeys[2];
CFTypeRef myValues[2];

// Set up options if you want them. The options here are for
// caching the image in a decoded form and for using floating-point
// values if the image format supports them.
myKeys[0] = kCGImageSourceShouldCache;
myValues[0] = (CFTypeRef)kCFBooleanTrue;
myKeys[1] = kCGImageSourceShouldAllowFloat;
myValues[1] = (CFTypeRef)kCFBooleanTrue;
// Create the dictionary
myOptions = CFDictionaryCreate(NULL, (const void **) myKeys,
               (const void **) myValues, 2,
               &kCFTypeDictionaryKeyCallBacks,
               & kCFTypeDictionaryValueCallBacks);
// Create an image source from the URL.
myImageSource = CGImageSourceCreateWithURL((CFURLRef)url, myOptions);
CFRelease(myOptions);
// Make sure the image source exists before continuing
if (myImageSource == NULL){
    fprintf(stderr, "Image source is NULL.");
    return  NULL;
}
// Create an image from the first item in the image source.
myImage = CGImageSourceCreateImageAtIndex(myImageSource,
                                       0,
                                       NULL);

CFRelease(myImageSource);
// Make sure the image exists before continuing
if (myImage == NULL){
     fprintf(stderr, "Image not created from image source.");
     return NULL;
}

return myImage;

}

2、從一個Image Source中創建一個縮略圖
一些image source file包含縮略圖。如果縮略圖沒有準備好,Image I/O給你一些選項來創建他們。你還可以指定一個最大的縮略圖尺寸和是否應用一個transform到縮略圖上。
例子:
CGImageRef MyCreateThumbnailImageFromData (NSData * data, int imageSize)
{
CGImageRef myThumbnailImage = NULL;
CGImageSourceRef myImageSource;
CFDictionaryRef myOptions = NULL;
CFStringRef myKeys[3];
CFTypeRef myValues[3];
CFNumberRef thumbnailSize;

// Create an image source from NSData; no options.
myImageSource = CGImageSourceCreateWithData((CFDataRef)data,
NULL);
// Make sure the image source exists before continuing.
if (myImageSource == NULL){
fprintf(stderr, “Image source is NULL.”);
return NULL;
}

// Package the integer as a CFNumber object. Using CFTypes allows you
// to more easily create the options dictionary later.
thumbnailSize = CFNumberCreate(NULL, kCFNumberIntType, &imageSize);

// Set up the thumbnail options.
myKeys[0] = kCGImageSourceCreateThumbnailWithTransform;
myValues[0] = (CFTypeRef)kCFBooleanTrue;
myKeys[1] = kCGImageSourceCreateThumbnailFromImageIfAbsent;
myValues[1] = (CFTypeRef)kCFBooleanTrue;
myKeys[2] = kCGImageSourceThumbnailMaxPixelSize;
myValues[2] = (CFTypeRef)thumbnailSize;

myOptions = CFDictionaryCreate(NULL, (const void **) myKeys,
(const void **) myValues, 2,
&kCFTypeDictionaryKeyCallBacks,
& kCFTypeDictionaryValueCallBacks);

// Create the thumbnail image using the specified options.
myThumbnailImage = CGImageSourceCreateThumbnailAtIndex(myImageSource,
0,
myOptions);
// Release the options dictionary and the image source
// when you no longer need them.
CFRelease(thumbnailSize);
CFRelease(myOptions);
CFRelease(myImageSource);

// Make sure the thumbnail image exists before continuing.
if (myThumbnailImage == NULL){
fprintf(stderr, “Thumbnail image not created from image source.”);
return NULL;
}

return myThumbnailImage;
}

3、逐步地加載一幅圖像:
如果你有一個很大的圖像,或者正在從網絡上加載圖像數據,你或許就想創建一個incremental image source,然後你就可以一點點地加載圖像數據。你需要執行下面的步驟:
1)創建一個CFData對象來累積圖像數據。
2)創建一個incremental image source,通過調用函數CGImageSourceCreateIncremental。
3)添加image data到CFData對象。
4)調用函數CGImageSourceUpdateData,傳遞CFData對象和一個布爾值(bool數據類型)來指定是否data 參數包含了整個圖像,或只是圖像數據的一部分。在任意一種情況下,data參數都必須包含當前所有的圖像數據。
5)如果你已經累積了足夠的圖像數據,就通過函數CGImageSourceCreateImageAtIndex,來繪製部分圖像,然後release掉。
6)檢查你是否已經有了所有的數據,通過函數CGImageSourceGetStatusAtIndex。如果圖像完成了,函數返回kCGImageStatusComplete。如果沒有完成,就重複3-4步,直到其完成。
7)釋放incremental image source。

4、顯示圖像屬性:
包括image dimensions(大小)、resolution(分辨率)、orientation(方向)、color profile、aperture、metering mode,focal length、creation date、keywords、caption等等。
雖然函數CGImageSourceCopyPropertiesAtIndex可以檢索所有圖像相關的屬性的字典,你還是需要寫代碼來檢索這個字典並顯示信息。
在mac中,你可以。。。

三、使用Image Destinations:
在你創建了一個CGImageDestination對象之後,你可以添加image數據和設置image屬性,然後調用函數CGImageDestinationFinalize來結束。
1、設置Image Destination的屬性:
函數CGImageDestinationSetProperties添加一個屬性字典CFDictionaryRef到image destination的圖像中。雖然設置屬性是可選的,但是很多時候你都需要這麼做。例如,如果你的應用允許用戶添加keywords到圖像或更改saturation(色飽和度)、exposure(曝光值)等等。

2、將圖像寫入到一個Image Destination:
CGImageDestinationCreateWithURL、CGImageDestinationCreateWithData、CGImageDestinationCreateWithDataConsumer函數。
創建完之後,你可以添加image,通過調用CGImageDestinationAddImage或CGImageDestinationAddImageFromSource函數。
最後調用CGImageDestinationFinalize來結束。一旦結束,你就不能再添加更多的數據到image destination。
例子:
- (void) writeCGImage: (CGImageRef) image toURL: (NSURL*) url withType: (CFStringRef) imageType andOptions: (CFDictionaryRef) options
{
CGImageDestinationRef myImageDest = CGImageDestinationCreateWithURL((CFURLRef)url, imageType, 1, nil);
CGImageDestinationAddImage(myImageDest, image, options);
CGImageDestinationFinalize(myImageDest);
CFRelease(myImageDest);
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章