1. 程式人生 > >iOS圖片元資料的讀寫

iOS圖片元資料的讀寫

圖片的本身就是各種影象資料的載體,包含著畫素、色彩、灰度等各種資料資訊,除此之外,還包含著曝光資料、日期、位置、版權等元資料(metadata)。
何為圖片元資料

元資料包括許多重要的資訊,常用的有Exif(可交換影象檔案格式,Exchangeable image file format)、GPS(位置資訊)和TIFF(Tagged Image File Format,標籤影象檔案格式)。

所謂元資料是指Data about Data,就是用來描述資料的資料。

以Exif為例,其中包含了大量資訊:

Image Description 影象描述、來源. 指生成影象的工具
Artist 作者 有些相機可以輸入使用者的名字
Make 生產者 指產品生產廠家
Model 型號 指裝置型號
Orientation方向 有的相機支援,有的不支援
XResolution/YResolution X/Y方向解析度 本欄目已有專門條目解釋此問題。
ResolutionUnit解析度單位 一般為PPI
Software軟體 顯示韌體Firmware版本
DateTime日期和時間
YCbCrPositioning 色相定位
ExifOffsetExif資訊位置,定義Exif在資訊在檔案中的寫入,有些軟體不顯示。
ExposureTime 曝光時間 即快門速度
FNumber光圈係數
ExposureProgram曝光程式 指程式式自動曝光的設定,各相機不同,可能是Sutter Priority(快門優先)、Aperture Priority(快門優先)等等。
ISO speed ratings感光度
ExifVersionExif版本
DateTimeOriginal建立時間
DateTimeDigitized數字化時間
ComponentsConfiguration影象構造(多指色彩組合方案)
CompressedBitsPerPixel(BPP)壓縮時每畫素色彩位 指壓縮程度
ExposureBiasValue曝光補償。
MaxApertureValue最大光圈
MeteringMode測光方式, 平均式測光、中央重點測光、點測光等。
Lightsource光源 指白平衡設定
Flash是否使用閃光燈。
FocalLength焦距,一般顯示鏡頭物理焦距,有些軟體可以定義一個係數,從而顯示相當於35
mm相機的焦距 MakerNote(User Comment)作者標記、說明、記錄 FlashPixVersionFlashPix版本 (個別機型支援)ColorSpace色域、色彩空間 ExifImageWidth(Pixel X Dimension)影象寬度 指橫向畫素數 ExifImageLength(Pixel Y Dimension)影象高度 指縱向畫素數 Interoperability IFD通用性擴充套件項定義指標 和TIFF檔案相關,具體含義不詳 FileSource原始檔 Compression壓縮比。

這些資料就是構成一張圖片的元素,也相當於一張圖片的名片,包含著豐富的資訊。

你可以在此瞭解更多關於Exif的具體研究。
在開發中使用

目前市場上的大部分智慧手機拍攝的照片都支援寫入元資料,因此我們可以利用圖片的元資料來攜帶需要新增的資料。在處理圖片時,我們往往需要對圖片資料進行操作,除了操作其中的影象資訊外,我們還可以對圖片資訊的元資料進行操作,包括存和取。這對於傳遞資料將是十分便利的,其中一方只需將資料寫入圖片,另一方通過讀取圖片的元資料就可獲取所要傳遞的資料,而不需要傳除圖片之外的任何物件,在實際開發中應用場景很多。


    首先,我們需要藉助與UIImagePickerControllerDelegate的代理方法,建立一個UIImagePickerController,在其代理方法- (void
)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info中就可獲取info,從而獲取image物件: UIImage *image = [info valueForKey:UIImagePickerControllerOriginalImage]; 為獲取info的metadata,要使用ALAssetsLibrary的assetForURL: resultBlock:方法: //1. 首先得到Reference URL NSURL *assetURL = [info objectForKey:UIImagePickerControllerReferenceURL]; //2. 建立一個ALAssetsLibrary ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init]; //3. 使用回撥方法,得到字典型別的metadata [library assetForURL:assetURL resultBlock:^(ALAsset *asset) { NSDictionary *imageMetadata = [[NSMutableDictionary alloc] initWithDictionary:asset.defaultRepresentation.metadata]; NSLog(@"metadata:--%@",imageMetadata); NSDictionary *gpsDic = [imageMetadata objectForKey:@"{GPS}"]; NSDictionary *exifDic = [imageMetadata objectForKey:@"{Exif}"]; NSDictionary *tiffDic = [imageMetadata objectForKey:@"{TIFF}"]; //可交換影象檔案 NSLog(@"Exif info:--%@",exifDic); //地理位置資訊 NSLog(@"GPS info:--%@",gpsDic); //影象檔案格式 NSLog(@"tiff info:--%@",tiffDic); }

以向圖片元資料中寫入Exif的kCGImagePropertyExifDateTimeOriginal為例。

1.先按照特定的格式建立一個日期物件:

NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:@"YYYY:MM:dd hh:mm:ss"];
NSString *now = [formatter stringFromDate:[NSDate date]];

2.將之前的exifDic中的對應欄位值設為當前日期物件now:

[exifDic setValue:now forKey:(NSString*)kCGImagePropertyExifDateTimeOriginal];
[imageMetadata setValue:exifDic forKey:@"{Exif}"];

3.利用ALAssetsLibrary的writeImageToSavedPhotosAlbum: metadata: completionBlock方法寫入並儲存:

[library writeImageToSavedPhotosAlbum:[image CGImage] metadata:imageMetadata completionBlock:^(NSURL *assetURL, NSError *error) {
                     if (error == nil)
                         NSLog(@"metadata write success!");
                     else
                         NSLog(@"write error:%@",error.userInfo);
                 }];

這樣,圖片的建立時間就被寫入並儲存了,如果是對相簿中已經存在的圖片進行此寫入操作,則其將被更改建立時間而另存。

如果你想寫入中文或者自定義資料,可以考慮將資料寫入到kCGImagePropertyExifUserComment中。

UserComment標籤說明
標籤號:0x9286;格式:undefined;描述:儲存使用者的註釋,這個標籤允許使用兩位元組的德字元或者 unicode,前8 個位元組描述的是字符集,'JIS' 是日文 (著名的有 Kanji)。
'0x41,0x53,0x43,0x49,0x49,0x00,0x00,0x00':ASCII
'0x4a,0x49,0x53,0x00,0x00,0x00,0x00,0x00':JIS
'0x55,0x4e,0x49,0x43,0x4f,0x44,0x45,0x00':Unicode
'0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00':Undefined

UserComment寫入的程式碼實現

NSString *userComment = @"你好,this is a test text for writing data in UserComment";
                 [exifDic setValue:userComment forKey:(NSString*)kCGImagePropertyExifUserComment];
                 [imageMetadata setValue:exifDic forKey:@"{Exif}"];